ldb-2.0.8/ABI/ldb-0.9.10.sigs0000660000000000000000000004050212406075657015001 0ustar rootroot00000000000000ldb_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 *(void *, 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 *(void *, const char *, int) ldb_binary_decode: struct ldb_val (void *, const char *) ldb_binary_encode: char *(void *, struct ldb_val) ldb_binary_encode_string: char *(void *, const char *) ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) ldb_casefold_default: char *(void *, void *, const char *, size_t) 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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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 *(void *, struct ldb_dn *) ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) ldb_dn_get_linearized: const char *(struct ldb_dn *) ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) 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_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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_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 *(void *) 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_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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_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_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_set_state: void (struct ldb_request *, int) ldb_reset_err_string: void (struct ldb_context *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.12.sigs0000660000000000000000000004061612406075657015011 0ustar rootroot00000000000000ldb_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 *(void *, 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 *(void *, const char *, int) ldb_binary_decode: struct ldb_val (void *, const char *) ldb_binary_encode: char *(void *, struct ldb_val) ldb_binary_encode_string: char *(void *, const char *) ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) ldb_casefold_default: char *(void *, void *, const char *, size_t) 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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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 *(void *, struct ldb_dn *) ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) ldb_dn_get_linearized: const char *(struct ldb_dn *) ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) 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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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_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 *(void *) 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_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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_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_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_set_state: void (struct ldb_request *, int) ldb_reset_err_string: void (struct ldb_context *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.15.sigs0000660000000000000000000004234312406075657015013 0ustar rootroot00000000000000ldb_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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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_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_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_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_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 *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_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_location: const char *(struct ldb_request *) 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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.16.sigs0000660000000000000000000004251112406075657015011 0ustar rootroot00000000000000ldb_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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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_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_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_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_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 *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_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_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) 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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.17.sigs0000660000000000000000000004263312406075657015017 0ustar rootroot00000000000000ldb_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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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_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_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_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_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 *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_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_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) 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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.18.sigs0000660000000000000000000004355712406075657015026 0ustar rootroot00000000000000ldb_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_asq_init: int (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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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_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_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_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_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 *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_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_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_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_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_paged_results_init: int (const char *) ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_rdn_name_init: int (const char *) ldb_register_backend: int (const char *, ldb_connect_fn, bool) 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_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) 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_sample_init: int (const char *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_server_sort_init: int (const char *) 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_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_skel_init: int (const char *) 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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.19.sigs0000660000000000000000000004426212406075657015021 0ustar rootroot00000000000000ldb_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_asq_init: int (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_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_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_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_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) 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_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_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_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_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_paged_results_init: int (const char *) ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_rdn_name_init: int (const char *) ldb_register_backend: int (const char *, ldb_connect_fn, bool) 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_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) 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_sample_init: int (const char *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_server_sort_init: int (const char *) 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_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_skel_init: int (const char *) 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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.20.sigs0000660000000000000000000004426212406075657015011 0ustar rootroot00000000000000ldb_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_asq_init: int (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_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_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_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_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) 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_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_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_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_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_paged_results_init: int (const char *) ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_rdn_name_init: int (const char *) ldb_register_backend: int (const char *, ldb_connect_fn, bool) 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_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) 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_sample_init: int (const char *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_server_sort_init: int (const char *) 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_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_skel_init: int (const char *) 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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.22.sigs0000660000000000000000000004470612406075657015016 0ustar rootroot00000000000000ldb_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_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_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_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_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_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_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_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_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_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_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_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_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.23.sigs0000660000000000000000000004504212406075657015011 0ustar rootroot00000000000000ldb_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_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_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_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_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_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_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_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_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_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_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-0.9.24.sigs0000660000000000000000000004512412406075657015013 0ustar rootroot00000000000000ldb_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_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.0.0.sigs0000660000000000000000000004512412406075657014715 0ustar rootroot00000000000000ldb_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_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.0.1.sigs0000660000000000000000000004512412406075657014716 0ustar rootroot00000000000000ldb_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_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.0.2.sigs0000660000000000000000000004540212406075657014716 0ustar rootroot00000000000000ldb_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.0.sigs0000660000000000000000000004604512406075657014721 0ustar rootroot00000000000000ldb_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.1.sigs0000660000000000000000000004614412406075657014722 0ustar rootroot00000000000000ldb_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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.10.sigs0000660000000000000000000004705712406075657015006 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.11.sigs0000660000000000000000000004705712406075657015007 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.12.sigs0000660000000000000000000004723112406075657015002 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.13.sigs0000660000000000000000000004723112406075657015003 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.14.sigs0000660000000000000000000004751312406075657015007 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.15.sigs0000660000000000000000000004751312406075657015010 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.16.sigs0000660000000000000000000004751312406075657015011 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.17.sigs0000660000000000000000000004751312406075657015012 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.18.sigs0000660000000000000000000004751312436652016015004 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.19.sigs0000660000000000000000000004766012445751605015014 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.2.sigs0000660000000000000000000004641412406075657014723 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.20.sigs0000660000000000000000000004766012461161556015002 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.21.sigs0000660000000000000000000004766012553526454015007 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.22.sigs0000660000000000000000000004775612617125140015002 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.23.sigs0000660000000000000000000004775612617125552015012 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.24.sigs0000660000000000000000000004775612634245625015016 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.25.sigs0000660000000000000000000005021312634460674015000 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.26.sigs0000660000000000000000000005021312661701535014773 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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) ldb-2.0.8/ABI/ldb-1.1.27.sigs0000660000000000000000000005047412746371751015014 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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) ldb-2.0.8/ABI/ldb-1.1.28.sigs0000660000000000000000000005047413015513033014772 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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) ldb-2.0.8/ABI/ldb-1.1.29.sigs0000660000000000000000000005107013020021120014747 0ustar rootroot00000000000000ldb_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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) ldb-2.0.8/ABI/ldb-1.1.3.sigs0000660000000000000000000004641412406075657014724 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.30.sigs0000660000000000000000000005151313114236424014764 0ustar rootroot00000000000000ldb_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_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_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_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_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_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) ldb-2.0.8/ABI/ldb-1.1.31.sigs0000660000000000000000000005213413120574744014774 0ustar rootroot00000000000000ldb_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_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_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_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_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) ldb-2.0.8/ABI/ldb-1.1.4.sigs0000660000000000000000000004641412406075657014725 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.5.sigs0000660000000000000000000004655512406075657014734 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.6.sigs0000660000000000000000000004673212406075657014732 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.7.sigs0000660000000000000000000004673212406075657014733 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.8.sigs0000660000000000000000000004673212406075657014734 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.1.9.sigs0000660000000000000000000004673212406075657014735 0ustar rootroot00000000000000ldb_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_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_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_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_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_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_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_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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_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_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb-2.0.8/ABI/ldb-1.2.0.sigs0000660000000000000000000005227213126253040014701 0ustar rootroot00000000000000ldb_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_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_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_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) ldb-2.0.8/ABI/ldb-1.2.1.sigs0000660000000000000000000005227213134750432014710 0ustar rootroot00000000000000ldb_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_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_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_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) ldb-2.0.8/ABI/ldb-1.2.2.sigs0000660000000000000000000005247013154214633014711 0ustar rootroot00000000000000ldb_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_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_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) ldb-2.0.8/ABI/ldb-1.2.3.sigs0000660000000000000000000005247013167070744014721 0ustar rootroot00000000000000ldb_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_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_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) ldb-2.0.8/ABI/ldb-1.3.0.sigs0000660000000000000000000005302513444661620014711 0ustar rootroot00000000000000ldb_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) ldb-2.0.8/ABI/ldb-1.3.1.sigs0000660000000000000000000005302513444661620014712 0ustar rootroot00000000000000ldb_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) ldb-2.0.8/ABI/ldb-1.3.2.sigs0000660000000000000000000005302513444661620014713 0ustar rootroot00000000000000ldb_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) ldb-2.0.8/ABI/ldb-1.4.0.sigs0000660000000000000000000005302513444661620014712 0ustar rootroot00000000000000ldb_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) ldb-2.0.8/ABI/ldb-1.4.1.sigs0000660000000000000000000005302513444661620014713 0ustar rootroot00000000000000ldb_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) ldb-2.0.8/ABI/ldb-1.5.0.sigs0000660000000000000000000005302513573675413014723 0ustar rootroot00000000000000ldb_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) ldb-2.0.8/ABI/ldb-1.5.1.sigs0000660000000000000000000005314013573675413014722 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-1.5.2.sigs0000660000000000000000000005314013573675413014723 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-1.5.3.sigs0000660000000000000000000005314013573675413014724 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-1.6.0.sigs0000660000000000000000000005314013573675413014722 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-1.6.1.sigs0000660000000000000000000005314013573675413014723 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-1.6.2.sigs0000660000000000000000000005314013573675413014724 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-1.6.3.sigs0000660000000000000000000005314013573675413014725 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-2.0.0.sigs0000660000000000000000000005314013573675413014715 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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) ldb-2.0.8/ABI/ldb-2.0.1.sigs0000660000000000000000000005276513573675413014732 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, 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) ldb-2.0.8/ABI/ldb-2.0.2.sigs0000660000000000000000000005307713573675413014730 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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 *, uint32_t) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) 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) ldb-2.0.8/ABI/ldb-2.0.3.sigs0000660000000000000000000005307713573675413014731 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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 *, uint32_t) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) 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) ldb-2.0.8/ABI/ldb-2.0.4.sigs0000660000000000000000000005317413573675413014730 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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_copy: const char **(TALLOC_CTX *, const char **) 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 *, uint32_t) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) 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) ldb-2.0.8/ABI/ldb-2.0.5.sigs0000660000000000000000000005326113573675413014726 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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_copy: const char **(TALLOC_CTX *, const char **) ldb_options_find: const char *(struct ldb_context *, const char **, const char *) ldb_options_get: const char **(struct ldb_context *) ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) 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) ldb-2.0.8/ABI/ldb-2.0.6.sigs0000660000000000000000000005326113573675413014727 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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_copy: const char **(TALLOC_CTX *, const char **) ldb_options_find: const char *(struct ldb_context *, const char **, const char *) ldb_options_get: const char **(struct ldb_context *) ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) 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) ldb-2.0.8/ABI/ldb-2.0.7.sigs0000660000000000000000000005326113573675413014730 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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_copy: const char **(TALLOC_CTX *, const char **) ldb_options_find: const char *(struct ldb_context *, const char **, const char *) ldb_options_get: const char **(struct ldb_context *) ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) 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) ldb-2.0.8/ABI/ldb-2.0.8.sigs0000660000000000000000000005326113573675413014731 0ustar rootroot00000000000000ldb_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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) 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_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) 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_copy: const char **(TALLOC_CTX *, const char **) ldb_options_find: const char *(struct ldb_context *, const char **, const char *) ldb_options_get: const char **(struct ldb_context *) ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) 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_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) 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) ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs0000660000000000000000000004155212406075657016100 0ustar rootroot00000000000000ldb_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 *(void *, 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 *(void *, const char *, int) ldb_binary_decode: struct ldb_val (void *, const char *) ldb_binary_encode: char *(void *, struct ldb_val) ldb_binary_encode_string: char *(void *, const char *) ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) ldb_casefold_default: char *(void *, void *, const char *, size_t) 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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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 *(void *, struct ldb_dn *) ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) ldb_dn_get_linearized: const char *(struct ldb_dn *) ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) 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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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_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 *(void *) 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_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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_fn) ldb_register_module: int (const struct ldb_module_ops *) ldb_register_samba_handlers: int (struct ldb_context *) 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_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_set_state: void (struct ldb_request *, int) ldb_reset_err_string: void (struct ldb_context *) ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) ldb_wrap_fork_hook: void (void) ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs0000660000000000000000000004143612406075657016155 0ustar rootroot00000000000000ldb_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 *(void *, 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 *(void *, const char *, int) ldb_binary_decode: struct ldb_val (void *, const char *) ldb_binary_encode: char *(void *, struct ldb_val) ldb_binary_encode_string: char *(void *, const char *) ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) ldb_casefold_default: char *(void *, void *, const char *, size_t) 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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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 *(void *, struct ldb_dn *) ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) ldb_dn_get_linearized: const char *(struct ldb_dn *) ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) 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_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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_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 *(void *) 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_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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_fn) ldb_register_module: int (const struct ldb_module_ops *) ldb_register_samba_handlers: int (struct ldb_context *) 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_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_set_state: void (struct ldb_request *, int) ldb_reset_err_string: void (struct ldb_context *) ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) ldb_wrap_fork_hook: void (void) ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs0000660000000000000000000004155212406075657016155 0ustar rootroot00000000000000ldb_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 *(void *, 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 *(void *, const char *, int) ldb_binary_decode: struct ldb_val (void *, const char *) ldb_binary_encode: char *(void *, struct ldb_val) ldb_binary_encode_string: char *(void *, const char *) ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) ldb_casefold_default: char *(void *, void *, const char *, size_t) 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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) 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 *(void *, struct ldb_dn *) ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) ldb_dn_get_linearized: const char *(struct ldb_dn *) ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) 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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) ldb_load_modules: int (struct ldb_context *, const char **) ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) 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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) 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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) 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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) 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_private: void (struct ldb_module *, void *) ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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_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 *(void *) 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_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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) ldb_register_backend: int (const char *, ldb_connect_fn) ldb_register_module: int (const struct ldb_module_ops *) ldb_register_samba_handlers: int (struct ldb_context *) 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_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_set_state: void (struct ldb_request *, int) ldb_reset_err_string: void (struct ldb_context *) ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) 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_remove: void (struct ldb_context *, const char *) ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) 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_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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) ldb_valid_attr_name: int (const char *) ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) ldb_wrap_fork_hook: void (void) ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs0000660000000000000000000000021012406075657016306 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs0000660000000000000000000000021012406075657016307 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs0000660000000000000000000000021012406075657016310 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs0000660000000000000000000000021012406075657016311 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs0000660000000000000000000000021012406075657016312 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs0000660000000000000000000000021012406075657016313 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs0000660000000000000000000000021012406075657016314 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs0000660000000000000000000000021012406075657016315 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs0000660000000000000000000000021012436652016016307 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs0000660000000000000000000000021012445751605016314 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs0000660000000000000000000000021012406075657016227 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs0000660000000000000000000000021012461161556016302 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs0000660000000000000000000000021012553526454016307 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs0000660000000000000000000000021012617125140016274 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs0000660000000000000000000000021012617125552016304 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs0000660000000000000000000000021012634245625016310 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs0000660000000000000000000000021012634460674016314 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs0000660000000000000000000000021012661701535016307 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs0000660000000000000000000000021012746371751016317 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs0000660000000000000000000000021013015513033016275 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs0000660000000000000000000000021013020021120016261 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs0000660000000000000000000000021012406075657016230 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs0000660000000000000000000000021013114236424016274 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs0000660000000000000000000000021013120574744016304 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs0000660000000000000000000000021012406075657016231 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs0000660000000000000000000000021012406075657016232 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs0000660000000000000000000000021012406075657016233 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs0000660000000000000000000000021012406075657016234 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs0000660000000000000000000000021012406075657016235 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs0000660000000000000000000000021012406075657016236 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs0000660000000000000000000000021013126253040016206 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs0000660000000000000000000000021013134750432016215 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs0000660000000000000000000000021013154214633016216 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs0000660000000000000000000000021013167070744016226 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs0000660000000000000000000000021013444661620016221 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs0000660000000000000000000000021013444661620016222 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs0000660000000000000000000000021013444661620016223 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs0000660000000000000000000000021013444661620016222 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs0000660000000000000000000000021013444661620016223 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs0000660000000000000000000000021013573675413016233 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs0000660000000000000000000000021013573675413016234 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs0000660000000000000000000000021013573675413016235 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs0000660000000000000000000000021013573675413016236 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs0000660000000000000000000000021013573675413016234 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs0000660000000000000000000000021013573675413016235 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs0000660000000000000000000000021013573675413016236 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs0000660000000000000000000000021013573675413016237 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs0000660000000000000000000000021013573675413016227 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs0000660000000000000000000000021013573675413016230 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs0000660000000000000000000000021013573675413016231 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs0000660000000000000000000000021013573675413016232 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs0000660000000000000000000000021013573675413016233 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs0000660000000000000000000000021013573675413016234 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs0000660000000000000000000000021013573675413016235 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs0000660000000000000000000000021013573675413016236 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs0000660000000000000000000000021013573675413016237 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs0000660000000000000000000000021013573675413016741 0ustar rootroot00000000000000pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) ldb-2.0.8/Doxyfile0000660000000000000000000000145712406075657013747 0ustar rootroot00000000000000PROJECT_NAME = LDB OUTPUT_DIRECTORY = apidocs REPEAT_BRIEF = YES OPTIMIZE_OUTPUT_FOR_C = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO GENERATE_TODOLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES SHOW_USED_FILES = NO SHOW_DIRECTORIES = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" INPUT = include . FILE_PATTERNS = *.h *.dox EXCLUDE = include/config.h include/dlinklist.h \ include/includes.h EXAMPLE_PATH = examples GENERATE_HTML = YES HTML_OUTPUT = html GENERATE_MAN = YES ALWAYS_DETAILED_SEC = YES JAVADOC_AUTOBRIEF = YES ldb-2.0.8/Makefile0000660000000000000000000000135413573675413013677 0ustar rootroot00000000000000# simple makefile wrapper to run waf WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` WAF_BINARY=$(PYTHON) $(WAF_BIN) WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) all: $(WAF) build install: $(WAF) install uninstall: $(WAF) uninstall test: $(WAF) test $(TEST_OPTIONS) dist: touch .tmplock WAFLOCK=.tmplock $(WAF) dist distcheck: touch .tmplock WAFLOCK=.tmplock $(WAF) distcheck clean: $(WAF) clean distclean: $(WAF) distclean reconfigure: configure $(WAF) reconfigure show_waf_options: $(WAF) --help # some compatibility make targets everything: all testsuite: all check: test # this should do an install as well, once install is finished installcheck: test etags: $(WAF) etags ctags: $(WAF) ctags ldb-2.0.8/README_gcov.txt0000660000000000000000000000147612406075657014756 0ustar rootroot00000000000000Here is how to use gcov to test code coverage in ldb. Step 1: build ldb with gcov enabled make clean all WITH_GCOV=1 Step 3: run the test suite make test-tdb Step 4: produce the gcov report make gcov Step 5: read the summary reports less *.report.gcov Step 6: examine the per-file reports less ldb_tdb\#ldb_tdb.c.gcov You can also combine steps 2 to 4 like this: make clean all test-tdb gcov WITH_GCOV=1 Note that you should not expect 100% coverage, as some error paths (such as memory allocation failures) are very hard to trigger. There are ways of working around this, but they are quite tricky (they involve allocation wrappers that "fork and fail on malloc"). The lines to look for in the per-file reports are the ones starting with "#####". Those are lines that are never executed. ldb-2.0.8/_ldb_text.py0000660000000000000000000000672013573675413014557 0ustar rootroot00000000000000# Text wrapper for ldb bindings # # Copyright (C) 2015 Petr Viktorin # Published under the GNU LGPLv3 or later import ldb def _recursive_encode(obj): if isinstance(obj, bytes): return obj elif isinstance(obj, str): return obj.encode('utf-8') else: return [_recursive_encode(o) for o in obj] class _WrapBase(object): @classmethod def _wrap(cls, wrapped): self = cls.__new__(cls) self._wrapped = wrapped return self def __len__(self): return len(self._wrapped) def __eq__(self, other): if hasattr(other, '_wrapped'): return self._wrapped == other._wrapped else: return self._wrapped == other def __ne__(self, other): if hasattr(other, '_wrapped'): return self._wrapped != other._wrapped else: return self._wrapped != other def __lt__(self, other): if hasattr(other, '_wrapped'): return self._wrapped < other._wrapped else: return self._wrapped < other def __le__(self, other): if hasattr(other, '_wrapped'): return self._wrapped >= other._wrapped else: return self._wrapped >= other def __gt__(self, other): if hasattr(other, '_wrapped'): return self._wrapped > other._wrapped else: return self._wrapped > other def __ge__(self, other): if hasattr(other, '_wrapped'): return self._wrapped >= other._wrapped else: return self._wrapped >= other def __repr__(self): return '%s.text' % repr(self._wrapped) class MessageElementTextWrapper(_WrapBase): """Text interface for a LDB message element""" def __iter__(self): for item in self._wrapped: yield item.decode('utf-8') def __getitem__(self, key): result = self._wrapped[key] if result is None: return None else: return result.decode('utf-8') @property def flags(self): return self._wrapped.flags @property def set_flags(self): return self._wrapped.set_flags _wrap_element = MessageElementTextWrapper._wrap class MessageTextWrapper(_WrapBase): """Text interface for a LDB message""" def __getitem__(self, key): result = self._wrapped[key] if result is None: return None else: return _wrap_element(result) def get(self, *args, **kwargs): result = self._wrapped.get(*args, **kwargs) if isinstance(result, ldb.MessageElement): return _wrap_element(result) elif isinstance(result, bytes): return result.decode('utf-8') else: return result def __setitem__(self, key, item): self._wrapped[key] = _recursive_encode(item) def __delitem__(self, key): del self._wrapped[key] def elements(self): return [_wrap_element(el) for el in self._wrapped.elements()] def items(self): return [(attr, _wrap_element(el)) for attr, el in self._wrapped.items()] @property def keys(self): return self._wrapped.keys @property def remove(self): return self._wrapped.remove @property def add(self): return self._wrapped.add @property def dn(self): return self._wrapped.dn @dn.setter def dn(self, new_value): self._wrapped.dn = new_value ldb-2.0.8/common/attrib_handlers.c0000660000000000000000000004053213573675413017041 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2005 Copyright (C) Andrew Bartlett 2006-2009 ** 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 . */ /* attribute handlers for well known attribute types, selected by syntax OID see rfc2252 */ #include "ldb_private.h" #include "system/locale.h" #include "ldb_handlers.h" /* default handler that just copies a ldb_val. */ int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { *out = ldb_val_dup(mem_ctx, in); if (in->length > 0 && out->data == NULL) { ldb_oom(ldb); return -1; } return 0; } /* a case folding copy handler, removing leading and trailing spaces and multiple internal spaces We exploit the fact that utf8 never uses the space octet except for the space itself */ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { char *s, *t; size_t l; if (!in || !out || !(in->data)) { return -1; } out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data), in->length); if (out->data == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%.*s]", (int)in->length, (const char *)in->data); return -1; } s = (char *)(out->data); /* remove trailing spaces if any */ l = strlen(s); while (l > 0 && s[l - 1] == ' ') l--; s[l] = '\0'; /* remove leading spaces if any */ if (*s == ' ') { for (t = s; *s == ' '; s++) ; /* remove leading spaces by moving down the string */ memmove(t, s, l); s = t; } /* check middle spaces */ while ((t = strchr(s, ' ')) != NULL) { for (s = t; *s == ' '; s++) ; if ((s - t) > 1) { l = strlen(s); /* remove all spaces but one by moving down the string */ memmove(t + 1, s, l); } } out->length = strlen((char *)out->data); return 0; } /* length limited conversion of a ldb_val to a int32_t */ static int val_to_int64(const struct ldb_val *in, int64_t *v) { char *end; char buf[64]; /* make sure we don't read past the end of the data */ if (in->length > sizeof(buf)-1) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } strncpy(buf, (char *)in->data, in->length); buf[in->length] = 0; /* We've to use "strtoll" here to have the intended overflows. * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ *v = (int64_t) strtoll(buf, &end, 0); if (*end != 0) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } return LDB_SUCCESS; } /* canonicalise a ldap Integer rfc2252 specifies it should be in decimal form */ static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { int64_t i; int ret; ret = val_to_int64(in, &i); if (ret != LDB_SUCCESS) { return ret; } out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); if (out->data == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } out->length = strlen((char *)out->data); return 0; } /* * Lexicographically ordered format for a ldap Integer * * [ INT64_MIN ... -3, -2, -1 | 0 | +1, +2, +3 ... INT64_MAX ] * n o p * * For human readability sake, we continue to format the key as a string * (like the canonicalize) rather than store as a fixed binary representation. * * In order to sort the integers in the correct string order, there are three * techniques we use: * * 1. Zero padding * 2. Negative integer inversion * 3. 1-byte prefixes: 'n' < 'o' < 'p' * * 1. To have a fixed-width representation so that 10 sorts after 2 rather than * after 1, we zero pad, like this 4-byte width example: * * 0001, 0002, 0010 * * INT64_MAX = 2^63 - 1 = 9223372036854775807 (19 characters long) * * Meaning we need to pad to 19 characters. * * 2. This works for positive integers, but negative integers will still be * sorted backwards, for example: * * -9223372036854775808 ..., -0000000000000000002, -0000000000000000001 * INT64_MIN -2 -1 * * gets sorted based on string as: * * -0000000000000000001, -0000000000000000002, ... -9223372036854775808 * * In order to fix this, we invert the negative integer range, so that they * get sorted the same way as positive numbers. INT64_MIN becomes the lowest * possible non-negative number (zero), and -1 becomes the highest (INT64_MAX). * * The actual conversion applied to negative number 'x' is: * INT64_MAX - abs(x) + 1 * (The +1 is needed because abs(INT64_MIN) is one greater than INT64_MAX) * * 3. Finally, we now have two different numbers that map to the same key, e.g. * INT64_MIN maps to -0000000000000000000 and zero maps to 0000000000000000000. * In order to avoid confusion, we give every number a prefix representing its * sign: 'n' for negative numbers, 'o' for zero, and 'p' for positive. (Note * that '+' and '-' weren't used because they sort the wrong way). * * The result is a range of key values that look like this: * * n0000000000000000000, ... n9223372036854775807, * INT64_MIN -1 * * o0000000000000000000, * ZERO * * p0000000000000000001, ... p9223372036854775807 * +1 INT64_MAX */ static int ldb_index_format_Integer(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { int64_t i; int ret; char prefix; size_t len; ret = val_to_int64(in, &i); if (ret != LDB_SUCCESS) { return ret; } if (i < 0) { /* * i is negative, so this is subtraction rather than * wrap-around. */ prefix = 'n'; i = INT64_MAX + i + 1; } else if (i > 0) { prefix = 'p'; } else { prefix = 'o'; } out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%c%019lld", prefix, (long long)i); if (out->data == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } len = talloc_array_length(out->data) - 1; if (len != 20) { ldb_debug(ldb, LDB_DEBUG_ERROR, __location__ ": expected index format str %s to" " have length 20 but got %zu", (char*)out->data, len); return LDB_ERR_OPERATIONS_ERROR; } out->length = 20; return 0; } /* compare two Integers */ static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { int64_t i1=0, i2=0; val_to_int64(v1, &i1); val_to_int64(v2, &i2); if (i1 == i2) return 0; return i1 > i2? 1 : -1; } /* canonicalise a ldap Boolean rfc2252 specifies it should be either "TRUE" or "FALSE" */ static int ldb_canonicalise_Boolean(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { if (in->length >= 4 && strncasecmp((char *)in->data, "TRUE", in->length) == 0) { out->data = (uint8_t *)talloc_strdup(mem_ctx, "TRUE"); out->length = 4; } else if (in->length >= 5 && strncasecmp((char *)in->data, "FALSE", in->length) == 0) { out->data = (uint8_t *)talloc_strdup(mem_ctx, "FALSE"); out->length = 5; } else { return -1; } return 0; } /* compare two Booleans */ static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { if (v1->length != v2->length) { return v1->length - v2->length; } return strncasecmp((char *)v1->data, (char *)v2->data, v1->length); } /* compare two binary blobs */ int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { if (v1->length != v2->length) { return v1->length - v2->length; } return memcmp(v1->data, v2->data, v1->length); } /* compare two case insensitive strings, ignoring multiple whitespaces and leading and trailing whitespaces see rfc2252 section 8.1 try to optimize for the ascii case, but if we find out an utf8 codepoint revert to slower but correct function */ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { const char *s1=(const char *)v1->data, *s2=(const char *)v2->data; size_t n1 = v1->length, n2 = v2->length; char *b1, *b2; const char *u1, *u2; int ret; while (n1 && *s1 == ' ') { s1++; n1--; }; while (n2 && *s2 == ' ') { s2++; n2--; }; while (n1 && n2 && *s1 && *s2) { /* the first 127 (0x7F) chars are ascii and utf8 guarantes they * never appear in multibyte sequences */ if (((unsigned char)s1[0]) & 0x80) goto utf8str; if (((unsigned char)s2[0]) & 0x80) goto utf8str; if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) break; if (*s1 == ' ') { while (n1 && s1[0] == s1[1]) { s1++; n1--; } while (n2 && s2[0] == s2[1]) { s2++; n2--; } } s1++; s2++; n1--; n2--; } /* check for trailing spaces only if the other pointers has * reached the end of the strings otherwise we can * mistakenly match. ex. "domain users" <-> * "domainUpdates" */ if (n1 && *s1 == ' ' && (!n2 || !*s2)) { while (n1 && *s1 == ' ') { s1++; n1--; } } if (n2 && *s2 == ' ' && (!n1 || !*s1)) { while (n2 && *s2 == ' ') { s2++; n2--; } } if (n1 == 0 && n2 != 0) { return -(int)toupper(*s2); } if (n2 == 0 && n1 != 0) { return (int)toupper(*s1); } if (n1 == 0 && n2 == 0) { return 0; } return (int)toupper(*s1) - (int)toupper(*s2); utf8str: /* no need to recheck from the start, just from the first utf8 char found */ b1 = ldb_casefold(ldb, mem_ctx, s1, n1); b2 = ldb_casefold(ldb, mem_ctx, s2, n2); if (!b1 || !b2) { /* One of the strings was not UTF8, so we have no * options but to do a binary compare */ talloc_free(b1); talloc_free(b2); ret = memcmp(s1, s2, MIN(n1, n2)); if (ret == 0) { if (n1 == n2) return 0; if (n1 > n2) { return (int)toupper(s1[n2]); } else { return -(int)toupper(s2[n1]); } } return ret; } u1 = b1; u2 = b2; while (*u1 & *u2) { if (*u1 != *u2) break; if (*u1 == ' ') { while (u1[0] == u1[1]) u1++; while (u2[0] == u2[1]) u2++; } u1++; u2++; } if (! (*u1 && *u2)) { while (*u1 == ' ') u1++; while (*u2 == ' ') u2++; } ret = (int)(*u1 - *u2); talloc_free(b1); talloc_free(b2); return ret; } /* canonicalise a attribute in DN format */ static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { struct ldb_dn *dn; int ret = -1; out->length = 0; out->data = NULL; dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); if ( ! ldb_dn_validate(dn)) { return LDB_ERR_INVALID_DN_SYNTAX; } out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); if (out->data == NULL) { goto done; } out->length = strlen((char *)out->data); ret = 0; done: talloc_free(dn); return ret; } /* compare two dns */ static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { struct ldb_dn *dn1 = NULL, *dn2 = NULL; int ret; dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); if ( ! ldb_dn_validate(dn1)) return -1; dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); if ( ! ldb_dn_validate(dn2)) { talloc_free(dn1); return -1; } ret = ldb_dn_compare(dn1, dn2); talloc_free(dn1); talloc_free(dn2); return ret; } /* compare two utc time values. 1 second resolution */ static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { time_t t1=0, t2=0; ldb_val_to_time(v1, &t1); ldb_val_to_time(v2, &t2); if (t1 == t2) return 0; return t1 > t2? 1 : -1; } /* canonicalise a utc time */ static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { time_t t; int ret; ret = ldb_val_to_time(in, &t); if (ret != LDB_SUCCESS) { return ret; } out->data = (uint8_t *)ldb_timestring_utc(mem_ctx, t); if (out->data == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } out->length = strlen((char *)out->data); return 0; } /* canonicalise a generalized time */ static int ldb_canonicalise_generalizedtime(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { time_t t; int ret; ret = ldb_val_to_time(in, &t); if (ret != LDB_SUCCESS) { return ret; } out->data = (uint8_t *)ldb_timestring(mem_ctx, t); if (out->data == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } out->length = strlen((char *)out->data); return 0; } /* table of standard attribute handlers */ static const struct ldb_schema_syntax ldb_standard_syntaxes[] = { { .name = LDB_SYNTAX_INTEGER, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_canonicalise_Integer, .comparison_fn = ldb_comparison_Integer }, { .name = LDB_SYNTAX_ORDERED_INTEGER, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_canonicalise_Integer, .index_format_fn = ldb_index_format_Integer, .comparison_fn = ldb_comparison_Integer }, { .name = LDB_SYNTAX_OCTET_STRING, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_handler_copy, .comparison_fn = ldb_comparison_binary }, { .name = LDB_SYNTAX_DIRECTORY_STRING, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_handler_fold, .comparison_fn = ldb_comparison_fold }, { .name = LDB_SYNTAX_DN, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_canonicalise_dn, .comparison_fn = ldb_comparison_dn }, { .name = LDB_SYNTAX_OBJECTCLASS, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_handler_fold, .comparison_fn = ldb_comparison_fold }, { .name = LDB_SYNTAX_UTC_TIME, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_canonicalise_utctime, .comparison_fn = ldb_comparison_utctime }, { .name = LDB_SYNTAX_GENERALIZED_TIME, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_canonicalise_generalizedtime, .comparison_fn = ldb_comparison_utctime }, { .name = LDB_SYNTAX_BOOLEAN, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_canonicalise_Boolean, .comparison_fn = ldb_comparison_Boolean }, }; /* return the attribute handlers for a given syntax name */ const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, const char *syntax) { unsigned int i; unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]); /* TODO: should be replaced with a binary search */ for (i=0;i. */ /* * Name: ldb * * Component: ldb core API * * Description: core API routines interfacing to ldb backends * * Author: Andrew Tridgell */ #define TEVENT_DEPRECATED 1 #include "ldb_private.h" #include "ldb.h" static int ldb_context_destructor(void *ptr) { struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context); if (ldb->transaction_active) { ldb_debug(ldb, LDB_DEBUG_FATAL, "A transaction is still active in ldb context [%p] on %s", ldb, (const char *)ldb_get_opaque(ldb, "ldb_url")); } return 0; } /* this is used to catch debug messages from events */ static void ldb_tevent_debug(void *context, enum tevent_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); static void ldb_tevent_debug(void *context, enum tevent_debug_level level, const char *fmt, va_list ap) { struct ldb_context *ldb = talloc_get_type(context, struct ldb_context); enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL; switch (level) { case TEVENT_DEBUG_FATAL: ldb_level = LDB_DEBUG_FATAL; break; case TEVENT_DEBUG_ERROR: ldb_level = LDB_DEBUG_ERROR; break; case TEVENT_DEBUG_WARNING: ldb_level = LDB_DEBUG_WARNING; break; case TEVENT_DEBUG_TRACE: ldb_level = LDB_DEBUG_TRACE; break; }; /* There isn't a tevent: prefix here because to add it means * actually printing the string, and most of the time we don't * want to show it */ ldb_vdebug(ldb, ldb_level, fmt, ap); } /* initialise a ldb context The mem_ctx is required The event_ctx is required */ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) { struct ldb_context *ldb; int ret; const char *modules_path = getenv("LDB_MODULES_PATH"); if (modules_path == NULL) { modules_path = LDB_MODULESDIR; } ret = ldb_modules_load(modules_path, LDB_VERSION); if (ret != LDB_SUCCESS) { return NULL; } ldb = talloc_zero(mem_ctx, struct ldb_context); if (ldb == NULL) { return NULL; } /* A new event context so that callers who don't want ldb * operating on their global event context can work without * having to provide their own private one explicitly */ if (ev_ctx == NULL) { ev_ctx = tevent_context_init(ldb); if (ev_ctx == NULL) { talloc_free(ldb); return NULL; } tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb); tevent_loop_allow_nesting(ev_ctx); } ret = ldb_setup_wellknown_attributes(ldb); if (ret != LDB_SUCCESS) { talloc_free(ldb); return NULL; } ldb_set_utf8_default(ldb); ldb_set_create_perms(ldb, 0666); ldb_set_modules_dir(ldb, LDB_MODULESDIR); ldb_set_event_context(ldb, ev_ctx); ret = ldb_register_extended_match_rules(ldb); if (ret != LDB_SUCCESS) { talloc_free(ldb); return NULL; } /* TODO: get timeout from options if available there */ ldb->default_timeout = 300; /* set default to 5 minutes */ talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor); return ldb; } /* try to autodetect a basedn if none specified. This fixes one of my pet hates about ldapsearch, which is that you have to get a long, complex basedn right to make any use of it. */ void ldb_set_default_dns(struct ldb_context *ldb) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_result *res; struct ldb_dn *tmp_dn=NULL; static const char *attrs[] = { "rootDomainNamingContext", "configurationNamingContext", "schemaNamingContext", "defaultNamingContext", NULL }; tmp_ctx = talloc_new(ldb); ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL), LDB_SCOPE_BASE, attrs, "(objectClass=*)"); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return; } if (res->count != 1) { talloc_free(tmp_ctx); return; } if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) { tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "rootDomainNamingContext"); ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn); } if (!ldb_get_opaque(ldb, "configurationNamingContext")) { tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "configurationNamingContext"); ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn); } if (!ldb_get_opaque(ldb, "schemaNamingContext")) { tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "schemaNamingContext"); ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn); } if (!ldb_get_opaque(ldb, "defaultNamingContext")) { tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "defaultNamingContext"); ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn); } talloc_free(tmp_ctx); } struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb) { void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext"); return talloc_get_type(opaque, struct ldb_dn); } struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb) { void *opaque = ldb_get_opaque(ldb, "configurationNamingContext"); return talloc_get_type(opaque, struct ldb_dn); } struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb) { void *opaque = ldb_get_opaque(ldb, "schemaNamingContext"); return talloc_get_type(opaque, struct ldb_dn); } struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb) { void *opaque = ldb_get_opaque(ldb, "defaultNamingContext"); return talloc_get_type(opaque, struct ldb_dn); } /* connect to a database. The URL can either be one of the following forms ldb://path ldapi://path flags is made up of LDB_FLG_* the options are passed uninterpreted to the backend, and are backend specific */ int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]) { int ret; char *url2; /* We seem to need to do this here, or else some utilities don't * get ldb backends */ ldb->flags = flags; url2 = talloc_strdup(ldb, url); if (!url2) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_set_opaque(ldb, "ldb_url", url2); if (ret != LDB_SUCCESS) { return ret; } /* * Take a copy of the options. */ ldb->options = ldb_options_copy(ldb, options); if (ldb->options == NULL && options != NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_load_modules(ldb, options); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for %s: %s", url, ldb_errstring(ldb)); return ret; } /* set the default base dn */ ldb_set_default_dns(ldb); return LDB_SUCCESS; } void ldb_set_errstring(struct ldb_context *ldb, const char *err_string) { ldb_asprintf_errstring(ldb, "%s", err_string); } void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) { va_list ap; char *old_err_string = NULL; if (ldb->err_string) { old_err_string = ldb->err_string; } va_start(ap, format); ldb->err_string = talloc_vasprintf(ldb, format, ap); va_end(ap); TALLOC_FREE(old_err_string); if (ldb->flags & LDB_FLG_ENABLE_TRACING) { ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_asprintf/set_errstring: %s", ldb->err_string); } } void ldb_reset_err_string(struct ldb_context *ldb) { if (ldb->err_string) { talloc_free(ldb->err_string); ldb->err_string = NULL; } } /* set an ldb error based on file:line */ int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line) { if (reason == NULL) { reason = ldb_strerror(ecode); } ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line); return ecode; } #define FIRST_OP_NOERR(ldb, op) do { \ next_module = ldb->modules; \ while (next_module && next_module->ops->op == NULL) { \ next_module = next_module->next; \ }; \ if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && next_module) { \ ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \ next_module->ops->name); \ } \ } while (0) #define FIRST_OP(ldb, op) do { \ FIRST_OP_NOERR(ldb, op); \ if (next_module == NULL) { \ ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \ return LDB_ERR_OPERATIONS_ERROR; \ } \ } while (0) /* start a transaction */ int ldb_transaction_start(struct ldb_context *ldb) { struct ldb_module *next_module; int status; ldb_debug(ldb, LDB_DEBUG_TRACE, "start ldb transaction (nesting: %d)", ldb->transaction_active); /* explicit transaction active, count nested requests */ if (ldb->transaction_active) { ldb->transaction_active++; return LDB_SUCCESS; } /* start a new transaction */ ldb->transaction_active++; ldb->prepare_commit_done = false; FIRST_OP(ldb, start_transaction); ldb_reset_err_string(ldb); status = next_module->ops->start_transaction(next_module); if (status != LDB_SUCCESS) { if (ldb->err_string == NULL) { /* no error string was setup by the backend */ ldb_asprintf_errstring(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", ldb_errstring(next_module->ldb)); } } else { if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "start ldb transaction success"); } } return status; } /* prepare for transaction commit (first phase of two phase commit) */ int ldb_transaction_prepare_commit(struct ldb_context *ldb) { struct ldb_module *next_module; int status; if (ldb->prepare_commit_done) { return LDB_SUCCESS; } /* commit only when all nested transactions are complete */ if (ldb->transaction_active > 1) { return LDB_SUCCESS; } ldb->prepare_commit_done = true; if (ldb->transaction_active < 0) { ldb_debug(ldb, LDB_DEBUG_FATAL, "prepare commit called but no ldb transactions are active!"); ldb->transaction_active = 0; return LDB_ERR_OPERATIONS_ERROR; } /* call prepare transaction if available */ FIRST_OP_NOERR(ldb, prepare_commit); if (next_module == NULL) { return LDB_SUCCESS; } ldb_reset_err_string(ldb); status = next_module->ops->prepare_commit(next_module); if (status != LDB_SUCCESS) { ldb->transaction_active--; /* if a next_module fails the prepare then we need to call the end transaction for everyone */ FIRST_OP(ldb, del_transaction); next_module->ops->del_transaction(next_module); if (ldb->err_string == NULL) { /* no error string was setup by the backend */ ldb_asprintf_errstring(ldb, "ldb transaction prepare commit: %s (%d)", ldb_strerror(status), status); } if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s", ldb_errstring(next_module->ldb)); } } return status; } /* commit a transaction */ int ldb_transaction_commit(struct ldb_context *ldb) { struct ldb_module *next_module; int status; status = ldb_transaction_prepare_commit(ldb); if (status != LDB_SUCCESS) { return status; } ldb->transaction_active--; ldb_debug(ldb, LDB_DEBUG_TRACE, "commit ldb transaction (nesting: %d)", ldb->transaction_active); /* commit only when all nested transactions are complete */ if (ldb->transaction_active > 0) { return LDB_SUCCESS; } if (ldb->transaction_active < 0) { ldb_debug(ldb, LDB_DEBUG_FATAL, "commit called but no ldb transactions are active!"); ldb->transaction_active = 0; return LDB_ERR_OPERATIONS_ERROR; } ldb_reset_err_string(ldb); FIRST_OP(ldb, end_transaction); status = next_module->ops->end_transaction(next_module); if (status != LDB_SUCCESS) { if (ldb->err_string == NULL) { /* no error string was setup by the backend */ ldb_asprintf_errstring(ldb, "ldb transaction commit: %s (%d)", ldb_strerror(status), status); } if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s", ldb_errstring(next_module->ldb)); } } return status; } /* cancel a transaction */ int ldb_transaction_cancel(struct ldb_context *ldb) { struct ldb_module *next_module; int status; ldb->transaction_active--; ldb_debug(ldb, LDB_DEBUG_TRACE, "cancel ldb transaction (nesting: %d)", ldb->transaction_active); /* really cancel only if all nested transactions are complete */ if (ldb->transaction_active > 0) { return LDB_SUCCESS; } if (ldb->transaction_active < 0) { ldb_debug(ldb, LDB_DEBUG_FATAL, "cancel called but no ldb transactions are active!"); ldb->transaction_active = 0; return LDB_ERR_OPERATIONS_ERROR; } FIRST_OP(ldb, del_transaction); status = next_module->ops->del_transaction(next_module); if (status != LDB_SUCCESS) { if (ldb->err_string == NULL) { /* no error string was setup by the backend */ ldb_asprintf_errstring(ldb, "ldb transaction cancel: %s (%d)", ldb_strerror(status), status); } if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s", ldb_errstring(next_module->ldb)); } } return status; } /* cancel a transaction with no error if no transaction is pending used when we fork() to clear any parent transactions */ int ldb_transaction_cancel_noerr(struct ldb_context *ldb) { if (ldb->transaction_active > 0) { return ldb_transaction_cancel(ldb); } return LDB_SUCCESS; } /* autostarts a transaction if none active */ static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req) { int ret; ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_request(ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret == LDB_SUCCESS) { return ldb_transaction_commit(ldb); } ldb_transaction_cancel(ldb); return ret; } int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type) { struct tevent_context *ev; int ret; if (handle == NULL) { return LDB_ERR_UNAVAILABLE; } if (handle->state == LDB_ASYNC_DONE) { if ((handle->status != LDB_SUCCESS) && (handle->ldb->err_string == NULL)) { /* if no error string was setup by the backend */ ldb_asprintf_errstring(handle->ldb, "ldb_wait from %s with LDB_ASYNC_DONE: %s (%d)", handle->location, ldb_strerror(handle->status), handle->status); } return handle->status; } ev = ldb_handle_get_event_context(handle); if (NULL == ev) { return ldb_oom(handle->ldb); } switch (type) { case LDB_WAIT_NONE: ret = tevent_loop_once(ev); if (ret != 0) { return ldb_operr(handle->ldb); } if (handle->status == LDB_SUCCESS) { return LDB_SUCCESS; } if (handle->ldb->err_string != NULL) { return handle->status; } /* * if no error string was setup by the backend */ ldb_asprintf_errstring(handle->ldb, "ldb_wait from %s with LDB_WAIT_NONE: %s (%d)", handle->location, ldb_strerror(handle->status), handle->status); return handle->status; case LDB_WAIT_ALL: while (handle->state != LDB_ASYNC_DONE) { ret = tevent_loop_once(ev); if (ret != 0) { return ldb_operr(handle->ldb); } if (handle->status != LDB_SUCCESS) { if (handle->ldb->err_string != NULL) { return handle->status; } /* * if no error string was setup by the * backend */ ldb_asprintf_errstring(handle->ldb, "ldb_wait from %s with " "LDB_WAIT_ALL: %s (%d)", handle->location, ldb_strerror(handle->status), handle->status); return handle->status; } } if (handle->status == LDB_SUCCESS) { return LDB_SUCCESS; } if (handle->ldb->err_string != NULL) { return handle->status; } /* * if no error string was setup by the backend */ ldb_asprintf_errstring(handle->ldb, "ldb_wait from %s with LDB_WAIT_ALL," " LDB_ASYNC_DONE: %s (%d)", handle->location, ldb_strerror(handle->status), handle->status); return handle->status; } return LDB_SUCCESS; } /* set the specified timeout or, if timeout is 0 set the default timeout */ int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout) { if (req == NULL) return LDB_ERR_OPERATIONS_ERROR; if (timeout != 0) { req->timeout = timeout; } else { req->timeout = ldb->default_timeout; } req->starttime = time(NULL); return LDB_SUCCESS; } /* calculates the new timeout based on the previous starttime and timeout */ int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq) { if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR; if (oldreq == NULL) { return ldb_set_timeout(ldb, newreq, 0); } newreq->starttime = oldreq->starttime; newreq->timeout = oldreq->timeout; return LDB_SUCCESS; } struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb) { struct ldb_handle *h; h = talloc_zero(mem_ctx, struct ldb_handle); if (h == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return NULL; } h->status = LDB_SUCCESS; h->state = LDB_ASYNC_INIT; h->ldb = ldb; h->flags = 0; h->location = NULL; h->parent = NULL; if (h->ldb->require_private_event_context == true) { h->event_context = tevent_context_init(h); if (h->event_context == NULL) { ldb_set_errstring(ldb, "Out of Memory allocating " "event context for new handle"); return NULL; } tevent_set_debug(h->event_context, ldb_tevent_debug, ldb); tevent_loop_allow_nesting(h->event_context); } return h; } static struct ldb_handle *ldb_handle_new_child(TALLOC_CTX *mem_ctx, struct ldb_request *parent_req) { struct ldb_handle *h; h = talloc_zero(mem_ctx, struct ldb_handle); if (h == NULL) { ldb_set_errstring(parent_req->handle->ldb, "Out of Memory"); return NULL; } h->status = LDB_SUCCESS; h->state = LDB_ASYNC_INIT; h->ldb = parent_req->handle->ldb; h->parent = parent_req; h->nesting = parent_req->handle->nesting + 1; h->flags = parent_req->handle->flags; h->custom_flags = parent_req->handle->custom_flags; h->event_context = parent_req->handle->event_context; return h; } /* set the permissions for new files to be passed to open() in backends that use local files */ void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms) { ldb->create_perms = perms; } unsigned int ldb_get_create_perms(struct ldb_context *ldb) { return ldb->create_perms; } void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev) { ldb->ev_ctx = ev; } struct tevent_context * ldb_get_event_context(struct ldb_context *ldb) { return ldb->ev_ctx; } void ldb_request_set_state(struct ldb_request *req, int state) { req->handle->state = state; } int ldb_request_get_status(struct ldb_request *req) { return req->handle->status; } /* * This function obtains the private event context for the handle, * which may have been created to avoid nested event loops during * ldb_tdb with the locks held */ struct tevent_context *ldb_handle_get_event_context(struct ldb_handle *handle) { if (handle->event_context != NULL) { return handle->event_context; } return ldb_get_event_context(handle->ldb); } /* * This function forces a specific ldb handle to use the global event * context. This allows a nested event loop to operate, so any open * transaction also needs to be aborted. * * Any events on this event context will be lost * * This is used in Samba when sending an IRPC to another part of the * same process instead of making a local DB modification. */ void ldb_handle_use_global_event_context(struct ldb_handle *handle) { TALLOC_FREE(handle->event_context); } void ldb_set_require_private_event_context(struct ldb_context *ldb) { ldb->require_private_event_context = true; } /* trace a ldb request */ static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req) { TALLOC_CTX *tmp_ctx = talloc_new(req); unsigned int i; struct ldb_ldif ldif; switch (req->operation) { case LDB_SEARCH: ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n"); ldb_debug_add(ldb, " dn: %s\n", ldb_dn_is_null(req->op.search.base)?"": ldb_dn_get_linearized(req->op.search.base)); ldb_debug_add(ldb, " scope: %s\n", req->op.search.scope==LDB_SCOPE_BASE?"base": req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN"); ldb_debug_add(ldb, " expr: %s\n", ldb_filter_from_tree(tmp_ctx, req->op.search.tree)); if (req->op.search.attrs == NULL) { ldb_debug_add(ldb, " attr: \n"); } else { for (i=0; req->op.search.attrs[i]; i++) { ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]); } } break; case LDB_DELETE: ldb_debug_add(ldb, "ldb_trace_request: DELETE\n"); ldb_debug_add(ldb, " dn: %s\n", ldb_dn_get_linearized(req->op.del.dn)); break; case LDB_RENAME: ldb_debug_add(ldb, "ldb_trace_request: RENAME\n"); ldb_debug_add(ldb, " olddn: %s\n", ldb_dn_get_linearized(req->op.rename.olddn)); ldb_debug_add(ldb, " newdn: %s\n", ldb_dn_get_linearized(req->op.rename.newdn)); break; case LDB_EXTENDED: ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n"); ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid); ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no"); break; case LDB_ADD: ldif.changetype = LDB_CHANGETYPE_ADD; ldif.msg = discard_const_p(struct ldb_message, req->op.add.message); ldb_debug_add(ldb, "ldb_trace_request: ADD\n"); /* * The choice to call * ldb_ldif_write_redacted_trace_string() is CRITICAL * for security. It ensures that we do not output * passwords into debug logs */ ldb_debug_add(req->handle->ldb, "%s\n", ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif)); break; case LDB_MODIFY: ldif.changetype = LDB_CHANGETYPE_MODIFY; ldif.msg = discard_const_p(struct ldb_message, req->op.mod.message); ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n"); /* * The choice to call * ldb_ldif_write_redacted_trace_string() is CRITICAL * for security. It ensures that we do not output * passwords into debug logs */ ldb_debug_add(req->handle->ldb, "%s\n", ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif)); break; case LDB_REQ_REGISTER_CONTROL: ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n"); ldb_debug_add(req->handle->ldb, "%s\n", req->op.reg_control.oid); break; case LDB_REQ_REGISTER_PARTITION: ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n"); ldb_debug_add(req->handle->ldb, "%s\n", ldb_dn_get_linearized(req->op.reg_partition.dn)); break; default: ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n", req->operation); break; } if (req->controls == NULL) { ldb_debug_add(ldb, " control: \n"); } else { for (i=0; req->controls && req->controls[i]; i++) { if (req->controls[i]->oid) { ldb_debug_add(ldb, " control: %s crit:%u data:%s\n", req->controls[i]->oid, req->controls[i]->critical, req->controls[i]->data?"yes":"no"); } } } ldb_debug_end(ldb, LDB_DEBUG_TRACE); talloc_free(tmp_ctx); } /* check that the element flags don't have any internal bits set */ static int ldb_msg_check_element_flags(struct ldb_context *ldb, const struct ldb_message *message) { unsigned i; for (i=0; inum_elements; i++) { if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) { ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n", message->elements[i].flags, message->elements[i].name, ldb_dn_get_linearized(message->dn)); return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; } } return LDB_SUCCESS; } /* * This context allows us to make the unlock be a talloc destructor * * This ensures that a request started, but not waited on, will still * unlock. */ struct ldb_db_lock_context { struct ldb_request *req; struct ldb_context *ldb; }; /* * We have to have a the unlock on a destructor so that we unlock the * DB if a caller calls talloc_free(req). We trust that the ldb * context has not already gone away. */ static int ldb_db_lock_destructor(struct ldb_db_lock_context *lock_context) { int ret; struct ldb_module *next_module; FIRST_OP_NOERR(lock_context->ldb, read_unlock); if (next_module != NULL) { ret = next_module->ops->read_unlock(next_module); } else { ret = LDB_SUCCESS; } if (ret != LDB_SUCCESS) { ldb_debug(lock_context->ldb, LDB_DEBUG_FATAL, "Failed to unlock db: %s / %s", ldb_errstring(lock_context->ldb), ldb_strerror(ret)); } return 0; } static int ldb_lock_backend_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_db_lock_context *lock_context; int ret; lock_context = talloc_get_type(req->context, struct ldb_db_lock_context); if (!ares) { return ldb_module_done(lock_context->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS || ares->type == LDB_REPLY_DONE) { ret = ldb_module_done(lock_context->req, ares->controls, ares->response, ares->error); /* * If this is a LDB_REPLY_DONE or an error, unlock the * DB by calling the destructor on this context */ talloc_free(lock_context); return ret; } /* Otherwise pass on the callback */ switch (ares->type) { case LDB_REPLY_ENTRY: return ldb_module_send_entry(lock_context->req, ares->message, ares->controls); case LDB_REPLY_REFERRAL: return ldb_module_send_referral(lock_context->req, ares->referral); default: /* Can't happen */ return LDB_ERR_OPERATIONS_ERROR; } } /* * Do an ldb_search() with a lock held, but release it if the request * is freed with talloc_free() */ static int lock_search(struct ldb_module *lock_module, struct ldb_request *req) { /* Used in FIRST_OP_NOERR to find where to send the lock request */ struct ldb_module *next_module = NULL; struct ldb_request *down_req = NULL; struct ldb_db_lock_context *lock_context; struct ldb_context *ldb = ldb_module_get_ctx(lock_module); int ret; lock_context = talloc(req, struct ldb_db_lock_context); if (lock_context == NULL) { return ldb_oom(ldb); } lock_context->ldb = ldb; lock_context->req = req; ret = ldb_build_search_req_ex(&down_req, ldb, req, req->op.search.base, req->op.search.scope, req->op.search.tree, req->op.search.attrs, req->controls, lock_context, ldb_lock_backend_callback, req); LDB_REQ_SET_LOCATION(down_req); if (ret != LDB_SUCCESS) { return ret; } /* call DB lock */ FIRST_OP_NOERR(ldb, read_lock); if (next_module != NULL) { ret = next_module->ops->read_lock(next_module); } else { ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; } if (ret == LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION) { /* We might be talking LDAP */ ldb_reset_err_string(ldb); TALLOC_FREE(lock_context); return ldb_next_request(lock_module, req); } else if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) { /* if no error string was setup by the backend */ ldb_asprintf_errstring(ldb, "Failed to get DB lock: %s (%d)", ldb_strerror(ret), ret); } else { talloc_set_destructor(lock_context, ldb_db_lock_destructor); } if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(lock_module, down_req); } /* start an ldb request NOTE: the request must be a talloc context. returns LDB_ERR_* on errors. */ int ldb_request(struct ldb_context *ldb, struct ldb_request *req) { struct ldb_module *next_module; int ret; if (req->callback == NULL) { ldb_set_errstring(ldb, "Requests MUST define callbacks"); return LDB_ERR_UNWILLING_TO_PERFORM; } ldb_reset_err_string(ldb); if (ldb->flags & LDB_FLG_ENABLE_TRACING) { ldb_trace_request(ldb, req); } /* call the first module in the chain */ switch (req->operation) { case LDB_SEARCH: { /* * A fake module to allow ldb_next_request() to be * re-used and to keep the locking out of this function. */ static const struct ldb_module_ops lock_module_ops = { .name = "lock_searches", .search = lock_search }; struct ldb_module lock_module = { .ldb = ldb, .next = ldb->modules, .ops = &lock_module_ops }; next_module = &lock_module; /* due to "ldb_build_search_req" base DN always != NULL */ if (!ldb_dn_validate(req->op.search.base)) { ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'", ldb_dn_get_linearized(req->op.search.base)); return LDB_ERR_INVALID_DN_SYNTAX; } ret = next_module->ops->search(next_module, req); break; } case LDB_ADD: if (!ldb_dn_validate(req->op.add.message->dn)) { ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'", ldb_dn_get_linearized(req->op.add.message->dn)); return LDB_ERR_INVALID_DN_SYNTAX; } /* * we have to normalize here, as so many places * in modules and backends assume we don't have two * elements with the same name */ ret = ldb_msg_normalize(ldb, req, req->op.add.message, discard_const(&req->op.add.message)); if (ret != LDB_SUCCESS) { ldb_oom(ldb); return ret; } FIRST_OP(ldb, add); ret = ldb_msg_check_element_flags(ldb, req->op.add.message); if (ret != LDB_SUCCESS) { /* * "ldb_msg_check_element_flags" generates an error * string */ return ret; } ret = next_module->ops->add(next_module, req); break; case LDB_MODIFY: if (!ldb_dn_validate(req->op.mod.message->dn)) { ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'", ldb_dn_get_linearized(req->op.mod.message->dn)); return LDB_ERR_INVALID_DN_SYNTAX; } FIRST_OP(ldb, modify); ret = ldb_msg_check_element_flags(ldb, req->op.mod.message); if (ret != LDB_SUCCESS) { /* * "ldb_msg_check_element_flags" generates an error * string */ return ret; } ret = next_module->ops->modify(next_module, req); break; case LDB_DELETE: if (!ldb_dn_validate(req->op.del.dn)) { ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'", ldb_dn_get_linearized(req->op.del.dn)); return LDB_ERR_INVALID_DN_SYNTAX; } FIRST_OP(ldb, del); ret = next_module->ops->del(next_module, req); break; case LDB_RENAME: if (!ldb_dn_validate(req->op.rename.olddn)) { ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'", ldb_dn_get_linearized(req->op.rename.olddn)); return LDB_ERR_INVALID_DN_SYNTAX; } if (!ldb_dn_validate(req->op.rename.newdn)) { ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'", ldb_dn_get_linearized(req->op.rename.newdn)); return LDB_ERR_INVALID_DN_SYNTAX; } FIRST_OP(ldb, rename); ret = next_module->ops->rename(next_module, req); break; case LDB_EXTENDED: FIRST_OP(ldb, extended); ret = next_module->ops->extended(next_module, req); break; default: FIRST_OP(ldb, request); ret = next_module->ops->request(next_module, req); break; } if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) { /* if no error string was setup by the backend */ ldb_asprintf_errstring(ldb, "ldb_request: %s (%d)", ldb_strerror(ret), ret); } return ret; } int ldb_request_done(struct ldb_request *req, int status) { req->handle->state = LDB_ASYNC_DONE; req->handle->status = status; return status; } /* search the database given a LDAP-like search expression returns an LDB error code Use talloc_free to free the ldb_message returned in 'res', if successful */ int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_result *res; unsigned int n; res = talloc_get_type(req->context, struct ldb_result); if (!ares) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_request_done(req, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: res->msgs = talloc_realloc(res, res->msgs, struct ldb_message *, res->count + 2); if (! res->msgs) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } res->msgs[res->count + 1] = NULL; res->msgs[res->count] = talloc_move(res->msgs, &ares->message); res->count++; break; case LDB_REPLY_REFERRAL: if (res->refs) { for (n = 0; res->refs[n]; n++) /*noop*/ ; } else { n = 0; } res->refs = talloc_realloc(res, res->refs, char *, n + 2); if (! res->refs) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } res->refs[n] = talloc_move(res->refs, &ares->referral); res->refs[n + 1] = NULL; break; case LDB_REPLY_DONE: /* TODO: we should really support controls on entries * and referrals too! */ res->controls = talloc_move(res, &ares->controls); /* this is the last message, and means the request is done */ /* we have to signal and eventual ldb_wait() waiting that the * async request operation was completed */ talloc_free(ares); return ldb_request_done(req, LDB_SUCCESS); } talloc_free(ares); return LDB_SUCCESS; } int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_result *res; unsigned int n; int ret; res = talloc_get_type(req->context, struct ldb_result); if (!ares) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { ret = ares->error; talloc_free(ares); return ldb_request_done(req, ret); } switch (ares->type) { case LDB_REPLY_REFERRAL: if (res->refs) { for (n = 0; res->refs[n]; n++) /*noop*/ ; } else { n = 0; } res->refs = talloc_realloc(res, res->refs, char *, n + 2); if (! res->refs) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } res->refs[n] = talloc_move(res->refs, &ares->referral); res->refs[n + 1] = NULL; break; case LDB_REPLY_DONE: talloc_free(ares); return ldb_request_done(req, LDB_SUCCESS); default: talloc_free(ares); ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } talloc_free(ares); return ldb_request_done(req, LDB_SUCCESS); } int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares) { int ret; if (!ares) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { ret = ares->error; talloc_free(ares); return ldb_request_done(req, ret); } if (ares->type != LDB_REPLY_DONE) { talloc_free(ares); ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } talloc_free(ares); return ldb_request_done(req, LDB_SUCCESS); } static struct ldb_request *ldb_build_req_common(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_request *req = NULL; req = talloc_zero(mem_ctx, struct ldb_request); if (req == NULL) { return NULL; } req->controls = controls; req->context = context; req->callback = callback; ldb_set_timeout_from_prev_req(ldb, parent, req); if (parent != NULL) { req->handle = ldb_handle_new_child(req, parent); if (req->handle == NULL) { TALLOC_FREE(req); return NULL; } } else { req->handle = ldb_handle_new(req, ldb); if (req->handle == NULL) { TALLOC_FREE(req); return NULL; } } return req; } int ldb_build_search_req_ex(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const *attrs, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_request *req; *ret_req = NULL; req = ldb_build_req_common(mem_ctx, ldb, controls, context, callback, parent); if (req == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } req->operation = LDB_SEARCH; if (base == NULL) { req->op.search.base = ldb_dn_new(req, ldb, NULL); } else { req->op.search.base = base; } req->op.search.scope = scope; req->op.search.tree = tree; if (req->op.search.tree == NULL) { ldb_set_errstring(ldb, "'tree' can't be NULL"); talloc_free(req); return LDB_ERR_OPERATIONS_ERROR; } req->op.search.attrs = attrs; *ret_req = req; return LDB_SUCCESS; } int ldb_build_search_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *base, enum ldb_scope scope, const char *expression, const char * const *attrs, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_parse_tree *tree; int ret; tree = ldb_parse_tree(mem_ctx, expression); if (tree == NULL) { ldb_set_errstring(ldb, "Unable to parse search expression"); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base, scope, tree, attrs, controls, context, callback, parent); if (ret == LDB_SUCCESS) { talloc_steal(*ret_req, tree); } return ret; } int ldb_build_add_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *message, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_request *req; *ret_req = NULL; req = ldb_build_req_common(mem_ctx, ldb, controls, context, callback, parent); if (req == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } req->operation = LDB_ADD; req->op.add.message = message; *ret_req = req; return LDB_SUCCESS; } int ldb_build_mod_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *message, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_request *req; *ret_req = NULL; req = ldb_build_req_common(mem_ctx, ldb, controls, context, callback, parent); if (req == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } req->operation = LDB_MODIFY; req->op.mod.message = message; *ret_req = req; return LDB_SUCCESS; } int ldb_build_del_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_request *req; *ret_req = NULL; req = ldb_build_req_common(mem_ctx, ldb, controls, context, callback, parent); if (req == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } req->operation = LDB_DELETE; req->op.del.dn = dn; *ret_req = req; return LDB_SUCCESS; } int ldb_build_rename_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *olddn, struct ldb_dn *newdn, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_request *req; *ret_req = NULL; req = ldb_build_req_common(mem_ctx, ldb, controls, context, callback, parent); if (req == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } req->operation = LDB_RENAME; req->op.rename.olddn = olddn; req->op.rename.newdn = newdn; *ret_req = req; return LDB_SUCCESS; } int ldb_extended_default_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_result *res; res = talloc_get_type(req->context, struct ldb_result); if (!ares) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_request_done(req, ares->error); } if (ares->type == LDB_REPLY_DONE) { /* TODO: we should really support controls on entries and referrals too! */ res->extended = talloc_move(res, &ares->response); res->controls = talloc_move(res, &ares->controls); talloc_free(ares); return ldb_request_done(req, LDB_SUCCESS); } talloc_free(ares); ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } int ldb_build_extended_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *oid, void *data, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent) { struct ldb_request *req; *ret_req = NULL; req = ldb_build_req_common(mem_ctx, ldb, controls, context, callback, parent); if (req == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } req->operation = LDB_EXTENDED; req->op.extended.oid = oid; req->op.extended.data = data; *ret_req = req; return LDB_SUCCESS; } int ldb_extended(struct ldb_context *ldb, const char *oid, void *data, struct ldb_result **_res) { struct ldb_request *req; int ret; struct ldb_result *res; *_res = NULL; req = NULL; res = talloc_zero(ldb, struct ldb_result); if (!res) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_build_extended_req(&req, ldb, ldb, oid, data, NULL, res, ldb_extended_default_callback, NULL); ldb_req_set_location(req, "ldb_extended"); if (ret != LDB_SUCCESS) goto done; ldb_set_timeout(ldb, req, 0); /* use default timeout */ ret = ldb_request(ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } done: if (ret != LDB_SUCCESS) { talloc_free(res); res = NULL; } talloc_free(req); *_res = res; return ret; } /* note that ldb_search() will automatically replace a NULL 'base' value with the defaultNamingContext from the rootDSE if available. */ int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result **result, struct ldb_dn *base, enum ldb_scope scope, const char * const *attrs, const char *exp_fmt, ...) { struct ldb_request *req; struct ldb_result *res; char *expression; va_list ap; int ret; expression = NULL; *result = NULL; req = NULL; res = talloc_zero(mem_ctx, struct ldb_result); if (!res) { return LDB_ERR_OPERATIONS_ERROR; } if (exp_fmt) { va_start(ap, exp_fmt); expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); va_end(ap); if (!expression) { talloc_free(res); return LDB_ERR_OPERATIONS_ERROR; } } ret = ldb_build_search_req(&req, ldb, mem_ctx, base?base:ldb_get_default_basedn(ldb), scope, expression, attrs, NULL, res, ldb_search_default_callback, NULL); ldb_req_set_location(req, "ldb_search"); if (ret != LDB_SUCCESS) goto done; ret = ldb_request(ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } done: if (ret != LDB_SUCCESS) { talloc_free(res); res = NULL; } talloc_free(expression); talloc_free(req); *result = res; return ret; } /* add a record to the database. Will fail if a record with the given class and key already exists */ int ldb_add(struct ldb_context *ldb, const struct ldb_message *message) { struct ldb_request *req; int ret; ret = ldb_msg_sanity_check(ldb, message); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_build_add_req(&req, ldb, ldb, message, NULL, NULL, ldb_op_default_callback, NULL); ldb_req_set_location(req, "ldb_add"); if (ret != LDB_SUCCESS) return ret; /* do request and autostart a transaction */ ret = ldb_autotransaction_request(ldb, req); talloc_free(req); return ret; } /* modify the specified attributes of a record */ int ldb_modify(struct ldb_context *ldb, const struct ldb_message *message) { struct ldb_request *req; int ret; ret = ldb_msg_sanity_check(ldb, message); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_build_mod_req(&req, ldb, ldb, message, NULL, NULL, ldb_op_default_callback, NULL); ldb_req_set_location(req, "ldb_modify"); if (ret != LDB_SUCCESS) return ret; /* do request and autostart a transaction */ ret = ldb_autotransaction_request(ldb, req); talloc_free(req); return ret; } /* delete a record from the database */ int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn) { struct ldb_request *req; int ret; ret = ldb_build_del_req(&req, ldb, ldb, dn, NULL, NULL, ldb_op_default_callback, NULL); ldb_req_set_location(req, "ldb_delete"); if (ret != LDB_SUCCESS) return ret; /* do request and autostart a transaction */ ret = ldb_autotransaction_request(ldb, req); talloc_free(req); return ret; } /* rename a record in the database */ int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn) { struct ldb_request *req; int ret; ret = ldb_build_rename_req(&req, ldb, ldb, olddn, newdn, NULL, NULL, ldb_op_default_callback, NULL); ldb_req_set_location(req, "ldb_rename"); if (ret != LDB_SUCCESS) return ret; /* do request and autostart a transaction */ ret = ldb_autotransaction_request(ldb, req); talloc_free(req); return ret; } /* return the global sequence number */ int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num) { struct ldb_seqnum_request *seq; struct ldb_seqnum_result *seqr; struct ldb_result *res; TALLOC_CTX *tmp_ctx; int ret; *seq_num = 0; tmp_ctx = talloc_zero(ldb, struct ldb_request); if (tmp_ctx == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request); if (seq == NULL) { ldb_set_errstring(ldb, "Out of Memory"); ret = LDB_ERR_OPERATIONS_ERROR; goto done; } seq->type = type; ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res); if (ret != LDB_SUCCESS) { goto done; } talloc_steal(tmp_ctx, res); if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) { ldb_set_errstring(ldb, "Invalid OID in reply"); ret = LDB_ERR_OPERATIONS_ERROR; goto done; } seqr = talloc_get_type(res->extended->data, struct ldb_seqnum_result); *seq_num = seqr->seq_num; done: talloc_free(tmp_ctx); return ret; } /* return extended error information */ const char *ldb_errstring(struct ldb_context *ldb) { if (ldb->err_string) { return ldb->err_string; } return NULL; } /* return a string explaining what a ldb error constant meancs */ const char *ldb_strerror(int ldb_err) { switch (ldb_err) { case LDB_SUCCESS: return "Success"; case LDB_ERR_OPERATIONS_ERROR: return "Operations error"; case LDB_ERR_PROTOCOL_ERROR: return "Protocol error"; case LDB_ERR_TIME_LIMIT_EXCEEDED: return "Time limit exceeded"; case LDB_ERR_SIZE_LIMIT_EXCEEDED: return "Size limit exceeded"; case LDB_ERR_COMPARE_FALSE: return "Compare false"; case LDB_ERR_COMPARE_TRUE: return "Compare true"; case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED: return "Auth method not supported"; case LDB_ERR_STRONG_AUTH_REQUIRED: return "Strong auth required"; /* 9 RESERVED */ case LDB_ERR_REFERRAL: return "Referral error"; case LDB_ERR_ADMIN_LIMIT_EXCEEDED: return "Admin limit exceeded"; case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION: return "Unsupported critical extension"; case LDB_ERR_CONFIDENTIALITY_REQUIRED: return "Confidentiality required"; case LDB_ERR_SASL_BIND_IN_PROGRESS: return "SASL bind in progress"; case LDB_ERR_NO_SUCH_ATTRIBUTE: return "No such attribute"; case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE: return "Undefined attribute type"; case LDB_ERR_INAPPROPRIATE_MATCHING: return "Inappropriate matching"; case LDB_ERR_CONSTRAINT_VIOLATION: return "Constraint violation"; case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: return "Attribute or value exists"; case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: return "Invalid attribute syntax"; /* 22-31 unused */ case LDB_ERR_NO_SUCH_OBJECT: return "No such object"; case LDB_ERR_ALIAS_PROBLEM: return "Alias problem"; case LDB_ERR_INVALID_DN_SYNTAX: return "Invalid DN syntax"; /* 35 RESERVED */ case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM: return "Alias dereferencing problem"; /* 37-47 unused */ case LDB_ERR_INAPPROPRIATE_AUTHENTICATION: return "Inappropriate authentication"; case LDB_ERR_INVALID_CREDENTIALS: return "Invalid credentials"; case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: return "insufficient access rights"; case LDB_ERR_BUSY: return "Busy"; case LDB_ERR_UNAVAILABLE: return "Unavailable"; case LDB_ERR_UNWILLING_TO_PERFORM: return "Unwilling to perform"; case LDB_ERR_LOOP_DETECT: return "Loop detect"; /* 55-63 unused */ case LDB_ERR_NAMING_VIOLATION: return "Naming violation"; case LDB_ERR_OBJECT_CLASS_VIOLATION: return "Object class violation"; case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF: return "Not allowed on non-leaf"; case LDB_ERR_NOT_ALLOWED_ON_RDN: return "Not allowed on RDN"; case LDB_ERR_ENTRY_ALREADY_EXISTS: return "Entry already exists"; case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED: return "Object class mods prohibited"; /* 70 RESERVED FOR CLDAP */ case LDB_ERR_AFFECTS_MULTIPLE_DSAS: return "Affects multiple DSAs"; /* 72-79 unused */ case LDB_ERR_OTHER: return "Other"; } return "Unknown error"; } /* set backend specific opaque parameters */ int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value) { struct ldb_opaque *o; /* allow updating an existing value */ for (o=ldb->opaque;o;o=o->next) { if (strcmp(o->name, name) == 0) { o->value = value; return LDB_SUCCESS; } } o = talloc(ldb, struct ldb_opaque); if (o == NULL) { ldb_oom(ldb); return LDB_ERR_OTHER; } o->next = ldb->opaque; o->name = name; o->value = value; ldb->opaque = o; return LDB_SUCCESS; } /* get a previously set opaque value */ void *ldb_get_opaque(struct ldb_context *ldb, const char *name) { struct ldb_opaque *o; for (o=ldb->opaque;o;o=o->next) { if (strcmp(o->name, name) == 0) { return o->value; } } return NULL; } int ldb_global_init(void) { /* Provided for compatibility with some older versions of ldb */ return 0; } /* return the ldb flags */ unsigned int ldb_get_flags(struct ldb_context *ldb) { return ldb->flags; } /* set the ldb flags */ void ldb_set_flags(struct ldb_context *ldb, unsigned flags) { ldb->flags = flags; } /* set the location in a ldb request. Used for debugging */ void ldb_req_set_location(struct ldb_request *req, const char *location) { if (req && req->handle) { req->handle->location = location; } } /* return the location set with dsdb_req_set_location */ const char *ldb_req_location(struct ldb_request *req) { return req->handle->location; } /** mark a request as untrusted. This tells the rootdse module to remove unregistered controls */ void ldb_req_mark_untrusted(struct ldb_request *req) { req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED; } /** mark a request as trusted. */ void ldb_req_mark_trusted(struct ldb_request *req) { req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED; } /** set custom flags. Those flags are set by applications using ldb, they are application dependent and the same bit can have different meaning in different application. */ void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags) { if (req != NULL && req->handle != NULL) { req->handle->custom_flags = flags; } } /** get custom flags. Those flags are set by applications using ldb, they are application dependent and the same bit can have different meaning in different application. */ uint32_t ldb_req_get_custom_flags(struct ldb_request *req) { if (req != NULL && req->handle != NULL) { return req->handle->custom_flags; } /* * 0 is not something any better or worse than * anything else as req or the handle is NULL */ return 0; } /** * return true if a request is untrusted */ bool ldb_req_is_untrusted(struct ldb_request *req) { return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0; } ldb-2.0.8/common/ldb_attributes.c0000660000000000000000000002463413444661620016700 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2005 ** 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 . */ /* register handlers for specific attributes and objectclass relationships this allows a backend to store its schema information in any format it likes (or to not have any schema information at all) while keeping the message matching logic generic */ #include "ldb_private.h" #include "ldb_handlers.h" /* fill in an attribute to the ldb_schema into the supplied buffer if flags contains LDB_ATTR_FLAG_ALLOCATED the attribute name string will be copied using talloc_strdup(), otherwise it needs to be a static const string at least with a lifetime longer than the ldb struct! the ldb_schema_syntax structure should be a pointer to a static const struct or at least it needs to be a struct with a longer lifetime than the ldb context! */ int ldb_schema_attribute_fill_with_syntax(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *attribute, unsigned flags, const struct ldb_schema_syntax *syntax, struct ldb_schema_attribute *a) { a->name = attribute; a->flags = flags; a->syntax = syntax; if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { a->name = talloc_strdup(mem_ctx, a->name); if (a->name == NULL) { ldb_oom(ldb); return -1; } } return 0; } /* add a attribute to the ldb_schema if flags contains LDB_ATTR_FLAG_ALLOCATED the attribute name string will be copied using talloc_strdup(), otherwise it needs to be a static const string at least with a lifetime longer than the ldb struct! the ldb_schema_syntax structure should be a pointer to a static const struct or at least it needs to be a struct with a longer lifetime than the ldb context! */ int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, const char *attribute, unsigned flags, const struct ldb_schema_syntax *syntax) { unsigned int i, n; struct ldb_schema_attribute *a; if (!syntax) { return LDB_ERR_OPERATIONS_ERROR; } n = ldb->schema.num_attributes + 1; a = talloc_realloc(ldb, ldb->schema.attributes, struct ldb_schema_attribute, n); if (a == NULL) { ldb_oom(ldb); return -1; } ldb->schema.attributes = a; for (i = 0; i < ldb->schema.num_attributes; i++) { int cmp = ldb_attr_cmp(attribute, a[i].name); if (cmp == 0) { /* silently ignore attempts to overwrite fixed attributes */ if (a[i].flags & LDB_ATTR_FLAG_FIXED) { return 0; } if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { talloc_free(discard_const_p(char, a[i].name)); } /* To cancel out increment below */ ldb->schema.num_attributes--; break; } else if (cmp < 0) { memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i)); break; } } ldb->schema.num_attributes++; a[i].name = attribute; a[i].flags = flags; a[i].syntax = syntax; if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { a[i].name = talloc_strdup(a, a[i].name); if (a[i].name == NULL) { ldb_oom(ldb); return -1; } } return 0; } static const struct ldb_schema_syntax ldb_syntax_default = { .name = LDB_SYNTAX_OCTET_STRING, .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_handler_copy, .comparison_fn = ldb_comparison_binary }; static const struct ldb_schema_attribute ldb_attribute_default = { .name = NULL, .flags = 0, .syntax = &ldb_syntax_default }; /* * Return the attribute handlers for a given attribute * * @param ldb ldb context * @param name attribute name to search for * @return Always return valid pointer to schema attribute. * In case there is no attribute with name, * ldb_attribute_default is returned */ static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal( struct ldb_context *ldb, const char *name) { /* for binary search we need signed variables */ unsigned int i, e, b = 0; int r; const struct ldb_schema_attribute *def = &ldb_attribute_default; /* fallback to default attribute implementation */ if (name == NULL) { return def; } /* as handlers are sorted, '*' must be the first if present */ if (strcmp(ldb->schema.attributes[0].name, "*") == 0) { def = &ldb->schema.attributes[0]; b = 1; } /* do a binary search on the array */ e = ldb->schema.num_attributes - 1; while ((b <= e) && (e != (unsigned int) -1)) { i = (b + e) / 2; r = ldb_attr_cmp(name, ldb->schema.attributes[i].name); if (r == 0) { return &ldb->schema.attributes[i]; } if (r < 0) { e = i - 1; } else { b = i + 1; } } return def; } /* return the attribute handlers for a given attribute */ const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, const char *name) { if (ldb->schema.attribute_handler_override) { const struct ldb_schema_attribute *ret = ldb->schema.attribute_handler_override(ldb, ldb->schema.attribute_handler_override_private, name); if (ret) { return ret; } } return ldb_schema_attribute_by_name_internal(ldb, name); } /* add to the list of ldif handlers for this ldb context */ void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name) { const struct ldb_schema_attribute *a; ptrdiff_t i; a = ldb_schema_attribute_by_name_internal(ldb, name); if (a == NULL || a->name == NULL) { return; } /* FIXED attributes are never removed */ if (a->flags & LDB_ATTR_FLAG_FIXED) { return; } if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { talloc_free(discard_const_p(char, a->name)); } i = a - ldb->schema.attributes; if (i < ldb->schema.num_attributes - 1) { memmove(&ldb->schema.attributes[i], a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); } ldb->schema.num_attributes--; } /* remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context This is to permit correct reloads */ void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag) { ptrdiff_t i; for (i = 0; i < ldb->schema.num_attributes;) { const struct ldb_schema_attribute *a = &ldb->schema.attributes[i]; /* FIXED attributes are never removed */ if (a->flags & LDB_ATTR_FLAG_FIXED) { i++; continue; } if ((a->flags & flag) == 0) { i++; continue; } if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { talloc_free(discard_const_p(char, a->name)); } if (i < ldb->schema.num_attributes - 1) { memmove(&ldb->schema.attributes[i], a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); } ldb->schema.num_attributes--; } } /* setup a attribute handler using a standard syntax */ int ldb_schema_attribute_add(struct ldb_context *ldb, const char *attribute, unsigned flags, const char *syntax) { const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax); return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s); } /* setup the attribute handles for well known attributes */ int ldb_setup_wellknown_attributes(struct ldb_context *ldb) { const struct { const char *attr; const char *syntax; } wellknown[] = { { "dn", LDB_SYNTAX_DN }, { "distinguishedName", LDB_SYNTAX_DN }, { "cn", LDB_SYNTAX_DIRECTORY_STRING }, { "dc", LDB_SYNTAX_DIRECTORY_STRING }, { "ou", LDB_SYNTAX_DIRECTORY_STRING }, { "objectClass", LDB_SYNTAX_OBJECTCLASS } }; unsigned int i; int ret; for (i=0;ischema.num_dn_extended_syntax + 1; a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax, struct ldb_dn_extended_syntax, n); if (!a) { return LDB_ERR_OPERATIONS_ERROR; } a[ldb->schema.num_dn_extended_syntax] = *syntax; ldb->schema.dn_extended_syntax = a; ldb->schema.num_dn_extended_syntax = n; return LDB_SUCCESS; } /* return the extended dn syntax for a given name */ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, const char *name) { unsigned int i; for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) { if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) { return &ldb->schema.dn_extended_syntax[i]; } } return NULL; } /* set an attribute handler override function - used to delegate schema handling to external code */ void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, ldb_attribute_handler_override_fn_t override, void *private_data) { ldb->schema.attribute_handler_override_private = private_data; ldb->schema.attribute_handler_override = override; } /* set that the attribute handler override function - used to delegate schema handling to external code, is handling setting LDB_ATTR_FLAG_INDEXED */ void ldb_schema_set_override_indexlist(struct ldb_context *ldb, bool one_level_indexes) { ldb->schema.index_handler_override = true; ldb->schema.one_level_indexes = one_level_indexes; } /* * set that the GUID index mode is in operation * * The caller must ensure the supplied strings do not go out of * scope (they are typically constant memory). */ void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, const char *GUID_index_attribute, const char *GUID_index_dn_component) { ldb->schema.GUID_index_attribute = GUID_index_attribute; ldb->schema.GUID_index_dn_component = GUID_index_dn_component; } ldb-2.0.8/common/ldb_controls.c0000660000000000000000000010240613444661620016347 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2005 ** 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 . */ /* * Name: ldb_controls.c * * Component: ldb controls utility functions * * Description: helper functions for control modules * * Author: Simo Sorce */ #include "ldb_private.h" /* check if a control with the specified "oid" exist and return it */ /* returns NULL if not found */ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid) { unsigned int i; if (req->controls != NULL) { for (i = 0; req->controls[i]; i++) { if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) { break; } } return req->controls[i]; } return NULL; } /* check if a control with the specified "oid" exist and return it */ /* returns NULL if not found */ struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid) { unsigned int i; if (rep->controls != NULL) { for (i = 0; rep->controls[i]; i++) { if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) { break; } } return rep->controls[i]; } return NULL; } /* * Saves the current controls list into the "saver" (can also be NULL) and * replace the one in "req" with a new one excluding the "exclude" control * (if it is NULL then the list remains the same) * * Returns 0 on error. */ int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) { struct ldb_control **lcs, **lcs_old; unsigned int i, j; lcs_old = req->controls; if (saver != NULL) { *saver = lcs_old; } for (i = 0; req->controls && req->controls[i]; i++); if (i == 0) { req->controls = NULL; return 1; } lcs = talloc_array(req, struct ldb_control *, i + 1); if (!lcs) { return 0; } for (i = 0, j = 0; lcs_old[i]; i++) { if (exclude == lcs_old[i]) continue; lcs[j] = lcs_old[i]; j++; } lcs[j] = NULL; req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1); if (req->controls == NULL) { return 0; } return 1; } /* * Returns a list of controls, except the one specified with "exclude" (can * also be NULL). Included controls become a child of returned list if they * were children of "controls_in". * * Returns NULL on error (OOM) or an empty control list. */ struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, TALLOC_CTX *mem_ctx, struct ldb_control *exclude) { struct ldb_control **lcs = NULL; unsigned int i, j, n; for (i = 0; controls_in && controls_in[i]; i++); if (i == 0) { return NULL; } n = i; for (i = 0, j = 0; controls_in && controls_in[i]; i++) { if (exclude == controls_in[i]) continue; if (!lcs) { /* Allocate here so if we remove the only * control, or there were no controls, we * don't allocate at all, and just return * NULL */ lcs = talloc_array(mem_ctx, struct ldb_control *, n + 1); if (!lcs) { return NULL; } } lcs[j] = controls_in[i]; talloc_reparent(controls_in, lcs, lcs[j]); j++; } if (lcs) { lcs[j] = NULL; lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1); } return lcs; } /* check if there's any control marked as critical in the list */ /* return True if any, False if none */ int ldb_check_critical_controls(struct ldb_control **controls) { unsigned int i; if (controls == NULL) { return 0; } for (i = 0; controls[i]; i++) { if (controls[i]->critical) { return 1; } } return 0; } int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data) { unsigned int i, n; struct ldb_control **ctrls; struct ldb_control *ctrl; for (n=0; req->controls && req->controls[n];n++) { /* having two controls of the same OID makes no sense */ if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } } ctrls = talloc_array(req, struct ldb_control *, n + 2); if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; for (i=0; icontrols[i]; } req->controls = ctrls; ctrls[n] = NULL; ctrls[n+1] = NULL; ctrl = talloc(ctrls, struct ldb_control); if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; ctrl->oid = talloc_strdup(ctrl, oid); if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; ctrl->critical = critical; ctrl->data = data; ctrls[n] = ctrl; return LDB_SUCCESS; } int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data) { unsigned n; struct ldb_control **ctrls; struct ldb_control *ctrl; for (n=0; ares->controls && ares->controls[n];) { /* having two controls of the same OID makes no sense */ if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) { return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } n++; } ctrls = talloc_realloc(ares, ares->controls, struct ldb_control *, n + 2); if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; ares->controls = ctrls; ctrls[n] = NULL; ctrls[n+1] = NULL; ctrl = talloc(ctrls, struct ldb_control); if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; ctrl->oid = talloc_strdup(ctrl, oid); if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; ctrl->critical = critical; ctrl->data = data; ctrls[n] = ctrl; return LDB_SUCCESS; } /* Add a control to the request, replacing the old one if it is already in the request */ int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data) { unsigned int n; int ret; ret = ldb_request_add_control(req, oid, critical, data); if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { return ret; } for (n=0; req->controls[n];n++) { if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { req->controls[n]->critical = critical; req->controls[n]->data = data; return LDB_SUCCESS; } } return LDB_ERR_OPERATIONS_ERROR; } /* * Return a control as string * the project (ie. name:value1:value2:...:valuen * The string didn't include the criticity of the critical flag */ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control) { char *res = NULL; if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control); char *cookie; cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); if (cookie == NULL) { return NULL; } if (cookie[0] != '\0') { res = talloc_asprintf(mem_ctx, "%s:%d:%s", LDB_CONTROL_PAGED_RESULTS_NAME, control->critical, cookie); talloc_free(cookie); } else { res = talloc_asprintf(mem_ctx, "%s:%d", LDB_CONTROL_PAGED_RESULTS_NAME, control->critical); } return res; } if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) { struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data, struct ldb_vlv_resp_control); char *cookie; cookie = ldb_base64_encode(mem_ctx, (char *)rep_control->contextId, rep_control->ctxid_len); if (cookie == NULL) { return NULL; } res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%s", LDB_CONTROL_VLV_RESP_NAME, control->critical, rep_control->targetPosition, rep_control->contentCount, rep_control->vlv_result, cookie); return res; } if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) { struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data, struct ldb_sort_resp_control); res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", LDB_CONTROL_SORT_RESP_NAME, control->critical, rep_control->result, rep_control->attr_desc); return res; } if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) { struct ldb_asq_control *rep_control = talloc_get_type(control->data, struct ldb_asq_control); res = talloc_asprintf(mem_ctx, "%s:%d:%d", LDB_CONTROL_SORT_RESP_NAME, control->critical, rep_control->result); return res; } if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) { char *cookie; struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, struct ldb_dirsync_control); cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); if (cookie == NULL) { return NULL; } res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", LDB_CONTROL_DIRSYNC_NAME, control->critical, rep_control->flags, rep_control->max_attributes, cookie); talloc_free(cookie); return res; } if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) { char *cookie; struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, struct ldb_dirsync_control); cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); if (cookie == NULL) { return NULL; } res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", LDB_CONTROL_DIRSYNC_EX_NAME, control->critical, rep_control->flags, rep_control->max_attributes, cookie); talloc_free(cookie); return res; } if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) { struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control); if (rep_control->gc != NULL) { res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", LDB_CONTROL_VERIFY_NAME_NAME, control->critical, rep_control->flags, rep_control->gc); } else { res = talloc_asprintf(mem_ctx, "%s:%d:%d", LDB_CONTROL_VERIFY_NAME_NAME, control->critical, rep_control->flags); } return res; } /* * From here we don't know the control */ if (control->data == NULL) { /* * We don't know the control but there is no real data attached * to it so we can represent it with local_oid:oid:criticity. */ res = talloc_asprintf(mem_ctx, "local_oid:%s:%d", control->oid, control->critical); } else { res = talloc_asprintf(mem_ctx, "unknown oid:%s", control->oid); } return res; } /* * A little trick to allow one to use constants defined in headers rather than * hardwritten in the file. * "sizeof" will return the \0 char as well so it will take the place of ":" * in the length of the string. */ #define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) /* Parse one string and return associated control if parsing is successful*/ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings) { struct ldb_control *ctrl; if (!(ctrl = talloc(mem_ctx, struct ldb_control))) { ldb_oom(ldb); return NULL; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_VLV_REQ_NAME) == 0) { struct ldb_vlv_req_control *control; const char *p; char attr[1024]; char ctxid[1024]; int crit, bc, ac, os, cc, ret; attr[0] = '\0'; ctxid[0] = '\0'; p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]); ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); /* We allow 2 ways to encode the GT_EQ case, because the comparison string might contain null bytes or colons, which would break sscanf (or indeed any parsing mechanism). */ if (ret == 3) { ret = sscanf(p, "%d:%d:%d:>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); } if (ret == 3) { int len; ret = sscanf(p, "%d:%d:%d:base64>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); len = ldb_base64_decode(attr); if (len < 0) { ret = -1; } } if ((ret < 4) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid VLV control syntax\n" " syntax: crit(b):bc(n):ac(n):" "{os(n):cc(n)|>=val(s)|base64>=val(o)}[:ctxid(o)]\n" " note: b = boolean, n = number, s = string, o = b64 binary blob"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_VLV_REQ_OID; ctrl->critical = crit; if (!(control = talloc(ctrl, struct ldb_vlv_req_control))) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->beforeCount = bc; control->afterCount = ac; if (attr[0]) { control->type = 1; control->match.gtOrEq.value = talloc_strdup(control, attr); control->match.gtOrEq.value_len = strlen(attr); } else { control->type = 0; control->match.byOffset.offset = os; control->match.byOffset.contentCount = cc; } if (ctxid[0]) { int len = ldb_base64_decode(ctxid); if (len < 0) { ldb_set_errstring(ldb, "invalid VLV context_id\n"); talloc_free(ctrl); return NULL; } control->ctxid_len = len; control->contextId = talloc_memdup(control, ctxid, control->ctxid_len); if (control->contextId == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } } else { control->ctxid_len = 0; control->contextId = NULL; } ctrl->data = control; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) { struct ldb_dirsync_control *control; const char *p; char *cookie = NULL; int crit, max_attrs, ret; uint32_t flags; cookie = talloc_zero_array(ctrl, char, strlen(control_strings) + 1); if (cookie == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]); ret = sscanf(p, "%d:%u:%d:%[^$]", &crit, &flags, &max_attrs, cookie); if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) { ldb_set_errstring(ldb, "invalid dirsync control syntax\n" " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n" " note: b = boolean, n = number, o = b64 binary blob"); talloc_free(ctrl); return NULL; } /* w2k3 seems to ignore the parameter, * but w2k sends a wrong cookie when this value is to small * this would cause looping forever, while getting * the same data and same cookie forever */ if (max_attrs == 0) max_attrs = 0x0FFFFFFF; ctrl->oid = LDB_CONTROL_DIRSYNC_OID; ctrl->critical = crit; control = talloc(ctrl, struct ldb_dirsync_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->flags = flags; control->max_attributes = max_attrs; if (*cookie) { int len = ldb_base64_decode(cookie); if (len < 0) { ldb_set_errstring(ldb, "invalid dirsync cookie\n"); talloc_free(ctrl); return NULL; } control->cookie_len = len; control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); if (control->cookie == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } } else { control->cookie = NULL; control->cookie_len = 0; } ctrl->data = control; TALLOC_FREE(cookie); return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) { struct ldb_dirsync_control *control; const char *p; char *cookie = NULL; int crit, max_attrs, ret; uint32_t flags; cookie = talloc_zero_array(ctrl, char, strlen(control_strings) + 1); if (cookie == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]); ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) { ldb_set_errstring(ldb, "invalid dirsync_ex control syntax\n" " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n" " note: b = boolean, n = number, o = b64 binary blob"); talloc_free(ctrl); return NULL; } /* w2k3 seems to ignore the parameter, * but w2k sends a wrong cookie when this value is to small * this would cause looping forever, while getting * the same data and same cookie forever */ if (max_attrs == 0) max_attrs = 0x0FFFFFFF; ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID; ctrl->critical = crit; control = talloc(ctrl, struct ldb_dirsync_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->flags = flags; control->max_attributes = max_attrs; if (*cookie) { int len = ldb_base64_decode(cookie); if (len < 0) { ldb_set_errstring(ldb, "invalid dirsync_ex cookie" " (probably too long)\n"); talloc_free(ctrl); return NULL; } control->cookie_len = len; control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); if (control->cookie == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } } else { control->cookie = NULL; control->cookie_len = 0; } ctrl->data = control; TALLOC_FREE(cookie); return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) { struct ldb_asq_control *control; const char *p; char attr[256]; int crit, ret; attr[0] = '\0'; p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]); ret = sscanf(p, "%d:%255[^$]", &crit, attr); if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { ldb_set_errstring(ldb, "invalid asq control syntax\n" " syntax: crit(b):attr(s)\n" " note: b = boolean, s = string"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_ASQ_OID; ctrl->critical = crit; control = talloc(ctrl, struct ldb_asq_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->request = 1; control->source_attribute = talloc_strdup(control, attr); control->src_attr_len = strlen(attr); ctrl->data = control; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) { struct ldb_extended_dn_control *control; const char *p; int crit, type, ret; p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]); ret = sscanf(p, "%d:%d", &crit, &type); if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid extended_dn control syntax\n" " syntax: crit(b)[:type(i)]\n" " note: b = boolean\n" " i = integer\n" " valid values are: 0 - hexadecimal representation\n" " 1 - normal string representation"); talloc_free(ctrl); return NULL; } control = NULL; } else { control = talloc(ctrl, struct ldb_extended_dn_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->type = type; } ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID; ctrl->critical = crit; ctrl->data = talloc_steal(ctrl, control); return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) { struct ldb_sd_flags_control *control; const char *p; int crit, ret; unsigned secinfo_flags; p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]); ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags > 0xF)) { ldb_set_errstring(ldb, "invalid sd_flags control syntax\n" " syntax: crit(b):secinfo_flags(n)\n" " note: b = boolean, n = number"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_SD_FLAGS_OID; ctrl->critical = crit; control = talloc(ctrl, struct ldb_sd_flags_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->secinfo_flags = secinfo_flags; ctrl->data = control; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) { struct ldb_search_options_control *control; const char *p; int crit, ret; unsigned search_options; p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]); ret = sscanf(p, "%d:%u", &crit, &search_options); if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options > 0xF)) { ldb_set_errstring(ldb, "invalid search_options control syntax\n" " syntax: crit(b):search_options(n)\n" " note: b = boolean, n = number"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; ctrl->critical = crit; control = talloc(ctrl, struct ldb_search_options_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->search_options = search_options; ctrl->data = control; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid bypassopreational control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid relax control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_RELAX_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid recalculate_sd control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid domain_scope control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) { struct ldb_paged_control *control; const char *p; char cookie[1024]; int crit, size, ret; cookie[0] = '\0'; p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]); ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &size, cookie); if ((ret < 2) || (ret > 3) || (crit < 0) || (crit > 1) || (size < 0)) { ldb_set_errstring(ldb, "invalid paged_results control syntax\n" " syntax: crit(b):size(n)[:cookie(base64)]\n" " note: b = boolean, n = number"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID; ctrl->critical = crit; control = talloc(ctrl, struct ldb_paged_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->size = size; if (cookie[0] != '\0') { int len = ldb_base64_decode(cookie); if (len < 0) { ldb_set_errstring(ldb, "invalid paged_results cookie" " (probably too long)\n"); talloc_free(ctrl); return NULL; } control->cookie_len = len; control->cookie = talloc_memdup(control, cookie, control->cookie_len); if (control->cookie == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } } else { control->cookie = NULL; control->cookie_len = 0; } ctrl->data = control; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) { struct ldb_server_sort_control **control; const char *p; char attr[256]; char rule[128]; int crit, rev, ret; attr[0] = '\0'; rule[0] = '\0'; p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]); ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { ldb_set_errstring(ldb, "invalid server_sort control syntax\n" " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n" " note: b = boolean, s = string"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_SERVER_SORT_OID; ctrl->critical = crit; control = talloc_array(ctrl, struct ldb_server_sort_control *, 2); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control[0] = talloc(control, struct ldb_server_sort_control); if (control[0] == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control[0]->attributeName = talloc_strdup(control, attr); if (control[0]->attributeName == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } if (rule[0]) { control[0]->orderingRule = talloc_strdup(control, rule); if (control[0]->orderingRule == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } } else { control[0]->orderingRule = NULL; } control[0]->reverse = rev; control[1] = NULL; ctrl->data = control; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid notification control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_NOTIFICATION_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid tree_delete control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_TREE_DELETE_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid show_deleted control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid show_deactivated_link control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid show_recycled control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid permissive_modify control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid reveal_internals control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (strncmp(control_strings, "local_oid:", 10) == 0) { const char *p; int crit = 0, ret = 0; char oid[256]; oid[0] = '\0'; p = &(control_strings[10]); ret = sscanf(p, "%255[^:]:%d", oid, &crit); if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid local_oid control syntax\n" " syntax: oid(s):crit(b)\n" " note: b = boolean, s = string"); talloc_free(ctrl); return NULL; } ctrl->oid = talloc_strdup(ctrl, oid); if (!ctrl->oid) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid rodc_join control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) { const char *p; int crit, ret; p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]); ret = sscanf(p, "%d", &crit); if ((ret != 1) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid provision control syntax\n" " syntax: crit(b)\n" " note: b = boolean"); talloc_free(ctrl); return NULL; } ctrl->oid = LDB_CONTROL_PROVISION_OID; ctrl->critical = crit; ctrl->data = NULL; return ctrl; } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_VERIFY_NAME_NAME) == 0) { const char *p; char gc[1024]; int crit, flags, ret; struct ldb_verify_name_control *control; gc[0] = '\0'; p = &(control_strings[sizeof(LDB_CONTROL_VERIFY_NAME_NAME)]); ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &flags, gc); if ((ret != 3) || (crit < 0) || (crit > 1)) { ret = sscanf(p, "%d:%d", &crit, &flags); if ((ret != 2) || (crit < 0) || (crit > 1)) { ldb_set_errstring(ldb, "invalid verify_name control syntax\n" " syntax: crit(b):flags(i)[:gc(s)]\n" " note: b = boolean" " note: i = integer" " note: s = string"); talloc_free(ctrl); return NULL; } } ctrl->oid = LDB_CONTROL_VERIFY_NAME_OID; ctrl->critical = crit; control = talloc(ctrl, struct ldb_verify_name_control); if (control == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->gc = talloc_strdup(control, gc); if (control->gc == NULL) { ldb_oom(ldb); talloc_free(ctrl); return NULL; } control->gc_len = strlen(gc); control->flags = flags; ctrl->data = control; return ctrl; } /* * When no matching control has been found. */ return NULL; } /* Parse controls from the format used on the command line and in ejs */ struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings) { unsigned int i; struct ldb_control **ctrl; if (control_strings == NULL || control_strings[0] == NULL) return NULL; for (i = 0; control_strings[i]; i++); ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); ldb_reset_err_string(ldb); for (i = 0; control_strings[i]; i++) { ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]); if (ctrl[i] == NULL) { if (ldb_errstring(ldb) == NULL) { /* no controls matched, throw an error */ ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]); } talloc_free(ctrl); return NULL; } } ctrl[i] = NULL; return ctrl; } ldb-2.0.8/common/ldb_debug.c0000660000000000000000000000743312406075657015604 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldb debug * * Description: functions for printing debug messages * * Author: Andrew Tridgell */ #include "ldb_private.h" /* this allows the user to choose their own debug function */ int ldb_set_debug(struct ldb_context *ldb, void (*debug)(void *context, enum ldb_debug_level level, const char *fmt, va_list ap), void *context) { ldb->debug_ops.debug = debug; ldb->debug_ops.context = context; return 0; } /* debug function for ldb_set_debug_stderr */ static void ldb_debug_stderr(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); static void ldb_debug_stderr(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) { if (level <= LDB_DEBUG_WARNING) { vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); } } static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) { vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); } /* convenience function to setup debug messages on stderr messages of level LDB_DEBUG_WARNING and higher are printed */ int ldb_set_debug_stderr(struct ldb_context *ldb) { return ldb_set_debug(ldb, ldb_debug_stderr, ldb); } /* log a message (va_list helper for ldb_tevent_debug) */ void ldb_vdebug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, va_list ap) { if (ldb->debug_ops.debug == NULL) { if (ldb->flags & LDB_FLG_ENABLE_TRACING) { ldb_set_debug(ldb, ldb_debug_stderr_all, ldb); } else { ldb_set_debug_stderr(ldb); } } ldb->debug_ops.debug(ldb->debug_ops.context, level, fmt, ap); } /* log a message */ void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); ldb_vdebug(ldb, level, fmt, ap); va_end(ap); } /* add to an accumulated log message */ void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) { va_list ap; va_start(ap, fmt); if (ldb->partial_debug == NULL) { ldb->partial_debug = talloc_vasprintf(ldb, fmt, ap); } else { ldb->partial_debug = talloc_vasprintf_append(ldb->partial_debug, fmt, ap); } va_end(ap); } /* send the accumulated log message, and free it */ void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level) { ldb_debug(ldb, level, "%s", ldb->partial_debug); talloc_free(ldb->partial_debug); ldb->partial_debug = NULL; } /* log a message, and set the ldb error string to the same message */ void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) { va_list ap; char *msg; va_start(ap, fmt); msg = talloc_vasprintf(ldb, fmt, ap); va_end(ap); if (msg != NULL) { ldb_set_errstring(ldb, msg); ldb_debug(ldb, level, "%s", msg); } talloc_free(msg); } ldb-2.0.8/common/ldb_dn.c0000660000000000000000000013352013573675413015116 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2005 ** 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 . */ /* * Name: ldb * * Component: ldb dn creation and manipulation utility functions * * Description: - explode a dn into it's own basic elements * and put them in a structure (only if necessary) * - manipulate ldb_dn structures * * Author: Simo Sorce */ #include "ldb_private.h" #include #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0) /** internal ldb exploded dn structures */ struct ldb_dn_component { char *name; struct ldb_val value; char *cf_name; struct ldb_val cf_value; }; struct ldb_dn_ext_component { const char *name; struct ldb_val value; }; struct ldb_dn { struct ldb_context *ldb; /* Special DNs are always linearized */ bool special; bool invalid; bool valid_case; char *linearized; char *ext_linearized; char *casefold; unsigned int comp_num; struct ldb_dn_component *components; unsigned int ext_comp_num; struct ldb_dn_ext_component *ext_components; }; /* it is helpful to be able to break on this in gdb */ static void ldb_dn_mark_invalid(struct ldb_dn *dn) { dn->invalid = true; } /* strdn may be NULL */ struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn) { struct ldb_dn *dn; if (ldb == NULL || strdn == NULL) { return NULL; } if (strdn->data && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) { /* The RDN must not contain a character with value 0x0 */ return NULL; } dn = talloc_zero(mem_ctx, struct ldb_dn); LDB_DN_NULL_FAILED(dn); dn->ldb = talloc_get_type(ldb, struct ldb_context); if (dn->ldb == NULL) { /* the caller probably got the arguments to ldb_dn_new() mixed up */ talloc_free(dn); return NULL; } if (strdn->data && strdn->length) { const char *data = (const char *)strdn->data; size_t length = strdn->length; if (data[0] == '@') { dn->special = true; } dn->ext_linearized = talloc_strndup(dn, data, length); LDB_DN_NULL_FAILED(dn->ext_linearized); if (data[0] == '<') { const char *p_save, *p = dn->ext_linearized; do { p_save = p; p = strstr(p, ">;"); if (p) { p = p + 2; } } while (p); if (p_save == dn->ext_linearized) { dn->linearized = talloc_strdup(dn, ""); } else { dn->linearized = talloc_strdup(dn, p_save); } LDB_DN_NULL_FAILED(dn->linearized); } else { dn->linearized = dn->ext_linearized; dn->ext_linearized = NULL; } } else { dn->linearized = talloc_strdup(dn, ""); LDB_DN_NULL_FAILED(dn->linearized); } return dn; failed: talloc_free(dn); return NULL; } /* strdn may be NULL */ struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *strdn) { struct ldb_val blob; blob.data = discard_const_p(uint8_t, strdn); blob.length = strdn ? strlen(strdn) : 0; return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob); } struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) { char *strdn; va_list ap; if (! ldb) return NULL; va_start(ap, new_fmt); strdn = talloc_vasprintf(mem_ctx, new_fmt, ap); va_end(ap); if (strdn) { struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn); talloc_free(strdn); return dn; } return NULL; } /* see RFC2253 section 2.4 */ static int ldb_dn_escape_internal(char *dst, const char *src, int len) { char c; char *d; int i; d = dst; for (i = 0; i < len; i++){ c = src[i]; switch (c) { case ' ': if (i == 0 || i == len - 1) { /* if at the beginning or end * of the string then escape */ *d++ = '\\'; *d++ = c; } else { /* otherwise don't escape */ *d++ = c; } break; case '#': /* despite the RFC, windows escapes a # anywhere in the string */ case ',': case '+': case '"': case '\\': case '<': case '>': case '?': /* these must be escaped using \c form */ *d++ = '\\'; *d++ = c; break; case ';': case '\r': case '\n': case '=': case '\0': { /* any others get \XX form */ unsigned char v; const char *hexbytes = "0123456789ABCDEF"; v = (const unsigned char)c; *d++ = '\\'; *d++ = hexbytes[v>>4]; *d++ = hexbytes[v&0xF]; break; } default: *d++ = c; } } /* return the length of the resulting string */ return (d - dst); } char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) { char *dst; size_t len; if (!value.length) return NULL; /* allocate destination string, it will be at most 3 times the source */ dst = talloc_array(mem_ctx, char, value.length * 3 + 1); if ( ! dst) { talloc_free(dst); return NULL; } len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length); dst = talloc_realloc(mem_ctx, dst, char, len + 1); if ( ! dst) { talloc_free(dst); return NULL; } dst[len] = '\0'; return dst; } /* explode a DN string into a ldb_dn structure based on RFC4514 except that we don't support multiple valued RDNs TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints DN must be compliant with RFC2253 */ static bool ldb_dn_explode(struct ldb_dn *dn) { char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t; bool trim = true; bool in_extended = true; bool in_ex_name = false; bool in_ex_value = false; bool in_attr = false; bool in_value = false; bool in_quote = false; bool is_oid = false; bool escape = false; unsigned int x; size_t l = 0; int ret; char *parse_dn; bool is_index; if (dn == NULL || dn->invalid == true) { return false; } if (dn->components != NULL) { return true; } if (dn->ext_linearized != NULL) { parse_dn = dn->ext_linearized; } else { parse_dn = dn->linearized; } if (parse_dn == NULL) { return false; } is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0); /* Empty DNs */ if (parse_dn[0] == '\0') { return true; } /* Special DNs case */ if (dn->special == true) { return true; } LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; dn->comp_num = 0; /* in the common case we have 3 or more components */ /* make sure all components are zeroed, other functions depend on it */ dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3); if (dn->components == NULL) { return false; } /* Components data space is allocated here once */ data = talloc_array(dn->components, char, strlen(parse_dn) + 1); if (data == NULL) { goto failed; } p = parse_dn; t = NULL; d = dt = data; while (*p) { if (in_extended == true) { if (!in_ex_name && !in_ex_value) { if (p[0] == '<') { p++; ex_name = d; in_ex_name = true; continue; } else { in_extended = false; in_attr = true; dt = d; continue; } } if (in_ex_name && *p == '=') { *d++ = '\0'; p++; ex_value = d; in_ex_name = false; in_ex_value = true; continue; } if (in_ex_value && *p == '>') { struct ldb_dn_ext_component *ext_comp = NULL; const struct ldb_dn_extended_syntax *ext_syntax; struct ldb_val ex_val = { .data = (uint8_t *)ex_value, .length = d - ex_value }; *d++ = '\0'; p++; in_ex_value = false; /* Process name and ex_value */ ext_comp = talloc_realloc( dn, dn->ext_components, struct ldb_dn_ext_component, dn->ext_comp_num + 1); if (ext_comp == NULL) { /* ouch ! */ goto failed; } dn->ext_components = ext_comp; ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); if (ext_syntax == NULL) { /* We don't know about this type of extended DN */ goto failed; } dn->ext_components[dn->ext_comp_num].name = ext_syntax->name; ret = ext_syntax->read_fn(dn->ldb, dn->ext_components, &ex_val, &dn->ext_components[dn->ext_comp_num].value); if (ret != LDB_SUCCESS) { ldb_dn_mark_invalid(dn); goto failed; } dn->ext_comp_num++; if (*p == '\0') { /* We have reached the end (extended component only)! */ talloc_free(data); return true; } else if (*p == ';') { p++; continue; } else { ldb_dn_mark_invalid(dn); goto failed; } } *d++ = *p++; continue; } if (in_attr == true) { if (trim == true) { if (*p == ' ') { p++; continue; } /* first char */ trim = false; if (!isascii(*p)) { /* attr names must be ascii only */ ldb_dn_mark_invalid(dn); goto failed; } if (isdigit(*p)) { is_oid = true; } else if ( ! isalpha(*p)) { /* not a digit nor an alpha, * invalid attribute name */ ldb_dn_mark_invalid(dn); goto failed; } /* Copy this character across from parse_dn, * now we have trimmed out spaces */ *d++ = *p++; continue; } if (*p == ' ') { p++; /* valid only if we are at the end */ trim = true; continue; } if (*p == '=') { /* attribute terminated */ in_attr = false; in_value = true; trim = true; l = 0; /* Terminate this string in d * (which is a copy of parse_dn * with spaces trimmed) */ *d++ = '\0'; dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt); if (dn->components[dn->comp_num].name == NULL) { /* ouch */ goto failed; } dt = d; p++; continue; } if (!isascii(*p)) { /* attr names must be ascii only */ ldb_dn_mark_invalid(dn); goto failed; } if (is_oid == true && ( ! (isdigit(*p) || (*p == '.')))) { /* not a digit nor a dot, * invalid attribute oid */ ldb_dn_mark_invalid(dn); goto failed; } else if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) { /* not ALPHA, DIGIT or HYPHEN */ ldb_dn_mark_invalid(dn); goto failed; } *d++ = *p++; continue; } if (in_value == true) { if (in_quote == true) { if (*p == '\"') { if (p[-1] != '\\') { p++; in_quote = false; continue; } } *d++ = *p++; l++; continue; } if (trim == true) { if (*p == ' ') { p++; continue; } /* first char */ trim = false; if (*p == '\"') { in_quote = true; p++; continue; } } switch (*p) { /* TODO: support ber encoded values case '#': */ case ',': if (escape == true) { *d++ = *p++; l++; escape = false; continue; } /* ok found value terminator */ if (t != NULL) { /* trim back */ d -= (p - t); l -= (p - t); } in_attr = true; in_value = false; trim = true; p++; *d++ = '\0'; /* * This talloc_memdup() is OK with the * +1 because *d has been set to '\0' * just above */ dn->components[dn->comp_num].value.data = \ (uint8_t *)talloc_memdup(dn->components, dt, l + 1); dn->components[dn->comp_num].value.length = l; if (dn->components[dn->comp_num].value.data == NULL) { /* ouch ! */ goto failed; } talloc_set_name_const(dn->components[dn->comp_num].value.data, (const char *)dn->components[dn->comp_num].value.data); dt = d; dn->comp_num++; if (dn->comp_num > 2) { dn->components = talloc_realloc(dn, dn->components, struct ldb_dn_component, dn->comp_num + 1); if (dn->components == NULL) { /* ouch ! */ goto failed; } /* make sure all components are zeroed, other functions depend on this */ memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component)); } continue; case '+': case '=': /* to main compatibility with earlier versions of ldb indexing, we have to accept the base64 encoded binary index values, which contain a '+' or '=' which should normally be escaped */ if (is_index == true) { if (t != NULL) { t = NULL; } *d++ = *p++; l++; break; } FALL_THROUGH; case '\"': case '<': case '>': case ';': /* a string with not escaped specials is invalid (tested) */ if (escape == false) { ldb_dn_mark_invalid(dn); goto failed; } escape = false; *d++ = *p++; l++; if (t != NULL) { t = NULL; } break; case '\\': if (escape == false) { escape = true; p++; continue; } escape = false; *d++ = *p++; l++; if (t != NULL) { t = NULL; } break; default: if (escape == true) { if (isxdigit(p[0]) && isxdigit(p[1])) { if (sscanf(p, "%02x", &x) != 1) { /* invalid escaping sequence */ ldb_dn_mark_invalid(dn); goto failed; } p += 2; *d++ = (unsigned char)x; } else { *d++ = *p++; } escape = false; l++; if (t != NULL) { t = NULL; } break; } if (*p == ' ') { if (t == NULL) { t = p; } } else { if (t != NULL) { t = NULL; } } *d++ = *p++; l++; break; } } } if (in_attr == true || in_quote == true) { /* invalid dn */ ldb_dn_mark_invalid(dn); goto failed; } if (in_value == true) { /* save last element */ if (t != NULL) { /* trim back */ d -= (p - t); l -= (p - t); } *d++ = '\0'; /* * This talloc_memdup() is OK with the * +1 because *d has been set to '\0' * just above. */ dn->components[dn->comp_num].value.length = l; dn->components[dn->comp_num].value.data = (uint8_t *)talloc_memdup(dn->components, dt, l + 1); if (dn->components[dn->comp_num].value.data == NULL) { /* ouch */ goto failed; } talloc_set_name_const(dn->components[dn->comp_num].value.data, (const char *)dn->components[dn->comp_num].value.data); dn->comp_num++; } talloc_free(data); return true; failed: LDB_FREE(dn->components); /* "data" is implicitly free'd */ dn->comp_num = 0; LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; return false; } bool ldb_dn_validate(struct ldb_dn *dn) { return ldb_dn_explode(dn); } const char *ldb_dn_get_linearized(struct ldb_dn *dn) { unsigned int i; size_t len; char *d, *n; if ( ! dn || ( dn->invalid)) return NULL; if (dn->linearized) return dn->linearized; if ( ! dn->components) { ldb_dn_mark_invalid(dn); return NULL; } if (dn->comp_num == 0) { dn->linearized = talloc_strdup(dn, ""); if ( ! dn->linearized) return NULL; return dn->linearized; } /* calculate maximum possible length of DN */ for (len = 0, i = 0; i < dn->comp_num; i++) { /* name len */ len += strlen(dn->components[i].name); /* max escaped data len */ len += (dn->components[i].value.length * 3); len += 2; /* '=' and ',' */ } dn->linearized = talloc_array(dn, char, len); if ( ! dn->linearized) return NULL; d = dn->linearized; for (i = 0; i < dn->comp_num; i++) { /* copy the name */ n = dn->components[i].name; while (*n) *d++ = *n++; *d++ = '='; /* and the value */ d += ldb_dn_escape_internal( d, (char *)dn->components[i].value.data, dn->components[i].value.length); *d++ = ','; } *(--d) = '\0'; /* don't waste more memory than necessary */ dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1)); return dn->linearized; } static int ldb_dn_extended_component_compare(const void *p1, const void *p2) { const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1; const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2; return strcmp(ec1->name, ec2->name); } char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode) { const char *linearized = ldb_dn_get_linearized(dn); char *p = NULL; unsigned int i; if (!linearized) { return NULL; } if (!ldb_dn_has_extended(dn)) { return talloc_strdup(mem_ctx, linearized); } if (!ldb_dn_validate(dn)) { return NULL; } /* sort the extended components by name. The idea is to make * the resulting DNs consistent, plus to ensure that we put * 'DELETED' first, so it can be very quickly recognised */ TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num, ldb_dn_extended_component_compare); for (i = 0; i < dn->ext_comp_num; i++) { const struct ldb_dn_extended_syntax *ext_syntax; const char *name = dn->ext_components[i].name; struct ldb_val ec_val = dn->ext_components[i].value; struct ldb_val val; int ret; ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); if (!ext_syntax) { return NULL; } if (mode == 1) { ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx, &ec_val, &val); } else if (mode == 0) { ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx, &ec_val, &val); } else { ret = -1; } if (ret != LDB_SUCCESS) { return NULL; } if (i == 0) { p = talloc_asprintf(mem_ctx, "<%s=%.*s>", name, (int)val.length, val.data); } else { p = talloc_asprintf_append_buffer(p, ";<%s=%.*s>", name, (int)val.length, val.data); } talloc_free(val.data); if (!p) { return NULL; } } if (dn->ext_comp_num && *linearized) { p = talloc_asprintf_append_buffer(p, ";%s", linearized); } if (!p) { return NULL; } return p; } /* filter out all but an acceptable list of extended DN components */ void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list) { unsigned int i; for (i=0; iext_comp_num; i++) { if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) { memmove(&dn->ext_components[i], &dn->ext_components[i+1], (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0])); dn->ext_comp_num--; i--; } } LDB_FREE(dn->ext_linearized); } char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); } /* casefold a dn. We need to casefold the attribute names, and canonicalize attribute values of case insensitive attributes. */ static bool ldb_dn_casefold_internal(struct ldb_dn *dn) { unsigned int i; int ret; if ( ! dn || dn->invalid) return false; if (dn->valid_case) return true; if (( ! dn->components) && ( ! ldb_dn_explode(dn))) { return false; } for (i = 0; i < dn->comp_num; i++) { const struct ldb_schema_attribute *a; dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name); if (!dn->components[i].cf_name) { goto failed; } a = ldb_schema_attribute_by_name(dn->ldb, dn->components[i].cf_name); ret = a->syntax->canonicalise_fn(dn->ldb, dn->components, &(dn->components[i].value), &(dn->components[i].cf_value)); if (ret != 0) { goto failed; } } dn->valid_case = true; return true; failed: for (i = 0; i < dn->comp_num; i++) { LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } return false; } const char *ldb_dn_get_casefold(struct ldb_dn *dn) { unsigned int i; size_t len; char *d, *n; if (dn->casefold) return dn->casefold; if (dn->special) { dn->casefold = talloc_strdup(dn, dn->linearized); if (!dn->casefold) return NULL; dn->valid_case = true; return dn->casefold; } if ( ! ldb_dn_casefold_internal(dn)) { return NULL; } if (dn->comp_num == 0) { dn->casefold = talloc_strdup(dn, ""); return dn->casefold; } /* calculate maximum possible length of DN */ for (len = 0, i = 0; i < dn->comp_num; i++) { /* name len */ len += strlen(dn->components[i].cf_name); /* max escaped data len */ len += (dn->components[i].cf_value.length * 3); len += 2; /* '=' and ',' */ } dn->casefold = talloc_array(dn, char, len); if ( ! dn->casefold) return NULL; d = dn->casefold; for (i = 0; i < dn->comp_num; i++) { /* copy the name */ n = dn->components[i].cf_name; while (*n) *d++ = *n++; *d++ = '='; /* and the value */ d += ldb_dn_escape_internal( d, (char *)dn->components[i].cf_value.data, dn->components[i].cf_value.length); *d++ = ','; } *(--d) = '\0'; /* don't waste more memory than necessary */ dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1); return dn->casefold; } char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn)); } /* Determine if dn is below base, in the ldap tree. Used for * evaluating a subtree search. * 0 if they match, otherwise non-zero */ int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn) { int ret; unsigned int n_base, n_dn; if ( ! base || base->invalid) return 1; if ( ! dn || dn->invalid) return -1; if (( ! base->valid_case) || ( ! dn->valid_case)) { if (base->linearized && dn->linearized && dn->special == base->special) { /* try with a normal compare first, if we are lucky * we will avoid exploding and casfolding */ int dif; dif = strlen(dn->linearized) - strlen(base->linearized); if (dif < 0) { return dif; } if (strcmp(base->linearized, &dn->linearized[dif]) == 0) { return 0; } } if ( ! ldb_dn_casefold_internal(base)) { return 1; } if ( ! ldb_dn_casefold_internal(dn)) { return -1; } } /* if base has more components, * they don't have the same base */ if (base->comp_num > dn->comp_num) { return (dn->comp_num - base->comp_num); } if ((dn->comp_num == 0) || (base->comp_num == 0)) { if (dn->special && base->special) { return strcmp(base->linearized, dn->linearized); } else if (dn->special) { return -1; } else if (base->special) { return 1; } else { return 0; } } n_base = base->comp_num - 1; n_dn = dn->comp_num - 1; while (n_base != (unsigned int) -1) { char *b_name = base->components[n_base].cf_name; char *dn_name = dn->components[n_dn].cf_name; char *b_vdata = (char *)base->components[n_base].cf_value.data; char *dn_vdata = (char *)dn->components[n_dn].cf_value.data; size_t b_vlen = base->components[n_base].cf_value.length; size_t dn_vlen = dn->components[n_dn].cf_value.length; /* compare attr names */ ret = strcmp(b_name, dn_name); if (ret != 0) return ret; /* compare attr.cf_value. */ if (b_vlen != dn_vlen) { return b_vlen - dn_vlen; } ret = strncmp(b_vdata, dn_vdata, b_vlen); if (ret != 0) return ret; n_base--; n_dn--; } return 0; } /* compare DNs using casefolding compare functions. If they match, then return 0 */ int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1) { unsigned int i; int ret; if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) { return -1; } if (( ! dn0->valid_case) || ( ! dn1->valid_case)) { if (dn0->linearized && dn1->linearized) { /* try with a normal compare first, if we are lucky * we will avoid exploding and casfolding */ if (strcmp(dn0->linearized, dn1->linearized) == 0) { return 0; } } if ( ! ldb_dn_casefold_internal(dn0)) { return 1; } if ( ! ldb_dn_casefold_internal(dn1)) { return -1; } } if (dn0->comp_num != dn1->comp_num) { return (dn1->comp_num - dn0->comp_num); } if (dn0->comp_num == 0) { if (dn0->special && dn1->special) { return strcmp(dn0->linearized, dn1->linearized); } else if (dn0->special) { return 1; } else if (dn1->special) { return -1; } else { return 0; } } for (i = 0; i < dn0->comp_num; i++) { char *dn0_name = dn0->components[i].cf_name; char *dn1_name = dn1->components[i].cf_name; char *dn0_vdata = (char *)dn0->components[i].cf_value.data; char *dn1_vdata = (char *)dn1->components[i].cf_value.data; size_t dn0_vlen = dn0->components[i].cf_value.length; size_t dn1_vlen = dn1->components[i].cf_value.length; /* compare attr names */ ret = strcmp(dn0_name, dn1_name); if (ret != 0) { return ret; } /* compare attr.cf_value. */ if (dn0_vlen != dn1_vlen) { return dn0_vlen - dn1_vlen; } ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen); if (ret != 0) { return ret; } } return 0; } static struct ldb_dn_component ldb_dn_copy_component( TALLOC_CTX *mem_ctx, struct ldb_dn_component *src) { struct ldb_dn_component dst; memset(&dst, 0, sizeof(dst)); if (src == NULL) { return dst; } dst.value = ldb_val_dup(mem_ctx, &(src->value)); if (dst.value.data == NULL) { return dst; } dst.name = talloc_strdup(mem_ctx, src->name); if (dst.name == NULL) { LDB_FREE(dst.value.data); return dst; } if (src->cf_value.data) { dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value)); if (dst.cf_value.data == NULL) { LDB_FREE(dst.value.data); LDB_FREE(dst.name); return dst; } dst.cf_name = talloc_strdup(mem_ctx, src->cf_name); if (dst.cf_name == NULL) { LDB_FREE(dst.cf_name); LDB_FREE(dst.value.data); LDB_FREE(dst.name); return dst; } } else { dst.cf_value.data = NULL; dst.cf_name = NULL; } return dst; } static struct ldb_dn_ext_component ldb_dn_ext_copy_component( TALLOC_CTX *mem_ctx, struct ldb_dn_ext_component *src) { struct ldb_dn_ext_component dst; memset(&dst, 0, sizeof(dst)); if (src == NULL) { return dst; } dst.value = ldb_val_dup(mem_ctx, &(src->value)); if (dst.value.data == NULL) { return dst; } dst.name = talloc_strdup(mem_ctx, src->name); if (dst.name == NULL) { LDB_FREE(dst.value.data); return dst; } return dst; } struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { struct ldb_dn *new_dn; if (!dn || dn->invalid) { return NULL; } new_dn = talloc_zero(mem_ctx, struct ldb_dn); if ( !new_dn) { return NULL; } *new_dn = *dn; if (dn->components) { unsigned int i; new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num); if ( ! new_dn->components) { talloc_free(new_dn); return NULL; } for (i = 0; i < dn->comp_num; i++) { new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]); if ( ! new_dn->components[i].value.data) { talloc_free(new_dn); return NULL; } } } if (dn->ext_components) { unsigned int i; new_dn->ext_components = talloc_zero_array(new_dn, struct ldb_dn_ext_component, dn->ext_comp_num); if ( ! new_dn->ext_components) { talloc_free(new_dn); return NULL; } for (i = 0; i < dn->ext_comp_num; i++) { new_dn->ext_components[i] = ldb_dn_ext_copy_component( new_dn->ext_components, &dn->ext_components[i]); if ( ! new_dn->ext_components[i].value.data) { talloc_free(new_dn); return NULL; } } } if (dn->casefold) { new_dn->casefold = talloc_strdup(new_dn, dn->casefold); if ( ! new_dn->casefold) { talloc_free(new_dn); return NULL; } } if (dn->linearized) { new_dn->linearized = talloc_strdup(new_dn, dn->linearized); if ( ! new_dn->linearized) { talloc_free(new_dn); return NULL; } } if (dn->ext_linearized) { new_dn->ext_linearized = talloc_strdup(new_dn, dn->ext_linearized); if ( ! new_dn->ext_linearized) { talloc_free(new_dn); return NULL; } } return new_dn; } /* modify the given dn by adding a base. * * return true if successful and false if not * if false is returned the dn may be marked invalid */ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base) { const char *s; char *t; if ( !base || base->invalid || !dn || dn->invalid) { return false; } if (dn == base) { return false; /* or we will visit infinity */ } if (dn->components) { unsigned int i; if ( ! ldb_dn_validate(base)) { return false; } s = NULL; if (dn->valid_case) { if ( ! (s = ldb_dn_get_casefold(base))) { return false; } } dn->components = talloc_realloc(dn, dn->components, struct ldb_dn_component, dn->comp_num + base->comp_num); if ( ! dn->components) { ldb_dn_mark_invalid(dn); return false; } for (i = 0; i < base->comp_num; dn->comp_num++, i++) { dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]); if (dn->components[dn->comp_num].value.data == NULL) { ldb_dn_mark_invalid(dn); return false; } } if (dn->casefold && s) { if (*dn->casefold) { t = talloc_asprintf(dn, "%s,%s", dn->casefold, s); } else { t = talloc_strdup(dn, s); } LDB_FREE(dn->casefold); dn->casefold = t; } } if (dn->linearized) { s = ldb_dn_get_linearized(base); if ( ! s) { return false; } if (*dn->linearized) { t = talloc_asprintf(dn, "%s,%s", dn->linearized, s); } else { t = talloc_strdup(dn, s); } if ( ! t) { ldb_dn_mark_invalid(dn); return false; } LDB_FREE(dn->linearized); dn->linearized = t; } /* Wipe the ext_linearized DN, * the GUID and SID are almost certainly no longer valid */ LDB_FREE(dn->ext_linearized); LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; return true; } /* modify the given dn by adding a base. * * return true if successful and false if not * if false is returned the dn may be marked invalid */ bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) { struct ldb_dn *base; char *base_str; va_list ap; bool ret; if ( !dn || dn->invalid) { return false; } va_start(ap, base_fmt); base_str = talloc_vasprintf(dn, base_fmt, ap); va_end(ap); if (base_str == NULL) { return false; } base = ldb_dn_new(base_str, dn->ldb, base_str); ret = ldb_dn_add_base(dn, base); talloc_free(base_str); return ret; } /* modify the given dn by adding children elements. * * return true if successful and false if not * if false is returned the dn may be marked invalid */ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child) { const char *s; char *t; if ( !child || child->invalid || !dn || dn->invalid) { return false; } if (dn->components) { unsigned int n; unsigned int i, j; if (dn->comp_num == 0) { return false; } if ( ! ldb_dn_validate(child)) { return false; } s = NULL; if (dn->valid_case) { if ( ! (s = ldb_dn_get_casefold(child))) { return false; } } n = dn->comp_num + child->comp_num; dn->components = talloc_realloc(dn, dn->components, struct ldb_dn_component, n); if ( ! dn->components) { ldb_dn_mark_invalid(dn); return false; } for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1; i--, j--) { dn->components[j] = dn->components[i]; } for (i = 0; i < child->comp_num; i++) { dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]); if (dn->components[i].value.data == NULL) { ldb_dn_mark_invalid(dn); return false; } } dn->comp_num = n; if (dn->casefold && s) { t = talloc_asprintf(dn, "%s,%s", s, dn->casefold); LDB_FREE(dn->casefold); dn->casefold = t; } } if (dn->linearized) { if (dn->linearized[0] == '\0') { return false; } s = ldb_dn_get_linearized(child); if ( ! s) { return false; } t = talloc_asprintf(dn, "%s,%s", s, dn->linearized); if ( ! t) { ldb_dn_mark_invalid(dn); return false; } LDB_FREE(dn->linearized); dn->linearized = t; } /* Wipe the ext_linearized DN, * the GUID and SID are almost certainly no longer valid */ LDB_FREE(dn->ext_linearized); LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; return true; } /* modify the given dn by adding children elements. * * return true if successful and false if not * if false is returned the dn may be marked invalid */ bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) { struct ldb_dn *child; char *child_str; va_list ap; bool ret; if ( !dn || dn->invalid) { return false; } va_start(ap, child_fmt); child_str = talloc_vasprintf(dn, child_fmt, ap); va_end(ap); if (child_str == NULL) { return false; } child = ldb_dn_new(child_str, dn->ldb, child_str); ret = ldb_dn_add_child(dn, child); talloc_free(child_str); return ret; } /* modify the given dn by adding a single child element. * * return true if successful and false if not * if false is returned the dn may be marked invalid */ bool ldb_dn_add_child_val(struct ldb_dn *dn, const char *rdn, struct ldb_val value) { bool ret; int ldb_ret; struct ldb_dn *child = NULL; if ( !dn || dn->invalid) { return false; } child = ldb_dn_new(dn, dn->ldb, "X=Y"); ret = ldb_dn_add_child(dn, child); if (ret == false) { return false; } ldb_ret = ldb_dn_set_component(dn, 0, rdn, value); if (ldb_ret != LDB_SUCCESS) { return false; } return true; } bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num) { unsigned int i; if ( ! ldb_dn_validate(dn)) { return false; } if (dn->comp_num < num) { return false; } /* free components */ for (i = dn->comp_num - num; i < dn->comp_num; i++) { LDB_FREE(dn->components[i].name); LDB_FREE(dn->components[i].value.data); LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } dn->comp_num -= num; if (dn->valid_case) { for (i = 0; i < dn->comp_num; i++) { LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } dn->valid_case = false; } LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); /* Wipe the ext_linearized DN, * the GUID and SID are almost certainly no longer valid */ LDB_FREE(dn->ext_linearized); LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; return true; } bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num) { unsigned int i, j; if ( ! ldb_dn_validate(dn)) { return false; } if (dn->comp_num < num) { return false; } for (i = 0, j = num; j < dn->comp_num; i++, j++) { if (i < num) { LDB_FREE(dn->components[i].name); LDB_FREE(dn->components[i].value.data); LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } dn->components[i] = dn->components[j]; } dn->comp_num -= num; if (dn->valid_case) { for (i = 0; i < dn->comp_num; i++) { LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } dn->valid_case = false; } LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); /* Wipe the ext_linearized DN, * the GUID and SID are almost certainly no longer valid */ LDB_FREE(dn->ext_linearized); LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; return true; } /* replace the components of a DN with those from another DN, without * touching the extended components * * return true if successful and false if not * if false is returned the dn may be marked invalid */ bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn) { unsigned int i; if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) { return false; } /* free components */ for (i = 0; i < dn->comp_num; i++) { LDB_FREE(dn->components[i].name); LDB_FREE(dn->components[i].value.data); LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } dn->components = talloc_realloc(dn, dn->components, struct ldb_dn_component, new_dn->comp_num); if (dn->components == NULL) { ldb_dn_mark_invalid(dn); return false; } dn->comp_num = new_dn->comp_num; dn->valid_case = new_dn->valid_case; for (i = 0; i < dn->comp_num; i++) { dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]); if (dn->components[i].name == NULL) { ldb_dn_mark_invalid(dn); return false; } } if (new_dn->linearized == NULL) { dn->linearized = NULL; } else { dn->linearized = talloc_strdup(dn, new_dn->linearized); if (dn->linearized == NULL) { ldb_dn_mark_invalid(dn); return false; } } return true; } struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { struct ldb_dn *new_dn; new_dn = ldb_dn_copy(mem_ctx, dn); if ( !new_dn ) { return NULL; } if ( ! ldb_dn_remove_child_components(new_dn, 1)) { talloc_free(new_dn); return NULL; } return new_dn; } /* Create a 'canonical name' string from a DN: ie dc=samba,dc=org -> samba.org/ uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator There are two formats, the EX format has the last '/' replaced with a newline (\n). */ static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) { unsigned int i; TALLOC_CTX *tmpctx; char *cracked = NULL; const char *format = (ex_format ? "\n" : "/" ); if ( ! ldb_dn_validate(dn)) { return NULL; } tmpctx = talloc_new(mem_ctx); /* Walk backwards down the DN, grabbing 'dc' components at first */ for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) { if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) { break; } if (cracked) { cracked = talloc_asprintf(tmpctx, "%s.%s", ldb_dn_escape_value(tmpctx, dn->components[i].value), cracked); } else { cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value); } if (!cracked) { goto done; } } /* Only domain components? Finish here */ if (i == (unsigned int) -1) { cracked = talloc_strdup_append_buffer(cracked, format); talloc_steal(mem_ctx, cracked); goto done; } /* Now walk backwards appending remaining components */ for (; i > 0; i--) { cracked = talloc_asprintf_append_buffer(cracked, "/%s", ldb_dn_escape_value(tmpctx, dn->components[i].value)); if (!cracked) { goto done; } } /* Last one, possibly a newline for the 'ex' format */ cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format, ldb_dn_escape_value(tmpctx, dn->components[i].value)); talloc_steal(mem_ctx, cracked); done: talloc_free(tmpctx); return cracked; } /* Wrapper functions for the above, for the two different string formats */ char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { return ldb_dn_canonical(mem_ctx, dn, 0); } char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { return ldb_dn_canonical(mem_ctx, dn, 1); } int ldb_dn_get_comp_num(struct ldb_dn *dn) { if ( ! ldb_dn_validate(dn)) { return -1; } return dn->comp_num; } int ldb_dn_get_extended_comp_num(struct ldb_dn *dn) { if ( ! ldb_dn_validate(dn)) { return -1; } return dn->ext_comp_num; } const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num) { if ( ! ldb_dn_validate(dn)) { return NULL; } if (num >= dn->comp_num) return NULL; return dn->components[num].name; } const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num) { if ( ! ldb_dn_validate(dn)) { return NULL; } if (num >= dn->comp_num) return NULL; return &dn->components[num].value; } const char *ldb_dn_get_rdn_name(struct ldb_dn *dn) { if ( ! ldb_dn_validate(dn)) { return NULL; } if (dn->comp_num == 0) return NULL; return dn->components[0].name; } const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn) { if ( ! ldb_dn_validate(dn)) { return NULL; } if (dn->comp_num == 0) return NULL; return &dn->components[0].value; } int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val) { char *n; struct ldb_val v; if ( ! ldb_dn_validate(dn)) { return LDB_ERR_OTHER; } if (num < 0) { return LDB_ERR_OTHER; } if ((unsigned)num >= dn->comp_num) { return LDB_ERR_OTHER; } if (val.length > val.length + 1) { return LDB_ERR_OTHER; } n = talloc_strdup(dn, name); if ( ! n) { return LDB_ERR_OTHER; } v.length = val.length; /* * This is like talloc_memdup(dn, v.data, v.length + 1), but * avoids the over-read */ v.data = (uint8_t *)talloc_size(dn, v.length+1); if ( ! v.data) { talloc_free(n); return LDB_ERR_OTHER; } memcpy(v.data, val.data, val.length); /* * Enforce NUL termination outside the stated length, as is * traditional in LDB */ v.data[v.length] = '\0'; talloc_free(dn->components[num].name); talloc_free(dn->components[num].value.data); dn->components[num].name = n; dn->components[num].value = v; if (dn->valid_case) { unsigned int i; for (i = 0; i < dn->comp_num; i++) { LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } dn->valid_case = false; } LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); /* Wipe the ext_linearized DN, * the GUID and SID are almost certainly no longer valid */ LDB_FREE(dn->ext_linearized); LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; return LDB_SUCCESS; } const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name) { unsigned int i; if ( ! ldb_dn_validate(dn)) { return NULL; } for (i=0; i < dn->ext_comp_num; i++) { if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { return &dn->ext_components[i].value; } } return NULL; } int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val) { struct ldb_dn_ext_component *p; unsigned int i; struct ldb_val v2; const struct ldb_dn_extended_syntax *ext_syntax; if ( ! ldb_dn_validate(dn)) { return LDB_ERR_OTHER; } ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); if (ext_syntax == NULL) { /* We don't know how to handle this type of thing */ return LDB_ERR_INVALID_DN_SYNTAX; } for (i=0; i < dn->ext_comp_num; i++) { if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { if (val) { dn->ext_components[i].value = ldb_val_dup(dn->ext_components, val); dn->ext_components[i].name = ext_syntax->name; if (!dn->ext_components[i].value.data) { ldb_dn_mark_invalid(dn); return LDB_ERR_OPERATIONS_ERROR; } } else { if (i != (dn->ext_comp_num - 1)) { memmove(&dn->ext_components[i], &dn->ext_components[i+1], ((dn->ext_comp_num-1) - i) * sizeof(*dn->ext_components)); } dn->ext_comp_num--; dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, dn->ext_comp_num); if (!dn->ext_components) { ldb_dn_mark_invalid(dn); return LDB_ERR_OPERATIONS_ERROR; } } LDB_FREE(dn->ext_linearized); return LDB_SUCCESS; } } if (val == NULL) { /* removing a value that doesn't exist is not an error */ return LDB_SUCCESS; } v2 = *val; p = dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, dn->ext_comp_num + 1); if (!dn->ext_components) { ldb_dn_mark_invalid(dn); return LDB_ERR_OPERATIONS_ERROR; } p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2); p[dn->ext_comp_num].name = talloc_strdup(p, name); if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) { ldb_dn_mark_invalid(dn); return LDB_ERR_OPERATIONS_ERROR; } dn->ext_components = p; dn->ext_comp_num++; LDB_FREE(dn->ext_linearized); return LDB_SUCCESS; } void ldb_dn_remove_extended_components(struct ldb_dn *dn) { LDB_FREE(dn->ext_linearized); LDB_FREE(dn->ext_components); dn->ext_comp_num = 0; } bool ldb_dn_is_valid(struct ldb_dn *dn) { if ( ! dn) return false; return ! dn->invalid; } bool ldb_dn_is_special(struct ldb_dn *dn) { if ( ! dn || dn->invalid) return false; return dn->special; } bool ldb_dn_has_extended(struct ldb_dn *dn) { if ( ! dn || dn->invalid) return false; if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true; return dn->ext_comp_num != 0; } bool ldb_dn_check_special(struct ldb_dn *dn, const char *check) { if ( ! dn || dn->invalid) return false; return ! strcmp(dn->linearized, check); } bool ldb_dn_is_null(struct ldb_dn *dn) { if ( ! dn || dn->invalid) return false; if (ldb_dn_has_extended(dn)) return false; if (dn->linearized && (dn->linearized[0] == '\0')) return true; return false; } /* this updates dn->components, taking the components from ref_dn. This is used by code that wants to update the DN path of a DN while not impacting on the extended DN components */ int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn) { dn->components = talloc_realloc(dn, dn->components, struct ldb_dn_component, ref_dn->comp_num); if (!dn->components) { return LDB_ERR_OPERATIONS_ERROR; } memcpy(dn->components, ref_dn->components, sizeof(struct ldb_dn_component)*ref_dn->comp_num); dn->comp_num = ref_dn->comp_num; LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); LDB_FREE(dn->ext_linearized); return LDB_SUCCESS; } /* minimise a DN. The caller must pass in a validated DN. If the DN has an extended component then only the first extended component is kept, the DN string is stripped. The existing dn is modified */ bool ldb_dn_minimise(struct ldb_dn *dn) { unsigned int i; if (!ldb_dn_validate(dn)) { return false; } if (dn->ext_comp_num == 0) { return true; } /* free components */ for (i = 0; i < dn->comp_num; i++) { LDB_FREE(dn->components[i].name); LDB_FREE(dn->components[i].value.data); LDB_FREE(dn->components[i].cf_name); LDB_FREE(dn->components[i].cf_value.data); } dn->comp_num = 0; dn->valid_case = false; LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); /* note that we don't free dn->components as this there are * several places in ldb_dn.c that rely on it being non-NULL * for an exploded DN */ for (i = 1; i < dn->ext_comp_num; i++) { LDB_FREE(dn->ext_components[i].value.data); } dn->ext_comp_num = 1; dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1); if (dn->ext_components == NULL) { ldb_dn_mark_invalid(dn); return false; } LDB_FREE(dn->ext_linearized); return true; } struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn) { return dn->ldb; } ldb-2.0.8/common/ldb_ldif.c0000660000000000000000000006213313573675413015434 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldif routines * * Description: ldif pack/unpack routines * * Author: Andrew Tridgell */ /* see RFC2849 for the LDIF format definition */ #include "ldb_private.h" #include "system/locale.h" /* */ static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value) { struct stat statbuf; char *buf; int count, size, bytes; int ret; int f; const char *fname = (const char *)value->data; if (strncmp(fname, "file://", 7) != 0) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } fname += 7; f = open(fname, O_RDONLY); if (f == -1) { return -1; } if (fstat(f, &statbuf) != 0) { ret = -1; goto done; } if (statbuf.st_size == 0) { ret = -1; goto done; } value->data = (uint8_t *)talloc_size(mem_ctx, statbuf.st_size + 1); if (value->data == NULL) { ret = -1; goto done; } value->data[statbuf.st_size] = 0; count = 0; size = statbuf.st_size; buf = (char *)value->data; while (count < statbuf.st_size) { bytes = read(f, buf, size); if (bytes == -1) { talloc_free(value->data); ret = -1; goto done; } count += bytes; buf += bytes; size -= bytes; } value->length = statbuf.st_size; ret = statbuf.st_size; done: close(f); return ret; } /* this base64 decoder was taken from jitterbug (written by tridge). we might need to replace it with a new version */ int ldb_base64_decode(char *s) { const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int bit_offset=0, byte_offset, idx, i, n; uint8_t *d = (uint8_t *)s; char *p=NULL; n=i=0; while (*s && (p=strchr(b64,*s))) { idx = (int)(p - b64); byte_offset = (i*6)/8; bit_offset = (i*6)%8; d[byte_offset] &= ~((1<<(8-bit_offset))-1); if (bit_offset < 3) { d[byte_offset] |= (idx << (2-bit_offset)); n = byte_offset+1; } else { d[byte_offset] |= (idx >> (bit_offset-2)); d[byte_offset+1] = 0; d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; n = byte_offset+2; } s++; i++; } if (bit_offset >= 3) { n--; } if (*s && !p) { /* the only termination allowed */ if (*s != '=') { return -1; } } /* null terminate */ d[n] = 0; return n; } /* encode as base64 caller frees */ char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len) { const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int bit_offset, byte_offset, idx, i; const uint8_t *d = (const uint8_t *)buf; int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; char *out; out = talloc_array(mem_ctx, char, bytes+pad_bytes+1); if (!out) return NULL; for (i=0;i> (2-bit_offset)) & 0x3F; } else { idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; if (byte_offset+1 < len) { idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); } } out[i] = b64[idx]; } for (;idata; if (val->length == 0) { return 0; } if (p[0] == ' ' || p[0] == ':') { return 1; } for (i=0; ilength; i++) { if (!isprint(p[i]) || p[i] == '\n') { return 1; } } return 0; } /* this macro is used to handle the return checking on fprintf_fn() */ #define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0) /* write a line folded string onto a file */ static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data, const char *buf, size_t length, int start_pos) { size_t i; size_t total = 0; int ret; for (i=0;imsg; p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1); ret = fprintf_fn(private_data, "dn: %s\n", p); talloc_free(p); CHECK_RET; if (ldif->changetype != LDB_CHANGETYPE_NONE) { for (i=0;ldb_changetypes[i].name;i++) { if (ldb_changetypes[i].changetype == ldif->changetype) { break; } } if (!ldb_changetypes[i].name) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d", ldif->changetype); talloc_free(mem_ctx); return -1; } ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name); CHECK_RET; } for (i=0;inum_elements;i++) { const struct ldb_schema_attribute *a; size_t namelen; if (msg->elements[i].name == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid element name (NULL) at position %d", i); talloc_free(mem_ctx); return -1; } namelen = strlen(msg->elements[i].name); a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { case LDB_FLAG_MOD_ADD: fprintf_fn(private_data, "add: %s\n", msg->elements[i].name); break; case LDB_FLAG_MOD_DELETE: fprintf_fn(private_data, "delete: %s\n", msg->elements[i].name); break; case LDB_FLAG_MOD_REPLACE: fprintf_fn(private_data, "replace: %s\n", msg->elements[i].name); break; } } if (in_trace && secret_attributes && ldb_attr_in_list(secret_attributes, msg->elements[i].name)) { /* Deliberatly skip printing this password */ ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE\n", msg->elements[i].name); CHECK_RET; continue; } for (j=0;jelements[i].num_values;j++) { struct ldb_val v; bool use_b64_encode = false; bool copy_raw_bytes = false; ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); if (ret != LDB_SUCCESS) { v = msg->elements[i].values[j]; } if (ldb->flags & LDB_FLG_SHOW_BINARY) { use_b64_encode = false; copy_raw_bytes = true; } else if (a->flags & LDB_ATTR_FLAG_FORCE_BASE64_LDIF) { use_b64_encode = true; } else if (msg->elements[i].flags & LDB_FLAG_FORCE_NO_BASE64_LDIF) { use_b64_encode = false; copy_raw_bytes = true; } else { use_b64_encode = ldb_should_b64_encode(ldb, &v); } if (ret != LDB_SUCCESS || use_b64_encode) { ret = fprintf_fn(private_data, "%s:: ", msg->elements[i].name); CHECK_RET; ret = base64_encode_f(ldb, fprintf_fn, private_data, (char *)v.data, v.length, namelen + 3); CHECK_RET; ret = fprintf_fn(private_data, "\n"); CHECK_RET; } else { ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name); CHECK_RET; if (copy_raw_bytes) { ret = fprintf_fn(private_data, "%*.*s", v.length, v.length, (char *)v.data); } else { ret = fold_string(fprintf_fn, private_data, (char *)v.data, v.length, namelen + 2); } CHECK_RET; ret = fprintf_fn(private_data, "\n"); CHECK_RET; } if (v.data != msg->elements[i].values[j].data) { talloc_free(v.data); } } if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { fprintf_fn(private_data, "-\n"); } } ret = fprintf_fn(private_data,"\n"); CHECK_RET; talloc_free(mem_ctx); return total; } #undef CHECK_RET /* write to ldif, using a caller supplied write method */ int ldb_ldif_write(struct ldb_context *ldb, int (*fprintf_fn)(void *, const char *, ...), void *private_data, const struct ldb_ldif *ldif) { return ldb_ldif_write_trace(ldb, fprintf_fn, private_data, ldif, false); } /* pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF this routine removes any RFC2849 continuations and comments caller frees */ static char *next_chunk(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void *), void *private_data) { size_t alloc_size=0, chunk_size = 0; char *chunk = NULL; int c; int in_comment = 0; while ((c = fgetc_fn(private_data)) != EOF) { if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); if (!c2) { talloc_free(chunk); errno = ENOMEM; return NULL; } chunk = c2; } if (in_comment) { if (c == '\n') { in_comment = 0; } continue; } /* handle continuation lines - see RFC2849 */ if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') { chunk_size--; continue; } /* chunks are terminated by a double line-feed */ if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') { chunk[chunk_size-1] = 0; return chunk; } if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { in_comment = 1; continue; } /* ignore leading blank lines */ if (chunk_size == 0 && c == '\n') { continue; } chunk[chunk_size++] = c; } if (chunk) { chunk[chunk_size] = 0; } return chunk; } /* simple ldif attribute parser */ static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value) { char *p; int base64_encoded = 0; int binary_file = 0; if (strncmp(*s, "-\n", 2) == 0) { value->length = 0; *attr = "-"; *s += 2; return 0; } p = strchr(*s, ':'); if (!p) { return -1; } *p++ = 0; if (*p == ':') { base64_encoded = 1; p++; } if (*p == '<') { binary_file = 1; p++; } *attr = *s; while (*p == ' ' || *p == '\t') { p++; } value->data = (uint8_t *)p; p = strchr(p, '\n'); if (!p) { value->length = strlen((char *)value->data); *s = ((char *)value->data) + value->length; } else { value->length = p - (char *)value->data; *s = p+1; *p = 0; } if (base64_encoded) { int len = ldb_base64_decode((char *)value->data); if (len == -1) { /* it wasn't valid base64 data */ return -1; } value->length = len; } if (binary_file) { int len = ldb_read_data_file(mem_ctx, value); if (len == -1) { /* an error occurred while trying to retrieve the file */ return -1; } } return 0; } /* free a message from a ldif_read */ void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) { talloc_free(ldif); } int ldb_ldif_parse_modrdn(struct ldb_context *ldb, const struct ldb_ldif *ldif, TALLOC_CTX *mem_ctx, struct ldb_dn **_olddn, struct ldb_dn **_newrdn, bool *_deleteoldrdn, struct ldb_dn **_newsuperior, struct ldb_dn **_newdn) { struct ldb_message *msg = ldif->msg; struct ldb_val *newrdn_val = NULL; struct ldb_val *deleteoldrdn_val = NULL; struct ldb_val *newsuperior_val = NULL; struct ldb_dn *olddn = NULL; struct ldb_dn *newrdn = NULL; bool deleteoldrdn = true; struct ldb_dn *newsuperior = NULL; struct ldb_dn *newdn = NULL; struct ldb_val tmp_false; struct ldb_val tmp_true; bool ok; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Error: talloc_new() failed"); goto err_op; } if (ldif->changetype != LDB_CHANGETYPE_MODRDN) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: invalid changetype '%d'", ldif->changetype); goto err_other; } if (msg->num_elements < 2) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: num_elements[%u] < 2", msg->num_elements); goto err_other; } if (msg->num_elements > 3) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: num_elements[%u] > 3", msg->num_elements); goto err_other; } #define CHECK_ELEMENT(i, _name, v, needed) do { \ v = NULL; \ if (msg->num_elements < (i + 1)) { \ if (needed) { \ ldb_debug(ldb, LDB_DEBUG_ERROR, \ "Error: num_elements[%u] < (%u + 1)", \ msg->num_elements, i); \ goto err_other; \ } \ } else if (ldb_attr_cmp(msg->elements[i].name, _name) != 0) { \ ldb_debug(ldb, LDB_DEBUG_ERROR, \ "Error: elements[%u].name[%s] != [%s]", \ i, msg->elements[i].name, _name); \ goto err_other; \ } else if (msg->elements[i].flags != 0) { \ ldb_debug(ldb, LDB_DEBUG_ERROR, \ "Error: elements[%u].flags[0x%X} != [0x0]", \ i, msg->elements[i].flags); \ goto err_other; \ } else if (msg->elements[i].num_values != 1) { \ ldb_debug(ldb, LDB_DEBUG_ERROR, \ "Error: elements[%u].num_values[%u] != 1", \ i, msg->elements[i].num_values); \ goto err_other; \ } else { \ v = &msg->elements[i].values[0]; \ } \ } while (0) CHECK_ELEMENT(0, "newrdn", newrdn_val, true); CHECK_ELEMENT(1, "deleteoldrdn", deleteoldrdn_val, true); CHECK_ELEMENT(2, "newsuperior", newsuperior_val, false); #undef CHECK_ELEMENT olddn = ldb_dn_copy(tmp_ctx, msg->dn); if (olddn == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: failed to copy olddn '%s'", ldb_dn_get_linearized(msg->dn)); goto err_op; } newrdn = ldb_dn_from_ldb_val(tmp_ctx, ldb, newrdn_val); if (!ldb_dn_validate(newrdn)) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", (char *)newrdn_val->data); goto err_dn; } tmp_false.length = 1; tmp_false.data = discard_const_p(uint8_t, "0"); tmp_true.length = 1; tmp_true.data = discard_const_p(uint8_t, "1"); if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_false) == 1) { deleteoldrdn = false; } else if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_true) == 1) { deleteoldrdn = true; } else { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: deleteoldrdn value invalid '%s' not '0'/'1'", (char *)deleteoldrdn_val->data); goto err_attr; } if (newsuperior_val) { newsuperior = ldb_dn_from_ldb_val(tmp_ctx, ldb, newsuperior_val); if (!ldb_dn_validate(newsuperior)) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", (char *)newsuperior_val->data); goto err_dn; } } else { newsuperior = ldb_dn_get_parent(tmp_ctx, msg->dn); if (newsuperior == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to get parent dn '%s'", ldb_dn_get_linearized(msg->dn)); goto err_dn; } } newdn = ldb_dn_copy(tmp_ctx, newrdn); if (newdn == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: failed to copy newrdn '%s'", ldb_dn_get_linearized(newrdn)); goto err_op; } ok = ldb_dn_add_base(newdn, newsuperior); if (!ok) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: failed to base '%s' to newdn '%s'", ldb_dn_get_linearized(newsuperior), ldb_dn_get_linearized(newdn)); goto err_op; } if (_olddn) { *_olddn = talloc_move(mem_ctx, &olddn); } if (_newrdn) { *_newrdn = talloc_move(mem_ctx, &newrdn); } if (_deleteoldrdn) { *_deleteoldrdn = deleteoldrdn; } if (_newsuperior != NULL && _newrdn != NULL) { if (newsuperior_val) { *_newrdn = talloc_move(mem_ctx, &newrdn); } else { *_newrdn = NULL; } } if (_newdn) { *_newdn = talloc_move(mem_ctx, &newdn); } talloc_free(tmp_ctx); return LDB_SUCCESS; err_other: talloc_free(tmp_ctx); return LDB_ERR_OTHER; err_op: talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; err_attr: talloc_free(tmp_ctx); return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; err_dn: talloc_free(tmp_ctx); return LDB_ERR_INVALID_DN_SYNTAX; } /* read from a LDIF source, creating a ldb_message */ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, int (*fgetc_fn)(void *), void *private_data) { struct ldb_ldif *ldif; struct ldb_message *msg; const char *attr=NULL; char *chunk=NULL, *s; struct ldb_val value; unsigned flags = 0; value.data = NULL; ldif = talloc(ldb, struct ldb_ldif); if (!ldif) return NULL; ldif->msg = ldb_msg_new(ldif); if (ldif->msg == NULL) { talloc_free(ldif); return NULL; } ldif->changetype = LDB_CHANGETYPE_NONE; msg = ldif->msg; chunk = next_chunk(ldb, ldif, fgetc_fn, private_data); if (!chunk) { goto failed; } s = chunk; if (next_attr(ldif, &s, &attr, &value) != 0) { goto failed; } /* first line must be a dn */ if (ldb_attr_cmp(attr, "dn") != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'", attr); goto failed; } msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value); if ( ! ldb_dn_validate(msg->dn)) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", (char *)value.data); goto failed; } while (next_attr(ldif, &s, &attr, &value) == 0) { const struct ldb_schema_attribute *a; struct ldb_message_element *el; int ret, empty = 0; if (ldb_attr_cmp(attr, "changetype") == 0) { int i; for (i=0;ldb_changetypes[i].name;i++) { if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) { ldif->changetype = ldb_changetypes[i].changetype; break; } } if (!ldb_changetypes[i].name) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Bad ldif changetype '%s'",(char *)value.data); } flags = 0; continue; } if (ldb_attr_cmp(attr, "add") == 0) { flags = LDB_FLAG_MOD_ADD; empty = 1; } if (ldb_attr_cmp(attr, "delete") == 0) { flags = LDB_FLAG_MOD_DELETE; empty = 1; } if (ldb_attr_cmp(attr, "replace") == 0) { flags = LDB_FLAG_MOD_REPLACE; empty = 1; } if (ldb_attr_cmp(attr, "-") == 0) { flags = 0; continue; } if (empty) { if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) { goto failed; } continue; } el = &msg->elements[msg->num_elements-1]; a = ldb_schema_attribute_by_name(ldb, attr); if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 && flags == el->flags) { /* its a continuation */ el->values = talloc_realloc(msg->elements, el->values, struct ldb_val, el->num_values+1); if (!el->values) { goto failed; } ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[el->num_values]); if (ret != 0) { goto failed; } if (value.length == 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Attribute value cannot be empty for attribute '%s'", el->name); goto failed; } if (value.data != el->values[el->num_values].data) { talloc_steal(el->values, el->values[el->num_values].data); } el->num_values++; } else { /* its a new attribute */ msg->elements = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements+1); if (!msg->elements) { goto failed; } el = &msg->elements[msg->num_elements]; el->flags = flags; el->name = talloc_strdup(msg->elements, attr); el->values = talloc(msg->elements, struct ldb_val); if (!el->values || !el->name) { goto failed; } el->num_values = 1; ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[0]); if (ret != 0) { goto failed; } if (value.data != el->values[0].data) { talloc_steal(el->values, el->values[0].data); } msg->num_elements++; } } if (ldif->changetype == LDB_CHANGETYPE_MODRDN) { int ret; ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, NULL, NULL, NULL, NULL, NULL); if (ret != LDB_SUCCESS) { goto failed; } } return ldif; failed: talloc_free(ldif); return NULL; } /* a wrapper around ldif_read() for reading from FILE* */ static int fgetc_file(void *private_data) { int c; struct ldif_read_file_state *state = (struct ldif_read_file_state *)private_data; c = fgetc(state->f); if (c == '\n') { state->line_no++; } return c; } struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, struct ldif_read_file_state *state) { return ldb_ldif_read(ldb, fgetc_file, state); } struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f) { struct ldif_read_file_state state; state.f = f; return ldb_ldif_read_file_state(ldb, &state); } /* a wrapper around ldif_read() for reading from const char* */ struct ldif_read_string_state { const char *s; }; static int fgetc_string(void *private_data) { struct ldif_read_string_state *state = (struct ldif_read_string_state *)private_data; if (state->s[0] != 0) { return *state->s++; } return EOF; } struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s) { struct ldif_read_string_state state; struct ldb_ldif *ldif; state.s = *s; ldif = ldb_ldif_read(ldb, fgetc_string, &state); *s = state.s; return ldif; } /* wrapper around ldif_write() for a file */ struct ldif_write_file_state { FILE *f; }; static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); static int fprintf_file(void *private_data, const char *fmt, ...) { struct ldif_write_file_state *state = (struct ldif_write_file_state *)private_data; int ret; va_list ap; va_start(ap, fmt); ret = vfprintf(state->f, fmt, ap); va_end(ap); return ret; } int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif) { struct ldif_write_file_state state; state.f = f; return ldb_ldif_write(ldb, fprintf_file, &state, ldif); } /* wrapper around ldif_write() for a string */ struct ldif_write_string_state { char *string; }; static int ldif_printf_string(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); static int ldif_printf_string(void *private_data, const char *fmt, ...) { struct ldif_write_string_state *state = (struct ldif_write_string_state *)private_data; va_list ap; size_t oldlen = talloc_get_size(state->string); va_start(ap, fmt); state->string = talloc_vasprintf_append(state->string, fmt, ap); va_end(ap); if (!state->string) { return -1; } return talloc_get_size(state->string) - oldlen; } char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *ldif) { struct ldif_write_string_state state; state.string = talloc_strdup(mem_ctx, ""); if (!state.string) { return NULL; } if (ldb_ldif_write_trace(ldb, ldif_printf_string, &state, ldif, true) == -1) { return NULL; } return state.string; } char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *ldif) { struct ldif_write_string_state state; state.string = talloc_strdup(mem_ctx, ""); if (!state.string) { return NULL; } if (ldb_ldif_write(ldb, ldif_printf_string, &state, ldif) == -1) { return NULL; } return state.string; } /* convenient function to turn a ldb_message into a string. Useful for debugging */ char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, enum ldb_changetype changetype, const struct ldb_message *msg) { struct ldb_ldif ldif; ldif.changetype = changetype; ldif.msg = discard_const_p(struct ldb_message, msg); return ldb_ldif_write_string(ldb, mem_ctx, &ldif); } /* * convenient function to turn a ldb_message into a string. Useful for * debugging but also safer if some of the LDIF could be sensitive. * * The secret attributes are specified in a 'const char * const *' within * the LDB_SECRET_ATTRIBUTE_LIST opaque set on the ldb * */ char *ldb_ldif_message_redacted_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, enum ldb_changetype changetype, const struct ldb_message *msg) { struct ldb_ldif ldif; ldif.changetype = changetype; ldif.msg = discard_const_p(struct ldb_message, msg); return ldb_ldif_write_redacted_trace_string(ldb, mem_ctx, &ldif); } ldb-2.0.8/common/ldb_match.c0000660000000000000000000004416213444661620015604 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004-2005 Copyright (C) Simo Sorce 2005 ** 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 . */ /* * Name: ldb * * Component: ldb expression matching * * Description: ldb expression matching * * Author: Andrew Tridgell */ #include "ldb_private.h" #include "dlinklist.h" /* check if the scope matches in a search result */ static int ldb_match_scope(struct ldb_context *ldb, struct ldb_dn *base, struct ldb_dn *dn, enum ldb_scope scope) { int ret = 0; if (base == NULL || dn == NULL) { return 1; } switch (scope) { case LDB_SCOPE_BASE: if (ldb_dn_compare(base, dn) == 0) { ret = 1; } break; case LDB_SCOPE_ONELEVEL: if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { if (ldb_dn_compare_base(base, dn) == 0) { ret = 1; } } break; case LDB_SCOPE_SUBTREE: default: if (ldb_dn_compare_base(base, dn) == 0) { ret = 1; } break; } return ret; } /* match if node is present */ static int ldb_match_present(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, bool *matched) { const struct ldb_schema_attribute *a; struct ldb_message_element *el; if (ldb_attr_dn(tree->u.present.attr) == 0) { *matched = true; return LDB_SUCCESS; } el = ldb_msg_find_element(msg, tree->u.present.attr); if (el == NULL) { *matched = false; return LDB_SUCCESS; } a = ldb_schema_attribute_by_name(ldb, el->name); if (!a) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } if (a->syntax->operator_fn) { unsigned int i; for (i = 0; i < el->num_values; i++) { int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched); if (ret != LDB_SUCCESS) return ret; if (*matched) return LDB_SUCCESS; } *matched = false; return LDB_SUCCESS; } *matched = true; return LDB_SUCCESS; } static int ldb_match_comparison(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, enum ldb_parse_op comp_op, bool *matched) { unsigned int i; struct ldb_message_element *el; const struct ldb_schema_attribute *a; /* FIXME: APPROX comparison not handled yet */ if (comp_op == LDB_OP_APPROX) { return LDB_ERR_INAPPROPRIATE_MATCHING; } el = ldb_msg_find_element(msg, tree->u.comparison.attr); if (el == NULL) { *matched = false; return LDB_SUCCESS; } a = ldb_schema_attribute_by_name(ldb, el->name); if (!a) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } for (i = 0; i < el->num_values; i++) { if (a->syntax->operator_fn) { int ret; ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched); if (ret != LDB_SUCCESS) return ret; if (*matched) return LDB_SUCCESS; } else { int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); if (ret == 0) { *matched = true; return LDB_SUCCESS; } if (ret > 0 && comp_op == LDB_OP_GREATER) { *matched = true; return LDB_SUCCESS; } if (ret < 0 && comp_op == LDB_OP_LESS) { *matched = true; return LDB_SUCCESS; } } } *matched = false; return LDB_SUCCESS; } /* match a simple leaf node */ static int ldb_match_equality(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, bool *matched) { unsigned int i; struct ldb_message_element *el; const struct ldb_schema_attribute *a; struct ldb_dn *valuedn; int ret; if (ldb_attr_dn(tree->u.equality.attr) == 0) { valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); if (valuedn == NULL) { return LDB_ERR_INVALID_DN_SYNTAX; } ret = ldb_dn_compare(msg->dn, valuedn); talloc_free(valuedn); *matched = (ret == 0); return LDB_SUCCESS; } /* TODO: handle the "*" case derived from an extended search operation without the attibute type defined */ el = ldb_msg_find_element(msg, tree->u.equality.attr); if (el == NULL) { *matched = false; return LDB_SUCCESS; } a = ldb_schema_attribute_by_name(ldb, el->name); if (a == NULL) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } for (i=0;inum_values;i++) { if (a->syntax->operator_fn) { ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, &tree->u.equality.value, &el->values[i], matched); if (ret != LDB_SUCCESS) return ret; if (*matched) return LDB_SUCCESS; } else { if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, &el->values[i]) == 0) { *matched = true; return LDB_SUCCESS; } } } *matched = false; return LDB_SUCCESS; } static int ldb_wildcard_compare(struct ldb_context *ldb, const struct ldb_parse_tree *tree, const struct ldb_val value, bool *matched) { const struct ldb_schema_attribute *a; struct ldb_val val; struct ldb_val cnk; struct ldb_val *chunk; uint8_t *save_p = NULL; unsigned int c = 0; if (tree->operation != LDB_OP_SUBSTRING) { *matched = false; return LDB_ERR_INAPPROPRIATE_MATCHING; } a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr); if (!a) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } if (tree->u.substring.chunks == NULL) { *matched = false; return LDB_SUCCESS; } if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } save_p = val.data; cnk.data = NULL; if ( ! tree->u.substring.start_with_wildcard ) { chunk = tree->u.substring.chunks[c]; if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ if (cnk.length > val.length) { goto mismatch; } /* * Empty strings are returned as length 0. Ensure * we can cope with this. */ if (cnk.length == 0) { goto mismatch; } if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; val.length -= cnk.length; val.data += cnk.length; c++; talloc_free(cnk.data); cnk.data = NULL; } while (tree->u.substring.chunks[c]) { uint8_t *p; chunk = tree->u.substring.chunks[c]; if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; /* * Empty strings are returned as length 0. Ensure * we can cope with this. */ if (cnk.length == 0) { goto mismatch; } /* * Values might be binary blobs. Don't use string * search, but memory search instead. */ p = memmem((const void *)val.data,val.length, (const void *)cnk.data, cnk.length); if (p == NULL) goto mismatch; /* * At this point we know cnk.length <= val.length as * otherwise there could be no match */ if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { uint8_t *g; uint8_t *end = val.data + val.length; do { /* greedy */ /* * haystack is a valid pointer in val * because the memmem() can only * succeed if the needle (cnk.length) * is <= haystacklen * * p will be a pointer at least * cnk.length from the end of haystack */ uint8_t *haystack = p + cnk.length; size_t haystacklen = end - (haystack); g = memmem(haystack, haystacklen, (const uint8_t *)cnk.data, cnk.length); if (g) { p = g; } } while(g); } val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length; val.data = (uint8_t *)(p + cnk.length); c++; talloc_free(cnk.data); cnk.data = NULL; } /* last chunk may not have reached end of string */ if ( (! tree->u.substring.end_with_wildcard) && (val.length != 0) ) goto mismatch; talloc_free(save_p); *matched = true; return LDB_SUCCESS; mismatch: *matched = false; talloc_free(save_p); talloc_free(cnk.data); return LDB_SUCCESS; } /* match a simple leaf node */ static int ldb_match_substring(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, bool *matched) { unsigned int i; struct ldb_message_element *el; el = ldb_msg_find_element(msg, tree->u.substring.attr); if (el == NULL) { *matched = false; return LDB_SUCCESS; } for (i = 0; i < el->num_values; i++) { int ret; ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); if (ret != LDB_SUCCESS) return ret; if (*matched) return LDB_SUCCESS; } *matched = false; return LDB_SUCCESS; } /* bitwise and/or comparator depending on oid */ static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2, bool *matched) { uint64_t i1, i2; char ibuf[100]; char *endptr = NULL; if (v1->length >= sizeof(ibuf)-1) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } memcpy(ibuf, (char *)v1->data, v1->length); ibuf[v1->length] = 0; i1 = strtoull(ibuf, &endptr, 0); if (endptr != NULL) { if (endptr == ibuf || *endptr != 0) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } } if (v2->length >= sizeof(ibuf)-1) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } endptr = NULL; memcpy(ibuf, (char *)v2->data, v2->length); ibuf[v2->length] = 0; i2 = strtoull(ibuf, &endptr, 0); if (endptr != NULL) { if (endptr == ibuf || *endptr != 0) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } } if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) { *matched = ((i1 & i2) == i2); } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) { *matched = ((i1 & i2) != 0); } else { return LDB_ERR_INAPPROPRIATE_MATCHING; } return LDB_SUCCESS; } static int ldb_match_bitmask(struct ldb_context *ldb, const char *oid, const struct ldb_message *msg, const char *attribute_to_match, const struct ldb_val *value_to_match, bool *matched) { unsigned int i; struct ldb_message_element *el; /* find the message element */ el = ldb_msg_find_element(msg, attribute_to_match); if (el == NULL) { *matched = false; return LDB_SUCCESS; } for (i=0;inum_values;i++) { int ret; struct ldb_val *v = &el->values[i]; ret = ldb_comparator_bitmask(oid, v, value_to_match, matched); if (ret != LDB_SUCCESS) { return ret; } if (*matched) { return LDB_SUCCESS; } } *matched = false; return LDB_SUCCESS; } /* always return false */ static int ldb_comparator_false(struct ldb_context *ldb, const char *oid, const struct ldb_message *msg, const char *attribute_to_match, const struct ldb_val *value_to_match, bool *matched) { *matched = false; return LDB_SUCCESS; } static const struct ldb_extended_match_rule *ldb_find_extended_match_rule(struct ldb_context *ldb, const char *oid) { struct ldb_extended_match_entry *extended_match_rule; for (extended_match_rule = ldb->extended_match_rules; extended_match_rule; extended_match_rule = extended_match_rule->next) { if (strcmp(extended_match_rule->rule->oid, oid) == 0) { return extended_match_rule->rule; } } return NULL; } /* extended match, handles things like bitops */ static int ldb_match_extended(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, bool *matched) { const struct ldb_extended_match_rule *rule; if (tree->u.extended.dnAttributes) { /* FIXME: We really need to find out what this ":dn" part in * an extended match means and how to handle it. For now print * only a warning to have s3 winbind and other tools working * against us. - Matthias */ ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet"); } if (tree->u.extended.rule_id == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); return LDB_ERR_INAPPROPRIATE_MATCHING; } if (tree->u.extended.attr == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); return LDB_ERR_INAPPROPRIATE_MATCHING; } rule = ldb_find_extended_match_rule(ldb, tree->u.extended.rule_id); if (rule == NULL) { *matched = false; ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s", tree->u.extended.rule_id); return LDB_SUCCESS; } return rule->callback(ldb, rule->oid, msg, tree->u.extended.attr, &tree->u.extended.value, matched); } /* Check if a particular message will match the given filter set *matched to true if it matches, false otherwise returns LDB_SUCCESS or an error this is a recursive function, and does short-circuit evaluation */ int ldb_match_message(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, bool *matched) { unsigned int i; int ret; *matched = false; if (scope != LDB_SCOPE_BASE && ldb_dn_is_special(msg->dn)) { /* don't match special records except on base searches */ return LDB_SUCCESS; } switch (tree->operation) { case LDB_OP_AND: for (i=0;iu.list.num_elements;i++) { ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); if (ret != LDB_SUCCESS) return ret; if (!*matched) return LDB_SUCCESS; } *matched = true; return LDB_SUCCESS; case LDB_OP_OR: for (i=0;iu.list.num_elements;i++) { ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); if (ret != LDB_SUCCESS) return ret; if (*matched) return LDB_SUCCESS; } *matched = false; return LDB_SUCCESS; case LDB_OP_NOT: ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched); if (ret != LDB_SUCCESS) return ret; *matched = ! *matched; return LDB_SUCCESS; case LDB_OP_EQUALITY: return ldb_match_equality(ldb, msg, tree, scope, matched); case LDB_OP_SUBSTRING: return ldb_match_substring(ldb, msg, tree, scope, matched); case LDB_OP_GREATER: return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched); case LDB_OP_LESS: return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched); case LDB_OP_PRESENT: return ldb_match_present(ldb, msg, tree, scope, matched); case LDB_OP_APPROX: return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched); case LDB_OP_EXTENDED: return ldb_match_extended(ldb, msg, tree, scope, matched); } return LDB_ERR_INAPPROPRIATE_MATCHING; } /* return 0 if the given parse tree matches the given message. Assumes the message is in sorted order return 1 if it matches, and 0 if it doesn't match */ int ldb_match_msg(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, struct ldb_dn *base, enum ldb_scope scope) { bool matched; int ret; if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { return 0; } ret = ldb_match_message(ldb, msg, tree, scope, &matched); if (ret != LDB_SUCCESS) { /* to match the old API, we need to consider this a failure to match */ return 0; } return matched?1:0; } int ldb_match_msg_error(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, struct ldb_dn *base, enum ldb_scope scope, bool *matched) { if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { *matched = false; return LDB_SUCCESS; } return ldb_match_message(ldb, msg, tree, scope, matched); } int ldb_match_msg_objectclass(const struct ldb_message *msg, const char *objectclass) { unsigned int i; struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass"); if (!el) { return 0; } for (i=0; i < el->num_values; i++) { if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) { return 1; } } return 0; } _PRIVATE_ int ldb_register_extended_match_rules(struct ldb_context *ldb) { struct ldb_extended_match_rule *bitmask_and; struct ldb_extended_match_rule *bitmask_or; struct ldb_extended_match_rule *always_false; int ret; /* Register bitmask-and match */ bitmask_and = talloc_zero(ldb, struct ldb_extended_match_rule); if (bitmask_and == NULL) { return LDB_ERR_OPERATIONS_ERROR; } bitmask_and->oid = LDB_OID_COMPARATOR_AND; bitmask_and->callback = ldb_match_bitmask; ret = ldb_register_extended_match_rule(ldb, bitmask_and); if (ret != LDB_SUCCESS) { return ret; } /* Register bitmask-or match */ bitmask_or = talloc_zero(ldb, struct ldb_extended_match_rule); if (bitmask_or == NULL) { return LDB_ERR_OPERATIONS_ERROR; } bitmask_or->oid = LDB_OID_COMPARATOR_OR; bitmask_or->callback = ldb_match_bitmask; ret = ldb_register_extended_match_rule(ldb, bitmask_or); if (ret != LDB_SUCCESS) { return ret; } /* Register always-false match */ always_false = talloc_zero(ldb, struct ldb_extended_match_rule); if (always_false == NULL) { return LDB_ERR_OPERATIONS_ERROR; } always_false->oid = SAMBA_LDAP_MATCH_ALWAYS_FALSE; always_false->callback = ldb_comparator_false; ret = ldb_register_extended_match_rule(ldb, always_false); if (ret != LDB_SUCCESS) { return ret; } return LDB_SUCCESS; } /* register a new ldb extended matching rule */ int ldb_register_extended_match_rule(struct ldb_context *ldb, const struct ldb_extended_match_rule *rule) { const struct ldb_extended_match_rule *lookup_rule; struct ldb_extended_match_entry *entry; lookup_rule = ldb_find_extended_match_rule(ldb, rule->oid); if (lookup_rule) { return LDB_ERR_ENTRY_ALREADY_EXISTS; } entry = talloc_zero(ldb, struct ldb_extended_match_entry); if (!entry) { return LDB_ERR_OPERATIONS_ERROR; } entry->rule = rule; DLIST_ADD_END(ldb->extended_match_rules, entry); return LDB_SUCCESS; } ldb-2.0.8/common/ldb_modules.c0000660000000000000000000007523313444661620016163 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2004-2008 ** 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 . */ /* * Name: ldb * * Component: ldb modules core * * Description: core modules routines * * Author: Simo Sorce */ #include "ldb_private.h" #include "dlinklist.h" #include "system/dir.h" static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) { size_t i, len; char *trimmed; trimmed = talloc_strdup(mem_ctx, string); if (!trimmed) { return NULL; } len = strlen(trimmed); for (i = 0; trimmed[i] != '\0'; i++) { switch (trimmed[i]) { case ' ': case '\t': case '\n': memmove(&trimmed[i], &trimmed[i + 1], len -i -1); break; } } return trimmed; } /* modules are called in inverse order on the stack. Lets place them as an admin would think the right order is. Modules order is important */ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string) { char **modules = NULL; const char **m; char *modstr, *p; unsigned int i; /* spaces not admitted */ modstr = ldb_modules_strdup_no_spaces(mem_ctx, string); if ( ! modstr) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()"); return NULL; } modules = talloc_realloc(mem_ctx, modules, char *, 2); if ( ! modules ) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); talloc_free(modstr); return NULL; } talloc_steal(modules, modstr); if (modstr[0] == '\0') { modules[0] = NULL; m = discard_const_p(const char *, modules); return m; } i = 0; /* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */ while ((p = strrchr(modstr, ',')) != NULL) { *p = '\0'; p++; modules[i] = p; i++; modules = talloc_realloc(mem_ctx, modules, char *, i + 2); if ( ! modules ) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); return NULL; } } modules[i] = modstr; modules[i + 1] = NULL; m = discard_const_p(const char *, modules); return m; } static struct backends_list_entry { struct ldb_backend_ops *ops; struct backends_list_entry *prev, *next; } *ldb_backends = NULL; static struct ops_list_entry { const struct ldb_module_ops *ops; struct ops_list_entry *next; } *registered_modules = NULL; static struct backends_list_entry *ldb_find_backend(const char *url_prefix) { struct backends_list_entry *backend; for (backend = ldb_backends; backend; backend = backend->next) { if (strcmp(backend->ops->name, url_prefix) == 0) { return backend; } } return NULL; } /* register a new ldb backend if override is true, then override any existing backend for this prefix */ int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override) { struct backends_list_entry *be; be = ldb_find_backend(url_prefix); if (be) { if (!override) { return LDB_SUCCESS; } } else { be = talloc_zero(ldb_backends, struct backends_list_entry); if (!be) { return LDB_ERR_OPERATIONS_ERROR; } be->ops = talloc_zero(be, struct ldb_backend_ops); if (!be->ops) { talloc_free(be); return LDB_ERR_OPERATIONS_ERROR; } DLIST_ADD_END(ldb_backends, be); } be->ops->name = url_prefix; be->ops->connect_fn = connectfn; return LDB_SUCCESS; } /* Return the ldb module form of a database. The URL can either be one of the following forms ldb://path ldapi://path flags is made up of LDB_FLG_* the options are passed uninterpreted to the backend, and are backend specific. This allows modules to get at only the backend module, for example where a module may wish to direct certain requests at a particular backend. */ int ldb_module_connect_backend(struct ldb_context *ldb, const char *url, const char *options[], struct ldb_module **backend_module) { int ret; char *backend; struct backends_list_entry *be; if (strchr(url, ':') != NULL) { backend = talloc_strndup(ldb, url, strchr(url, ':')-url); } else { /* Default to tdb */ backend = talloc_strdup(ldb, "tdb"); } if (backend == NULL) { return ldb_oom(ldb); } be = ldb_find_backend(backend); talloc_free(backend); if (be == NULL) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url); return LDB_ERR_OTHER; } ret = be->ops->connect_fn(ldb, url, ldb->flags, options, backend_module); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s' with backend '%s': %s", url, be->ops->name, ldb_errstring(ldb)); return ret; } return ret; } static struct ldb_hooks { struct ldb_hooks *next, *prev; ldb_hook_fn hook_fn; } *ldb_hooks; /* register a ldb hook function */ int ldb_register_hook(ldb_hook_fn hook_fn) { struct ldb_hooks *lc; lc = talloc_zero(ldb_hooks, struct ldb_hooks); if (lc == NULL) { return LDB_ERR_OPERATIONS_ERROR; } lc->hook_fn = hook_fn; DLIST_ADD_END(ldb_hooks, lc); return LDB_SUCCESS; } /* call ldb hooks of a given type */ int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) { struct ldb_hooks *lc; for (lc = ldb_hooks; lc; lc=lc->next) { int ret = lc->hook_fn(ldb, t); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } static const struct ldb_module_ops *ldb_find_module_ops(const char *name) { struct ops_list_entry *e; for (e = registered_modules; e; e = e->next) { if (strcmp(e->ops->name, name) == 0) return e->ops; } return NULL; } int ldb_register_module(const struct ldb_module_ops *ops) { struct ops_list_entry *entry; if (ldb_find_module_ops(ops->name) != NULL) return LDB_ERR_ENTRY_ALREADY_EXISTS; /* * ldb modules are not (yet) unloaded and * are only loaded once (the above check * makes sure of this). Allocate off the NULL * context. We never want this to be freed * until process shutdown. If eventually we * want to unload ldb modules we can add a * deregister function that walks and * frees the list. */ entry = talloc(NULL, struct ops_list_entry); if (entry == NULL) { return LDB_ERR_OPERATIONS_ERROR; } entry->ops = ops; entry->next = registered_modules; registered_modules = entry; return LDB_SUCCESS; } /* load a list of modules */ int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out) { struct ldb_module *module; unsigned int i; module = backend; for (i = 0; module_list && module_list[i] != NULL; i++) { struct ldb_module *current; const struct ldb_module_ops *ops; if (strcmp(module_list[i], "") == 0) { continue; } ops = ldb_find_module_ops(module_list[i]); if (ops == NULL) { ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?", module_list[i]); return LDB_ERR_OPERATIONS_ERROR; } current = talloc_zero(ldb, struct ldb_module); if (current == NULL) { return LDB_ERR_OPERATIONS_ERROR; } talloc_set_name(current, "ldb_module: %s", module_list[i]); current->ldb = ldb; current->ops = ops; DLIST_ADD(module, current); } *out = module; return LDB_SUCCESS; } /* initialise a chain of modules */ int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module) { while (module && module->ops->init_context == NULL) module = module->next; /* init is different in that it is not an error if modules * do not require initialization */ if (module) { int ret = module->ops->init_context(module); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s", module->ops->name, ldb_strerror(ret)); return ret; } } return LDB_SUCCESS; } int ldb_load_modules(struct ldb_context *ldb, const char *options[]) { const char *modules_string; const char **modules = NULL; int ret; TALLOC_CTX *mem_ctx = talloc_new(ldb); if (!mem_ctx) { return ldb_oom(ldb); } /* find out which modules we are requested to activate */ /* check if we have a custom module list passd as ldb option */ if (options) { modules_string = ldb_options_find(ldb, options, "modules"); if (modules_string) { modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string); } } /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */ if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { const char * const attrs[] = { "@LIST" , NULL}; struct ldb_result *res = NULL; struct ldb_dn *mods_dn; mods_dn = ldb_dn_new(mem_ctx, ldb, "@MODULES"); if (mods_dn == NULL) { talloc_free(mem_ctx); return ldb_oom(ldb); } ret = ldb_search(ldb, mods_dn, &res, mods_dn, LDB_SCOPE_BASE, attrs, "@LIST=*"); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); } else if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb)); talloc_free(mem_ctx); return ret; } else { const char *module_list; if (res->count == 0) { ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); } else if (res->count > 1) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%u), bailing out", res->count); talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } else { module_list = ldb_msg_find_attr_as_string(res->msgs[0], "@LIST", NULL); if (!module_list) { ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); } modules = ldb_modules_list_from_string(ldb, mem_ctx, module_list); } } talloc_free(mods_dn); } if (modules != NULL) { ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } } else { ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database"); } ret = ldb_module_init_chain(ldb, ldb->modules); talloc_free(mem_ctx); return ret; } /* by using this we allow ldb modules to only implement the functions they care about, which makes writing a module simpler, and makes it more likely to keep working when ldb is extended */ #define FIND_OP_NOERR(module, op) do { \ module = module->next; \ while (module && module->ops->op == NULL) module = module->next; \ if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { \ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_trace_next_request: (%s)->" #op, \ module->ops->name); \ } \ } while (0) #define FIND_OP(module, op) do { \ struct ldb_context *ldb = module->ldb; \ FIND_OP_NOERR(module, op); \ if (module == NULL) { \ ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \ return LDB_ERR_OPERATIONS_ERROR; \ } \ } while (0) struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, struct ldb_context *ldb, const char *module_name, const struct ldb_module_ops *ops) { struct ldb_module *module; module = talloc(memctx, struct ldb_module); if (!module) { ldb_oom(ldb); return NULL; } talloc_set_name_const(module, module_name); module->ldb = ldb; module->prev = module->next = NULL; module->ops = ops; return module; } const char * ldb_module_get_name(struct ldb_module *module) { return module->ops->name; } struct ldb_context *ldb_module_get_ctx(struct ldb_module *module) { return module->ldb; } const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module) { return module->ops; } void *ldb_module_get_private(struct ldb_module *module) { return module->private_data; } void ldb_module_set_private(struct ldb_module *module, void *private_data) { module->private_data = private_data; } /* helper functions to call the next module in chain */ int ldb_next_request(struct ldb_module *module, struct ldb_request *request) { int ret; if (request->callback == NULL) { ldb_set_errstring(module->ldb, "Requests MUST define callbacks"); return LDB_ERR_UNWILLING_TO_PERFORM; } request->handle->nesting++; switch (request->operation) { case LDB_SEARCH: FIND_OP(module, search); ret = module->ops->search(module, request); break; case LDB_ADD: FIND_OP(module, add); ret = module->ops->add(module, request); break; case LDB_MODIFY: FIND_OP(module, modify); ret = module->ops->modify(module, request); break; case LDB_DELETE: FIND_OP(module, del); ret = module->ops->del(module, request); break; case LDB_RENAME: FIND_OP(module, rename); ret = module->ops->rename(module, request); break; case LDB_EXTENDED: FIND_OP(module, extended); ret = module->ops->extended(module, request); break; default: FIND_OP(module, request); ret = module->ops->request(module, request); break; } request->handle->nesting--; if (ret == LDB_SUCCESS) { return ret; } if (!ldb_errstring(module->ldb)) { const char *op; switch (request->operation) { case LDB_SEARCH: op = "LDB_SEARCH"; break; case LDB_ADD: op = "LDB_ADD"; break; case LDB_MODIFY: op = "LDB_MODIFY"; break; case LDB_DELETE: op = "LDB_DELETE"; break; case LDB_RENAME: op = "LDB_RENAME"; break; case LDB_EXTENDED: op = "LDB_EXTENDED"; break; default: op = "request"; break; } /* Set a default error string, to place the blame somewhere */ ldb_asprintf_errstring(module->ldb, "error in module %s: %s during %s (%d)", module->ops->name, ldb_strerror(ret), op, ret); } if (!(request->handle->flags & LDB_HANDLE_FLAG_DONE_CALLED)) { /* It is _extremely_ common that a module returns a * failure without calling ldb_module_done(), but that * guarantees we will end up hanging in * ldb_wait(). This fixes it without having to rewrite * all our modules, and leaves us one less sharp * corner for module developers to cut themselves on */ ret = ldb_module_done(request, NULL, NULL, ret); } return ret; } int ldb_next_init(struct ldb_module *module) { module = module->next; return ldb_module_init_chain(module->ldb, module); } int ldb_next_start_trans(struct ldb_module *module) { int ret; FIND_OP(module, start_transaction); ret = module->ops->start_transaction(module); if (ret == LDB_SUCCESS) { return ret; } if (!ldb_errstring(module->ldb)) { /* Set a default error string, to place the blame somewhere */ ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); } if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", ldb_errstring(module->ldb)); } return ret; } int ldb_next_end_trans(struct ldb_module *module) { int ret; FIND_OP(module, end_transaction); ret = module->ops->end_transaction(module); if (ret == LDB_SUCCESS) { return ret; } if (!ldb_errstring(module->ldb)) { /* Set a default error string, to place the blame somewhere */ ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); } if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", ldb_errstring(module->ldb)); } return ret; } int ldb_next_read_lock(struct ldb_module *module) { int ret; FIND_OP(module, read_lock); ret = module->ops->read_lock(module); if (ret == LDB_SUCCESS) { return ret; } if (!ldb_errstring(module->ldb)) { /* Set a default error string, to place the blame somewhere */ ldb_asprintf_errstring(module->ldb, "read_lock error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); } if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_read_lock error: %s", ldb_errstring(module->ldb)); } return ret; } int ldb_next_read_unlock(struct ldb_module *module) { int ret; FIND_OP(module, read_unlock); ret = module->ops->read_unlock(module); if (ret == LDB_SUCCESS) { return ret; } if (!ldb_errstring(module->ldb)) { /* Set a default error string, to place the blame somewhere */ ldb_asprintf_errstring(module->ldb, "read_unlock error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); } if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_read_unlock error: %s", ldb_errstring(module->ldb)); } return ret; } int ldb_next_prepare_commit(struct ldb_module *module) { int ret; FIND_OP_NOERR(module, prepare_commit); if (module == NULL) { /* we are allowed to have no prepare commit in backends */ return LDB_SUCCESS; } ret = module->ops->prepare_commit(module); if (ret == LDB_SUCCESS) { return ret; } if (!ldb_errstring(module->ldb)) { /* Set a default error string, to place the blame somewhere */ ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); } if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", ldb_errstring(module->ldb)); } return ret; } int ldb_next_del_trans(struct ldb_module *module) { int ret; FIND_OP(module, del_transaction); ret = module->ops->del_transaction(module); if (ret == LDB_SUCCESS) { return ret; } if (!ldb_errstring(module->ldb)) { /* Set a default error string, to place the blame somewhere */ ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); } if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", ldb_errstring(module->ldb)); } return ret; } /* calls the request callback to send an entry * * params: * req: the original request passed to your module * msg: reply message (must be a talloc pointer, and it will be stolen * on the ldb_reply that is sent to the callback) * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen * on the ldb_reply that is sent to the callback) */ int ldb_module_send_entry(struct ldb_request *req, struct ldb_message *msg, struct ldb_control **ctrls) { struct ldb_reply *ares; ares = talloc_zero(req, struct ldb_reply); if (!ares) { ldb_oom(req->handle->ldb); req->callback(req, NULL); return LDB_ERR_OPERATIONS_ERROR; } ares->type = LDB_REPLY_ENTRY; ares->message = talloc_steal(ares, msg); ares->controls = talloc_steal(ares, ctrls); ares->error = LDB_SUCCESS; if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && req->handle->nesting == 0) { char *s; struct ldb_ldif ldif; ldif.changetype = LDB_CHANGETYPE_NONE; ldif.msg = discard_const_p(struct ldb_message, msg); ldb_debug_add(req->handle->ldb, "ldb_trace_response: ENTRY\n"); /* * The choice to call * ldb_ldif_write_redacted_trace_string() is CRITICAL * for security. It ensures that we do not output * passwords into debug logs */ s = ldb_ldif_write_redacted_trace_string(req->handle->ldb, msg, &ldif); ldb_debug_add(req->handle->ldb, "%s\n", s); talloc_free(s); ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); } return req->callback(req, ares); } /* calls the request callback to send an referrals * * params: * req: the original request passed to your module * ref: referral string (must be a talloc pointer, steal) */ int ldb_module_send_referral(struct ldb_request *req, char *ref) { struct ldb_reply *ares; ares = talloc_zero(req, struct ldb_reply); if (!ares) { ldb_oom(req->handle->ldb); req->callback(req, NULL); return LDB_ERR_OPERATIONS_ERROR; } ares->type = LDB_REPLY_REFERRAL; ares->referral = talloc_steal(ares, ref); ares->error = LDB_SUCCESS; if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && req->handle->nesting == 0) { ldb_debug_add(req->handle->ldb, "ldb_trace_response: REFERRAL\n"); ldb_debug_add(req->handle->ldb, "ref: %s\n", ref); ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); } return req->callback(req, ares); } /* calls the original request callback * * params: * req: the original request passed to your module * ctrls: controls to send in the reply (must be a talloc pointer, steal) * response: results for extended request (steal) * error: LDB_SUCCESS for a successful return * any other ldb error otherwise */ int ldb_module_done(struct ldb_request *req, struct ldb_control **ctrls, struct ldb_extended *response, int error) { struct ldb_reply *ares; ares = talloc_zero(req, struct ldb_reply); if (!ares) { ldb_oom(req->handle->ldb); req->callback(req, NULL); return LDB_ERR_OPERATIONS_ERROR; } ares->type = LDB_REPLY_DONE; ares->controls = talloc_steal(ares, ctrls); ares->response = talloc_steal(ares, response); ares->error = error; req->handle->flags |= LDB_HANDLE_FLAG_DONE_CALLED; if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && req->handle->nesting == 0) { ldb_debug_add(req->handle->ldb, "ldb_trace_response: DONE\n"); ldb_debug_add(req->handle->ldb, "error: %d\n", error); if (ldb_errstring(req->handle->ldb)) { ldb_debug_add(req->handle->ldb, "msg: %s\n", ldb_errstring(req->handle->ldb)); } ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); } return req->callback(req, ares); } /* to be used *only* in modules init functions. * this function is synchronous and will register * the requested OID in the rootdse module if present * otherwise it will return an error */ int ldb_mod_register_control(struct ldb_module *module, const char *oid) { struct ldb_request *req; int ret; req = talloc_zero(module, struct ldb_request); if (req == NULL) { return LDB_ERR_OPERATIONS_ERROR; } req->operation = LDB_REQ_REGISTER_CONTROL; req->op.reg_control.oid = oid; req->callback = ldb_op_default_callback; ldb_set_timeout(module->ldb, req, 0); req->handle = ldb_handle_new(req, module->ldb); if (req->handle == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_request(module->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } talloc_free(req); return ret; } static int ldb_modules_load_dir(const char *modules_dir, const char *version); /* load one module. A static list of loaded module inode numbers is used to prevent a module being loaded twice dlopen() is used on the module, and dlsym() is then used to look for a ldb_init_module() function. If present, that function is called with the ldb version number as an argument. The ldb_init_module() function will typically call ldb_register_module() and ldb_register_backend() to register a module or backend, but it may also be used to register command line handling functions, ldif handlers or any other local modififications. The ldb_init_module() function does not get a ldb_context passed in, as modules will be used for multiple ldb context handles. The call from the first ldb_init() is just a convenient way to ensure it is called early enough. */ static int ldb_modules_load_path(const char *path, const char *version) { void *handle; int (*init_fn)(const char *); int ret; struct stat st; static struct loaded { struct loaded *next, *prev; ino_t st_ino; dev_t st_dev; } *loaded; struct loaded *le; int dlopen_flags; #ifdef RTLD_DEEPBIND bool deepbind_enabled = (getenv("LDB_MODULES_DISABLE_DEEPBIND") == NULL); #endif ret = stat(path, &st); if (ret != 0) { fprintf(stderr, "ldb: unable to stat module %s : %s\n", path, strerror(errno)); return LDB_ERR_UNAVAILABLE; } for (le=loaded; le; le=le->next) { if (le->st_ino == st.st_ino && le->st_dev == st.st_dev) { /* its already loaded */ return LDB_SUCCESS; } } le = talloc(loaded, struct loaded); if (le == NULL) { fprintf(stderr, "ldb: unable to allocated loaded entry\n"); return LDB_ERR_UNAVAILABLE; } le->st_ino = st.st_ino; le->st_dev = st.st_dev; DLIST_ADD_END(loaded, le); /* if it is a directory, recurse */ if (S_ISDIR(st.st_mode)) { return ldb_modules_load_dir(path, version); } dlopen_flags = RTLD_NOW; #ifdef RTLD_DEEPBIND /* * use deepbind if possible, to avoid issues with different * system library variants, for example ldb modules may be linked * against Heimdal while the application may use MIT kerberos. * * See the dlopen manpage for details. * * One typical user is the bind_dlz module of Samba, * but symbol versioning might be enough... * * We need a way to disable this in order to allow the * ldb_*ldap modules to work with a preloaded socket wrapper. * * So in future we may remove this completely * or at least invert the default behavior. */ if (deepbind_enabled) { dlopen_flags |= RTLD_DEEPBIND; } #endif handle = dlopen(path, dlopen_flags); if (handle == NULL) { fprintf(stderr, "ldb: unable to dlopen %s : %s\n", path, dlerror()); return LDB_SUCCESS; } init_fn = dlsym(handle, "ldb_init_module"); if (init_fn == NULL) { /* ignore it, it could be an old-style * module. Once we've converted all modules we * could consider this an error */ dlclose(handle); return LDB_SUCCESS; } ret = init_fn(version); if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { /* the module is already registered - ignore this, as * it can happen if LDB_MODULES_PATH points at both * the build and install directory */ ret = LDB_SUCCESS; } return ret; } static int qsort_string(const char **s1, const char **s2) { return strcmp(*s1, *s2); } /* load all modules from the given ldb modules directory. This is run once during the first ldb_init() call. Modules are loaded in alphabetical order to ensure that any module load ordering dependencies are reproducible. Modules should avoid relying on load order */ static int ldb_modules_load_dir(const char *modules_dir, const char *version) { DIR *dir; struct dirent *de; const char **modlist = NULL; TALLOC_CTX *tmp_ctx = talloc_new(NULL); unsigned i, num_modules = 0; dir = opendir(modules_dir); if (dir == NULL) { if (errno == ENOENT) { talloc_free(tmp_ctx); /* we don't have any modules */ return LDB_SUCCESS; } talloc_free(tmp_ctx); fprintf(stderr, "ldb: unable to open modules directory '%s' - %s\n", modules_dir, strerror(errno)); return LDB_ERR_UNAVAILABLE; } while ((de = readdir(dir))) { if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) continue; modlist = talloc_realloc(tmp_ctx, modlist, const char *, num_modules+1); if (modlist == NULL) { talloc_free(tmp_ctx); closedir(dir); fprintf(stderr, "ldb: unable to allocate modules list\n"); return LDB_ERR_UNAVAILABLE; } modlist[num_modules] = talloc_asprintf(modlist, "%s/%s", modules_dir, de->d_name); if (modlist[num_modules] == NULL) { talloc_free(tmp_ctx); closedir(dir); fprintf(stderr, "ldb: unable to allocate module list entry\n"); return LDB_ERR_UNAVAILABLE; } num_modules++; } closedir(dir); /* sort the directory, so we get consistent load ordering */ TYPESAFE_QSORT(modlist, num_modules, qsort_string); for (i=0; ihandle) { char *s = talloc_asprintf_append_buffer(ret, "req[%u] %p : %s\n", i++, req, ldb_req_location(req)); if (s == NULL) { talloc_free(ret); return NULL; } ret = s; req = req->handle->parent; } return ret; } /* return the next module in the chain */ struct ldb_module *ldb_module_next(struct ldb_module *module) { return module->next; } /* set the next module in the module chain */ void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next) { module->next = next; } /* get the popt_options pointer in the ldb structure. This allows a ldb module to change the command line parsing */ struct poptOption **ldb_module_popt_options(struct ldb_context *ldb) { return &ldb->popt_options; } /* return the current ldb flags LDB_FLG_* */ uint32_t ldb_module_flags(struct ldb_context *ldb) { return ldb->flags; } ldb-2.0.8/common/ldb_msg.c0000660000000000000000000010137513573675413015306 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldb message component utility functions * * Description: functions for manipulating ldb_message structures * * Author: Andrew Tridgell */ #include "ldb_private.h" /* create a new ldb_message in a given memory context (NULL for top level) */ struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx) { return talloc_zero(mem_ctx, struct ldb_message); } /* find an element in a message by attribute name */ struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, const char *attr_name) { unsigned int i; for (i=0;inum_elements;i++) { if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { return &msg->elements[i]; } } return NULL; } /* see if two ldb_val structures contain exactly the same data return 1 for a match, 0 for a mis-match */ int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2) { if (v1->length != v2->length) return 0; if (v1->data == v2->data) return 1; if (v1->length == 0) return 1; if (memcmp(v1->data, v2->data, v1->length) == 0) { return 1; } return 0; } /* find a value in an element assumes case sensitive comparison */ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, struct ldb_val *val) { unsigned int i; for (i=0;inum_values;i++) { if (ldb_val_equal_exact(val, &el->values[i])) { return &el->values[i]; } } return NULL; } static int ldb_val_cmp(const struct ldb_val *v1, const struct ldb_val *v2) { if (v1->length != v2->length) { return v1->length - v2->length; } return memcmp(v1->data, v2->data, v1->length); } /* ldb_msg_find_duplicate_val() will set the **duplicate pointer to the first duplicate value it finds. It does a case sensitive comparison (memcmp). LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown options flag, otherwise LDB_SUCCESS. */ #define LDB_DUP_QUADRATIC_THRESHOLD 10 int ldb_msg_find_duplicate_val(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message_element *el, struct ldb_val **duplicate, uint32_t options) { unsigned int i, j; struct ldb_val *val; if (options != 0) { return LDB_ERR_OPERATIONS_ERROR; } *duplicate = NULL; /* If there are not many values, it is best to avoid the talloc overhead and just do a brute force search. */ if (el->num_values < LDB_DUP_QUADRATIC_THRESHOLD) { for (j = 0; j < el->num_values; j++) { val = &el->values[j]; for ( i = j + 1; i < el->num_values; i++) { if (ldb_val_equal_exact(val, &el->values[i])) { *duplicate = val; return LDB_SUCCESS; } } } } else { struct ldb_val *values; values = talloc_array(mem_ctx, struct ldb_val, el->num_values); if (values == NULL) { return LDB_ERR_OPERATIONS_ERROR; } memcpy(values, el->values, el->num_values * sizeof(struct ldb_val)); TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); for (i = 1; i < el->num_values; i++) { if (ldb_val_equal_exact(&values[i], &values[i - 1])) { /* find the original location */ for (j = 0; j < el->num_values; j++) { if (ldb_val_equal_exact(&values[i], &el->values[j]) ) { *duplicate = &el->values[j]; break; } } talloc_free(values); if (*duplicate == NULL) { /* how we got here, I don't know */ return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } } talloc_free(values); } return LDB_SUCCESS; } /* Determine whether the values in an element are also in another element. Without any flags, return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS if the elements share values, or LDB_SUCCESS if they don't. In this case, the function simply determines the set intersection and it doesn't matter in which order the elements are provided. With the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, any values in common are removed from the first element and LDB_SUCCESS is returned. LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown option. LDB_ERR_INAPPROPRIATE_MATCHING is returned if the elements differ in name. */ int ldb_msg_find_common_values(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_message_element *el, struct ldb_message_element *el2, uint32_t options) { struct ldb_val *values; struct ldb_val *values2; unsigned int i, j, k, n_values; bool remove_duplicates = options & LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; if ((options & ~LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES) != 0) { return LDB_ERR_OPERATIONS_ERROR; } if (strcmp(el->name, el2->name) != 0) { return LDB_ERR_INAPPROPRIATE_MATCHING; } if (el->num_values == 0 || el2->num_values == 0) { return LDB_SUCCESS; } /* With few values, it is better to do the brute-force search than the clever search involving tallocs, memcpys, sorts, etc. */ if (MIN(el->num_values, el2->num_values) == 1 || MAX(el->num_values, el2->num_values) < LDB_DUP_QUADRATIC_THRESHOLD) { for (i = 0; i < el2->num_values; i++) { for (j = 0; j < el->num_values; j++) { if (ldb_val_equal_exact(&el->values[j], &el2->values[i])) { if (! remove_duplicates) { return \ LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } /* With the remove_duplicates flag, we resolve the intersection by removing the offending one from el. */ el->num_values--; for (k = j; k < el->num_values; k++) { el->values[k] = \ el->values[k + 1]; } j--; /* rewind */ } } } return LDB_SUCCESS; } values = talloc_array(mem_ctx, struct ldb_val, el->num_values); if (values == NULL) { return LDB_ERR_OPERATIONS_ERROR; } values2 = talloc_array(mem_ctx, struct ldb_val, el2->num_values); if (values2 == NULL) { return LDB_ERR_OPERATIONS_ERROR; } memcpy(values, el->values, el->num_values * sizeof(struct ldb_val)); memcpy(values2, el2->values, el2->num_values * sizeof(struct ldb_val)); TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); TYPESAFE_QSORT(values2, el2->num_values, ldb_val_cmp); /* el->n_values may diverge from the number of values in the sorted list when the remove_duplicates flag is used. */ n_values = el->num_values; i = 0; j = 0; while (i != n_values && j < el2->num_values) { int ret = ldb_val_cmp(&values[i], &values2[j]); if (ret < 0) { i++; } else if (ret > 0) { j++; } else { /* we have a collision */ if (! remove_duplicates) { TALLOC_FREE(values); TALLOC_FREE(values2); return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } /* With the remove_duplicates flag we need to find this in the original list and remove it, which is inefficient but hopefully rare. */ for (k = 0; k < el->num_values; k++) { if (ldb_val_equal_exact(&el->values[k], &values[i])) { break; } } el->num_values--; for (; k < el->num_values; k++) { el->values[k] = el->values[k + 1]; } i++; } } TALLOC_FREE(values); TALLOC_FREE(values2); return LDB_SUCCESS; } /* duplicate a ldb_val structure */ struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v) { struct ldb_val v2; v2.length = v->length; if (v->data == NULL) { v2.data = NULL; return v2; } /* the +1 is to cope with buggy C library routines like strndup that look one byte beyond */ v2.data = talloc_array(mem_ctx, uint8_t, v->length+1); if (!v2.data) { v2.length = 0; return v2; } memcpy(v2.data, v->data, v->length); ((char *)v2.data)[v->length] = 0; return v2; } /** * Adds new empty element to msg->elements */ static int _ldb_msg_add_el(struct ldb_message *msg, struct ldb_message_element **return_el) { struct ldb_message_element *els; /* * TODO: Find out a way to assert on input parameters. * msg and return_el must be valid */ els = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements + 1); if (!els) { return LDB_ERR_OPERATIONS_ERROR; } ZERO_STRUCT(els[msg->num_elements]); msg->elements = els; msg->num_elements++; *return_el = &els[msg->num_elements-1]; return LDB_SUCCESS; } /** * Add an empty element with a given name to a message */ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags, struct ldb_message_element **return_el) { int ret; struct ldb_message_element *el; ret = _ldb_msg_add_el(msg, &el); if (ret != LDB_SUCCESS) { return ret; } /* initialize newly added element */ el->flags = flags; el->name = talloc_strdup(msg->elements, attr_name); if (!el->name) { return LDB_ERR_OPERATIONS_ERROR; } if (return_el) { *return_el = el; } return LDB_SUCCESS; } /** * Adds an element to a message. * * NOTE: Ownership of ldb_message_element fields * is NOT transferred. Thus, if *el pointer * is invalidated for some reason, this will * corrupt *msg contents also */ int ldb_msg_add(struct ldb_message *msg, const struct ldb_message_element *el, int flags) { int ret; struct ldb_message_element *el_new; /* We have to copy this, just in case *el is a pointer into * what ldb_msg_add_empty() is about to realloc() */ struct ldb_message_element el_copy = *el; ret = _ldb_msg_add_el(msg, &el_new); if (ret != LDB_SUCCESS) { return ret; } el_new->flags = flags; el_new->name = el_copy.name; el_new->num_values = el_copy.num_values; el_new->values = el_copy.values; return LDB_SUCCESS; } /* add a value to a message */ int ldb_msg_add_value(struct ldb_message *msg, const char *attr_name, const struct ldb_val *val, struct ldb_message_element **return_el) { struct ldb_message_element *el; struct ldb_val *vals; int ret; el = ldb_msg_find_element(msg, attr_name); if (!el) { ret = ldb_msg_add_empty(msg, attr_name, 0, &el); if (ret != LDB_SUCCESS) { return ret; } } vals = talloc_realloc(msg->elements, el->values, struct ldb_val, el->num_values+1); if (!vals) { return LDB_ERR_OPERATIONS_ERROR; } el->values = vals; el->values[el->num_values] = *val; el->num_values++; if (return_el) { *return_el = el; } return LDB_SUCCESS; } /* add a value to a message, stealing it into the 'right' place */ int ldb_msg_add_steal_value(struct ldb_message *msg, const char *attr_name, struct ldb_val *val) { int ret; struct ldb_message_element *el; ret = ldb_msg_add_value(msg, attr_name, val, &el); if (ret == LDB_SUCCESS) { talloc_steal(el->values, val->data); } return ret; } /* add a string element to a message */ int ldb_msg_add_string(struct ldb_message *msg, const char *attr_name, const char *str) { struct ldb_val val; val.data = discard_const_p(uint8_t, str); val.length = strlen(str); if (val.length == 0) { /* allow empty strings as non-existent attributes */ return LDB_SUCCESS; } return ldb_msg_add_value(msg, attr_name, &val, NULL); } /* add a string element to a message, stealing it into the 'right' place */ int ldb_msg_add_steal_string(struct ldb_message *msg, const char *attr_name, char *str) { struct ldb_val val; val.data = (uint8_t *)str; val.length = strlen(str); if (val.length == 0) { /* allow empty strings as non-existent attributes */ return LDB_SUCCESS; } return ldb_msg_add_steal_value(msg, attr_name, &val); } /* add a DN element to a message WARNING: this uses the linearized string from the dn, and does not copy the string. */ int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, struct ldb_dn *dn) { char *str = ldb_dn_alloc_linearized(msg, dn); if (str == NULL) { /* we don't want to have unknown DNs added */ return LDB_ERR_OPERATIONS_ERROR; } return ldb_msg_add_steal_string(msg, attr_name, str); } /* add a printf formatted element to a message */ int ldb_msg_add_fmt(struct ldb_message *msg, const char *attr_name, const char *fmt, ...) { struct ldb_val val; va_list ap; char *str; va_start(ap, fmt); str = talloc_vasprintf(msg, fmt, ap); va_end(ap); if (str == NULL) return LDB_ERR_OPERATIONS_ERROR; val.data = (uint8_t *)str; val.length = strlen(str); return ldb_msg_add_steal_value(msg, attr_name, &val); } /* compare two ldb_message_element structures assumes case sensitive comparison */ int ldb_msg_element_compare(struct ldb_message_element *el1, struct ldb_message_element *el2) { unsigned int i; if (el1->num_values != el2->num_values) { return el1->num_values - el2->num_values; } for (i=0;inum_values;i++) { if (!ldb_msg_find_val(el2, &el1->values[i])) { return -1; } } return 0; } /* compare two ldb_message_element structures. Different ordering is considered a mismatch */ bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1, const struct ldb_message_element *el2) { unsigned i; if (el1->num_values != el2->num_values) { return false; } for (i=0;inum_values;i++) { if (ldb_val_equal_exact(&el1->values[i], &el2->values[i]) != 1) { return false; } } return true; } /* compare two ldb_message_element structures comparing by element name */ int ldb_msg_element_compare_name(struct ldb_message_element *el1, struct ldb_message_element *el2) { return ldb_attr_cmp(el1->name, el2->name); } /* convenience functions to return common types from a message these return the first value if the attribute is multi-valued */ const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name) { struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); if (!el || el->num_values == 0) { return NULL; } return &el->values[0]; } int ldb_msg_find_attr_as_int(const struct ldb_message *msg, const char *attr_name, int default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); char buf[sizeof("-2147483648")]; char *end = NULL; int ret; if (!v || !v->data) { return default_value; } ZERO_STRUCT(buf); if (v->length >= sizeof(buf)) { return default_value; } memcpy(buf, v->data, v->length); errno = 0; ret = (int) strtoll(buf, &end, 10); if (errno != 0) { return default_value; } if (end && end[0] != '\0') { return default_value; } return ret; } unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, const char *attr_name, unsigned int default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); char buf[sizeof("-2147483648")]; char *end = NULL; unsigned int ret; if (!v || !v->data) { return default_value; } ZERO_STRUCT(buf); if (v->length >= sizeof(buf)) { return default_value; } memcpy(buf, v->data, v->length); errno = 0; ret = (unsigned int) strtoll(buf, &end, 10); if (errno != 0) { errno = 0; ret = (unsigned int) strtoull(buf, &end, 10); if (errno != 0) { return default_value; } } if (end && end[0] != '\0') { return default_value; } return ret; } int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, const char *attr_name, int64_t default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); char buf[sizeof("-9223372036854775808")]; char *end = NULL; int64_t ret; if (!v || !v->data) { return default_value; } ZERO_STRUCT(buf); if (v->length >= sizeof(buf)) { return default_value; } memcpy(buf, v->data, v->length); errno = 0; ret = (int64_t) strtoll(buf, &end, 10); if (errno != 0) { return default_value; } if (end && end[0] != '\0') { return default_value; } return ret; } uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, const char *attr_name, uint64_t default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); char buf[sizeof("-9223372036854775808")]; char *end = NULL; uint64_t ret; if (!v || !v->data) { return default_value; } ZERO_STRUCT(buf); if (v->length >= sizeof(buf)) { return default_value; } memcpy(buf, v->data, v->length); errno = 0; ret = (uint64_t) strtoll(buf, &end, 10); if (errno != 0) { errno = 0; ret = (uint64_t) strtoull(buf, &end, 10); if (errno != 0) { return default_value; } } if (end && end[0] != '\0') { return default_value; } return ret; } double ldb_msg_find_attr_as_double(const struct ldb_message *msg, const char *attr_name, double default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); char *buf; char *end = NULL; double ret; if (!v || !v->data) { return default_value; } buf = talloc_strndup(msg, (const char *)v->data, v->length); if (buf == NULL) { return default_value; } errno = 0; ret = strtod(buf, &end); talloc_free(buf); if (errno != 0) { return default_value; } if (end && end[0] != '\0') { return default_value; } return ret; } int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, const char *attr_name, int default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); if (!v || !v->data) { return default_value; } if (v->length == 5 && strncasecmp((const char *)v->data, "FALSE", 5) == 0) { return 0; } if (v->length == 4 && strncasecmp((const char *)v->data, "TRUE", 4) == 0) { return 1; } return default_value; } const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, const char *attr_name, const char *default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); if (!v || !v->data) { return default_value; } if (v->data[v->length] != '\0') { return default_value; } return (const char *)v->data; } struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg, const char *attr_name) { struct ldb_dn *res_dn; const struct ldb_val *v; v = ldb_msg_find_ldb_val(msg, attr_name); if (!v || !v->data) { return NULL; } res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v); if ( ! ldb_dn_validate(res_dn)) { talloc_free(res_dn); return NULL; } return res_dn; } /* sort the elements of a message by name */ void ldb_msg_sort_elements(struct ldb_message *msg) { TYPESAFE_QSORT(msg->elements, msg->num_elements, ldb_msg_element_compare_name); } /* shallow copy a message - copying only the elements array so that the caller can safely add new elements without changing the message */ struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, const struct ldb_message *msg) { struct ldb_message *msg2; unsigned int i; msg2 = talloc(mem_ctx, struct ldb_message); if (msg2 == NULL) return NULL; *msg2 = *msg; msg2->elements = talloc_array(msg2, struct ldb_message_element, msg2->num_elements); if (msg2->elements == NULL) goto failed; for (i=0;inum_elements;i++) { msg2->elements[i] = msg->elements[i]; } return msg2; failed: talloc_free(msg2); return NULL; } /* copy a message, allocating new memory for all parts */ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, const struct ldb_message *msg) { struct ldb_message *msg2; unsigned int i, j; msg2 = ldb_msg_copy_shallow(mem_ctx, msg); if (msg2 == NULL) return NULL; msg2->dn = ldb_dn_copy(msg2, msg2->dn); if (msg2->dn == NULL) goto failed; for (i=0;inum_elements;i++) { struct ldb_message_element *el = &msg2->elements[i]; struct ldb_val *values = el->values; el->name = talloc_strdup(msg2->elements, el->name); if (el->name == NULL) goto failed; el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); if (el->values == NULL) goto failed; for (j=0;jnum_values;j++) { el->values[j] = ldb_val_dup(el->values, &values[j]); if (el->values[j].data == NULL && values[j].length != 0) { goto failed; } } } return msg2; failed: talloc_free(msg2); return NULL; } /** * Canonicalize a message, merging elements of the same name */ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, const struct ldb_message *msg) { int ret; struct ldb_message *msg2; /* * Preserve previous behavior and allocate * *msg2 into *ldb context */ ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); if (ret != LDB_SUCCESS) { return NULL; } return msg2; } /** * Canonicalize a message, merging elements of the same name */ int ldb_msg_normalize(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg, struct ldb_message **_msg_out) { unsigned int i; struct ldb_message *msg2; msg2 = ldb_msg_copy(mem_ctx, msg); if (msg2 == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ldb_msg_sort_elements(msg2); for (i=1; i < msg2->num_elements; i++) { struct ldb_message_element *el1 = &msg2->elements[i-1]; struct ldb_message_element *el2 = &msg2->elements[i]; if (ldb_msg_element_compare_name(el1, el2) == 0) { el1->values = talloc_realloc(msg2->elements, el1->values, struct ldb_val, el1->num_values + el2->num_values); if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { talloc_free(msg2); return LDB_ERR_OPERATIONS_ERROR; } memcpy(el1->values + el1->num_values, el2->values, sizeof(struct ldb_val) * el2->num_values); el1->num_values += el2->num_values; talloc_free(discard_const_p(char, el2->name)); if ((i+1) < msg2->num_elements) { memmove(el2, el2+1, sizeof(struct ldb_message_element) * (msg2->num_elements - (i+1))); } msg2->num_elements--; i--; } } *_msg_out = msg2; return LDB_SUCCESS; } /** * return a ldb_message representing the differences between msg1 and msg2. * If you then use this in a ldb_modify() call, * it can be used to save edits to a message */ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, struct ldb_message *msg1, struct ldb_message *msg2) { int ldb_ret; struct ldb_message *mod; ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); if (ldb_ret != LDB_SUCCESS) { return NULL; } return mod; } /** * return a ldb_message representing the differences between msg1 and msg2. * If you then use this in a ldb_modify() call it can be used to save edits to a message * * Result message is constructed as follows: * - LDB_FLAG_MOD_ADD - elements found only in msg2 * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 * Value for msg2 element is used * - LDB_FLAG_MOD_DELETE - elements found only in msg2 * * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR */ int ldb_msg_difference(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg1, struct ldb_message *msg2, struct ldb_message **_msg_out) { int ldb_res; unsigned int i; struct ldb_message *mod; struct ldb_message_element *el; TALLOC_CTX *temp_ctx; temp_ctx = talloc_new(mem_ctx); if (!temp_ctx) { return LDB_ERR_OPERATIONS_ERROR; } mod = ldb_msg_new(temp_ctx); if (mod == NULL) { goto failed; } mod->dn = msg1->dn; mod->num_elements = 0; mod->elements = NULL; /* * Canonicalize *msg2 so we have no repeated elements * Resulting message is allocated in *mod's mem context, * as we are going to move some elements from *msg2 to * *mod object later */ ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2); if (ldb_res != LDB_SUCCESS) { goto failed; } /* look in msg2 to find elements that need to be added or modified */ for (i=0;inum_elements;i++) { el = ldb_msg_find_element(msg1, msg2->elements[i].name); if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { continue; } ldb_res = ldb_msg_add(mod, &msg2->elements[i], el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); if (ldb_res != LDB_SUCCESS) { goto failed; } } /* look in msg1 to find elements that need to be deleted */ for (i=0;inum_elements;i++) { el = ldb_msg_find_element(msg2, msg1->elements[i].name); if (el == NULL) { ldb_res = ldb_msg_add_empty(mod, msg1->elements[i].name, LDB_FLAG_MOD_DELETE, NULL); if (ldb_res != LDB_SUCCESS) { goto failed; } } } /* steal resulting message into supplied context */ talloc_steal(mem_ctx, mod); *_msg_out = mod; talloc_free(temp_ctx); return LDB_SUCCESS; failed: talloc_free(temp_ctx); return LDB_ERR_OPERATIONS_ERROR; } int ldb_msg_sanity_check(struct ldb_context *ldb, const struct ldb_message *msg) { unsigned int i, j; /* basic check on DN */ if (msg->dn == NULL) { ldb_set_errstring(ldb, "ldb message lacks a DN!"); return LDB_ERR_INVALID_DN_SYNTAX; } /* basic syntax checks */ for (i = 0; i < msg->num_elements; i++) { for (j = 0; j < msg->elements[i].num_values; j++) { if (msg->elements[i].values[j].length == 0) { /* an attribute cannot be empty */ ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", msg->elements[i].name, ldb_dn_get_linearized(msg->dn)); return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } } } return LDB_SUCCESS; } /* copy an attribute list. This only copies the array, not the elements (ie. the elements are left as the same pointers) */ const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) { const char **ret; unsigned int i; for (i=0;attrs && attrs[i];i++) /* noop */ ; ret = talloc_array(mem_ctx, const char *, i+1); if (ret == NULL) { return NULL; } for (i=0;attrs && attrs[i];i++) { ret[i] = attrs[i]; } ret[i] = attrs[i]; return ret; } /* copy an attribute list. This only copies the array, not the elements (ie. the elements are left as the same pointers). The new attribute is added to the list. */ const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) { const char **ret; unsigned int i; bool found = false; for (i=0;attrs && attrs[i];i++) { if (ldb_attr_cmp(attrs[i], new_attr) == 0) { found = true; } } if (found) { return ldb_attr_list_copy(mem_ctx, attrs); } ret = talloc_array(mem_ctx, const char *, i+2); if (ret == NULL) { return NULL; } for (i=0;attrs && attrs[i];i++) { ret[i] = attrs[i]; } ret[i] = new_attr; ret[i+1] = NULL; return ret; } /* return 1 if an attribute is in a list of attributes, or 0 otherwise */ int ldb_attr_in_list(const char * const *attrs, const char *attr) { unsigned int i; for (i=0;attrs && attrs[i];i++) { if (ldb_attr_cmp(attrs[i], attr) == 0) { return 1; } } return 0; } /* rename the specified attribute in a search result */ int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace) { struct ldb_message_element *el = ldb_msg_find_element(msg, attr); if (el == NULL) { return LDB_SUCCESS; } el->name = talloc_strdup(msg->elements, replace); if (el->name == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } /* copy the specified attribute in a search result to a new attribute */ int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace) { struct ldb_message_element *el = ldb_msg_find_element(msg, attr); int ret; if (el == NULL) { return LDB_SUCCESS; } ret = ldb_msg_add(msg, el, 0); if (ret != LDB_SUCCESS) { return ret; } return ldb_msg_rename_attr(msg, attr, replace); } /* remove the specified element in a search result */ void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) { ptrdiff_t n = (el - msg->elements); if (n >= msg->num_elements || n < 0) { /* the element is not in the list. the caller is crazy. */ return; } msg->num_elements--; if (n != msg->num_elements) { memmove(el, el+1, (msg->num_elements - n)*sizeof(*el)); } } /* remove the specified attribute in a search result */ void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) { struct ldb_message_element *el; while ((el = ldb_msg_find_element(msg, attr)) != NULL) { ldb_msg_remove_element(msg, el); } } /* return a LDAP formatted GeneralizedTime string */ char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) { struct tm *tm = gmtime(&t); char *ts; int r; if (!tm) { return NULL; } /* we now excatly how long this string will be */ ts = talloc_array(mem_ctx, char, 18); /* formatted like: 20040408072012.0Z */ r = snprintf(ts, 18, "%04u%02u%02u%02u%02u%02u.0Z", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); if (r != 17) { talloc_free(ts); return NULL; } return ts; } /* convert a LDAP GeneralizedTime string to a time_t. Return 0 if unable to convert */ time_t ldb_string_to_time(const char *s) { struct tm tm; if (s == NULL) return 0; memset(&tm, 0, sizeof(tm)); if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { return 0; } tm.tm_year -= 1900; tm.tm_mon -= 1; return timegm(&tm); } /* convert a LDAP GeneralizedTime string in ldb_val format to a time_t. */ int ldb_val_to_time(const struct ldb_val *v, time_t *t) { char val[15] = {0}; struct tm tm = { .tm_year = 0, }; if (v == NULL) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } if (v->data == NULL) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } if (v->length < 16 && v->length != 13) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } if (v->data[v->length - 1] != 'Z') { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } if (v->length == 13) { memcpy(val, v->data, 12); if (sscanf(val, "%02u%02u%02u%02u%02u%02u", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } if (tm.tm_year < 50) { tm.tm_year += 100; } } else { /* * anything between '.' and 'Z' is silently ignored. */ if (v->data[14] != '.') { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } memcpy(val, v->data, 14); if (sscanf(val, "%04u%02u%02u%02u%02u%02u", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } tm.tm_year -= 1900; } tm.tm_mon -= 1; *t = timegm(&tm); return LDB_SUCCESS; } /* return a LDAP formatted UTCTime string */ char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t) { struct tm *tm = gmtime(&t); char *ts; int r; if (!tm) { return NULL; } /* we now excatly how long this string will be */ ts = talloc_array(mem_ctx, char, 14); /* formatted like: 20040408072012.0Z => 040408072012Z */ r = snprintf(ts, 14, "%02u%02u%02u%02u%02u%02uZ", (tm->tm_year+1900)%100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); if (r != 13) { talloc_free(ts); return NULL; } return ts; } /* convert a LDAP UTCTime string to a time_t. Return 0 if unable to convert */ time_t ldb_string_utc_to_time(const char *s) { struct tm tm; if (s == NULL) return 0; memset(&tm, 0, sizeof(tm)); if (sscanf(s, "%02u%02u%02u%02u%02u%02uZ", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { return 0; } if (tm.tm_year < 50) { tm.tm_year += 100; } tm.tm_mon -= 1; return timegm(&tm); } /* dump a set of results to a file. Useful from within gdb */ void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) { unsigned int i; for (i = 0; i < result->count; i++) { struct ldb_ldif ldif; fprintf(f, "# record %d\n", i+1); ldif.changetype = LDB_CHANGETYPE_NONE; ldif.msg = result->msgs[i]; ldb_ldif_write_file(ldb, f, &ldif); } } /* checks for a string attribute. Returns "1" on match and otherwise "0". */ int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value) { struct ldb_message_element *el; struct ldb_val val; el = ldb_msg_find_element(msg, name); if (el == NULL) { return 0; } val.data = discard_const_p(uint8_t, value); val.length = strlen(value); if (ldb_msg_find_val(el, &val)) { return 1; } return 0; } /* compare a ldb_val to a string */ int ldb_val_string_cmp(const struct ldb_val *v, const char *str) { size_t len = strlen(str); if (len != v->length) { return len - v->length; } return strncmp((const char *)v->data, str, len); } ldb-2.0.8/common/ldb_options.c0000660000000000000000000000447713573675413016220 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 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 . */ /* * Name: ldb * * Component: ldb options[] handling * * Author: Andrew Tridgell */ #include "ldb_private.h" /* find an option within an options array accepts the following forms: NAME NAME:value NAME=value returns a pointer into an element of the options[] array, or NULL is not found. For the NAME form, returns a pointer to an empty string (thus allowing for boolean options). */ const char *ldb_options_find(struct ldb_context *ldb, const char *options[], const char *option_name) { size_t len = strlen(option_name); int i; if (options == NULL) { return NULL; } for (i=0; options[i]; i++) { if (strncmp(option_name, options[i], len) != 0) { continue; } if (options[i][len] == ':' || options[i][len] == '=') { return &options[i][len+1]; } if (options[i][len] == 0) { return &options[i][len]; } } return NULL; } const char **ldb_options_copy(TALLOC_CTX *ctx, const char *options[]) { size_t num_options = 0; const char **copy = NULL; size_t i = 0; if (options == NULL) { return copy; } for (i=0; options[i]; i++) { num_options++; } copy = talloc_zero_array(ctx, const char *, num_options + 1); if (copy == NULL) { return copy; } for (i=0; options[i]; i++) { copy[i] = talloc_strdup(copy, options[i]); if (copy[i] == NULL) { TALLOC_FREE(copy); return copy; } } return copy; } const char **ldb_options_get(struct ldb_context *ldb) { return ldb->options; } ldb-2.0.8/common/ldb_pack.c0000660000000000000000000007525413573675413015444 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldb pack/unpack * * Description: pack/unpack routines for ldb messages as key/value blobs * * Author: Andrew Tridgell */ #include "ldb_private.h" /* * These macros are from byte_array.h via libssh * TODO: This will be replaced with use of the byte_array.h header when it * becomes available. * * Macros for handling integer types in byte arrays * * This file is originally from the libssh.org project * * Copyright (c) 2018 Andreas Schneider * * 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 2.1 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _DATA_BYTE_CONST(data, pos) \ ((uint8_t)(((const uint8_t *)(data))[(pos)])) #define PULL_LE_U8(data, pos) \ (_DATA_BYTE_CONST(data, pos)) #define PULL_LE_U16(data, pos) \ ((uint16_t)PULL_LE_U8(data, pos) |\ ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8) #define PULL_LE_U32(data, pos) \ ((uint32_t)(PULL_LE_U16(data, pos) |\ ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16)) #define _DATA_BYTE(data, pos) \ (((uint8_t *)(data))[(pos)]) #define PUSH_LE_U8(data, pos, val) \ (_DATA_BYTE(data, pos) = ((uint8_t)(val))) #define PUSH_LE_U16(data, pos, val) \ (PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)),\ PUSH_LE_U8((data), (pos) + 1,\ (uint8_t)((uint16_t)(val) >> 8))) #define PUSH_LE_U32(data, pos, val) \ (PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)),\ PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16))) #define U32_LEN 4 #define U16_LEN 2 #define U8_LEN 1 #define NULL_PAD_BYTE_LEN 1 static int attribute_storable_values(const struct ldb_message_element *el) { if (el->num_values == 0) return 0; if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; return el->num_values; } static int ldb_pack_data_v1(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_val *data) { unsigned int i, j, real_elements=0; size_t size, dn_len, attr_len, value_len; const char *dn; uint8_t *p; size_t len; dn = ldb_dn_get_linearized(message->dn); if (dn == NULL) { errno = ENOMEM; return -1; } /* work out how big it needs to be */ size = U32_LEN * 2 + NULL_PAD_BYTE_LEN; dn_len = strlen(dn); if (size + dn_len < size) { errno = ENOMEM; return -1; } size += dn_len; /* * First calcuate the buffer size we need, and check for * overflows */ for (i=0;inum_elements;i++) { if (attribute_storable_values(&message->elements[i]) == 0) { continue; } real_elements++; if (size + U32_LEN + NULL_PAD_BYTE_LEN < size) { errno = ENOMEM; return -1; } size += U32_LEN + NULL_PAD_BYTE_LEN; attr_len = strlen(message->elements[i].name); if (size + attr_len < size) { errno = ENOMEM; return -1; } size += attr_len; for (j=0;jelements[i].num_values;j++) { if (size + U32_LEN + NULL_PAD_BYTE_LEN < size) { errno = ENOMEM; return -1; } size += U32_LEN + NULL_PAD_BYTE_LEN; value_len = message->elements[i].values[j].length; if (size + value_len < size) { errno = ENOMEM; return -1; } size += value_len; } } /* allocate it */ data->data = talloc_array(ldb, uint8_t, size); if (!data->data) { errno = ENOMEM; return -1; } data->length = size; p = data->data; PUSH_LE_U32(p, 0, LDB_PACKING_FORMAT); p += U32_LEN; PUSH_LE_U32(p, 0, real_elements); p += U32_LEN; /* the dn needs to be packed so we can be case preserving while hashing on a case folded dn */ len = dn_len; memcpy(p, dn, len+NULL_PAD_BYTE_LEN); p += len + NULL_PAD_BYTE_LEN; for (i=0;inum_elements;i++) { if (attribute_storable_values(&message->elements[i]) == 0) { continue; } len = strlen(message->elements[i].name); memcpy(p, message->elements[i].name, len+NULL_PAD_BYTE_LEN); p += len + NULL_PAD_BYTE_LEN; PUSH_LE_U32(p, 0, message->elements[i].num_values); p += U32_LEN; for (j=0;jelements[i].num_values;j++) { PUSH_LE_U32(p, 0, message->elements[i].values[j].length); p += U32_LEN; memcpy(p, message->elements[i].values[j].data, message->elements[i].values[j].length); p[message->elements[i].values[j].length] = 0; p += message->elements[i].values[j].length + NULL_PAD_BYTE_LEN; } } return 0; } /* * New pack version designed based on performance profiling of version 1. * The approach is to separate value data from the rest of the record's data. * This improves performance because value data is not needed during unpacking * or filtering of the message's attribute list. During filtering we only copy * attributes which are present in the attribute list, however at the parse * stage we need to point to all attributes as they may be referenced in the * search expression. * With this new format, we don't lose time loading data (eg via * talloc_memdup()) that is never needed (for the vast majority of attributes * are are never found in either the search expression or attribute list). * Additional changes include adding a canonicalized DN (for later * optimizations) and variable width length fields for faster unpacking. * The pack and unpack performance improvement is tested in the torture * test torture_ldb_pack_format_perf. * * Layout: * * Version (4 bytes) * Number of Elements (4 bytes) * DN length (4 bytes) * DN with null terminator (DN length + 1 bytes) * Canonicalized DN length (4 bytes) * Canonicalized DN with null terminator (Canonicalized DN length + 1 bytes) * Number of bytes from here to value data section (4 bytes) * # For each element: * Element name length (4 bytes) * Element name with null terminator (Element name length + 1 bytes) * Number of values (4 bytes) * Width of value lengths * # For each value: * Value data length (#bytes given by width field above) * # For each element: * # For each value: * Value data (#bytes given by corresponding length above) */ static int ldb_pack_data_v2(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_val *data) { unsigned int i, j, real_elements=0; size_t size, dn_len, dn_canon_len, attr_len, value_len; const char *dn, *dn_canon; uint8_t *p, *q; size_t len; size_t max_val_len; uint8_t val_len_width; /* * First half of this function will calculate required size for * packed data. Initial size is 20 = 5 * 4. 5 fixed fields are: * version, num elements, dn len, canon dn len, attr section len */ size = U32_LEN * 5; /* * Get linearized and canonicalized form of the DN and add the lengths * of each to size, plus 1 for null terminator. */ dn = ldb_dn_get_linearized(message->dn); if (dn == NULL) { errno = ENOMEM; return -1; } dn_len = strlen(dn) + NULL_PAD_BYTE_LEN; if (size + dn_len < size) { errno = ENOMEM; return -1; } size += dn_len; if (ldb_dn_is_special(message->dn)) { dn_canon_len = NULL_PAD_BYTE_LEN; dn_canon = discard_const_p(char, "\0"); } else { dn_canon = ldb_dn_canonical_string(message->dn, message->dn); if (dn_canon == NULL) { errno = ENOMEM; return -1; } dn_canon_len = strlen(dn_canon) + NULL_PAD_BYTE_LEN; if (size + dn_canon_len < size) { errno = ENOMEM; return -1; } } size += dn_canon_len; /* Add the size required by each element */ for (i=0;inum_elements;i++) { if (attribute_storable_values(&message->elements[i]) == 0) { continue; } real_elements++; /* * Add length of element name + 9 for: * 1 for null terminator * 4 for element name length field * 4 for number of values field */ attr_len = strlen(message->elements[i].name); if (size + attr_len + U32_LEN * 2 + NULL_PAD_BYTE_LEN < size) { errno = ENOMEM; return -1; } size += attr_len + U32_LEN * 2 + NULL_PAD_BYTE_LEN; /* * Find the max value length, so we can calculate the width * required for the value length fields. */ max_val_len = 0; for (j=0;jelements[i].num_values;j++) { value_len = message->elements[i].values[j].length; if (value_len > max_val_len) { max_val_len = value_len; } if (size + value_len + NULL_PAD_BYTE_LEN < size) { errno = ENOMEM; return -1; } size += value_len + NULL_PAD_BYTE_LEN; } if (max_val_len <= UCHAR_MAX) { val_len_width = U8_LEN; } else if (max_val_len <= USHRT_MAX) { val_len_width = U16_LEN; } else if (max_val_len <= UINT_MAX) { val_len_width = U32_LEN; } else { errno = EMSGSIZE; return -1; } /* Total size required for val lengths (re-using variable) */ max_val_len = (val_len_width*message->elements[i].num_values); /* Add one for storing the width */ max_val_len += U8_LEN; if (size + max_val_len < size) { errno = ENOMEM; return -1; } size += max_val_len; } /* Allocate */ data->data = talloc_array(ldb, uint8_t, size); if (!data->data) { errno = ENOMEM; return -1; } data->length = size; /* Packing format version and number of element */ p = data->data; PUSH_LE_U32(p, 0, LDB_PACKING_FORMAT_V2); p += U32_LEN; PUSH_LE_U32(p, 0, real_elements); p += U32_LEN; /* Pack DN and Canonicalized DN */ PUSH_LE_U32(p, 0, dn_len-NULL_PAD_BYTE_LEN); p += U32_LEN; memcpy(p, dn, dn_len); p += dn_len; PUSH_LE_U32(p, 0, dn_canon_len-NULL_PAD_BYTE_LEN); p += U32_LEN; memcpy(p, dn_canon, dn_canon_len); p += dn_canon_len; /* * Save pointer at this point and leave a U32_LEN gap for * storing the size of the attribute names and value lengths * section */ q = p; p += U32_LEN; for (i=0;inum_elements;i++) { if (attribute_storable_values(&message->elements[i]) == 0) { continue; } /* Length of el name */ len = strlen(message->elements[i].name); PUSH_LE_U32(p, 0, len); p += U32_LEN; /* * Even though we have the element name's length, put a null * terminator at the end so if any code uses the name * directly, it'll be safe to do things requiring null * termination like strlen */ memcpy(p, message->elements[i].name, len+NULL_PAD_BYTE_LEN); p += len + NULL_PAD_BYTE_LEN; /* Num values */ PUSH_LE_U32(p, 0, message->elements[i].num_values); p += U32_LEN; /* * Calculate value length width again. It's faster to * calculate it again than do the array management to * store the result during size calculation. */ max_val_len = 0; for (j=0;jelements[i].num_values;j++) { value_len = message->elements[i].values[j].length; if (value_len > max_val_len) { max_val_len = value_len; } } if (max_val_len <= UCHAR_MAX) { val_len_width = U8_LEN; } else if (max_val_len <= USHRT_MAX) { val_len_width = U16_LEN; } else if (max_val_len <= UINT_MAX) { val_len_width = U32_LEN; } else { errno = EMSGSIZE; return -1; } /* Pack the width */ *p = val_len_width & 0xFF; p += U8_LEN; /* * Pack each value's length using the minimum number of bytes * required, which we just calculated. We repeat the loop * for each case here so the compiler can inline code. */ if (val_len_width == U8_LEN) { for (j=0;jelements[i].num_values;j++) { PUSH_LE_U8(p, 0, message->elements[i].values[j].length); p += U8_LEN; } } else if (val_len_width == U16_LEN) { for (j=0;jelements[i].num_values;j++) { PUSH_LE_U16(p, 0, message->elements[i].values[j].length); p += U16_LEN; } } else if (val_len_width == U32_LEN) { for (j=0;jelements[i].num_values;j++) { PUSH_LE_U32(p, 0, message->elements[i].values[j].length); p += U32_LEN; } } } /* * We've finished packing the attr names and value lengths * section, so store the size in the U32_LEN gap we left * earlier */ PUSH_LE_U32(q, 0, p-q); /* Now pack the values */ for (i=0;inum_elements;i++) { if (attribute_storable_values(&message->elements[i]) == 0) { continue; } for (j=0;jelements[i].num_values;j++) { memcpy(p, message->elements[i].values[j].data, message->elements[i].values[j].length); /* * Even though we have the data length, put a null * terminator at the end of each value's data so if * any code uses the data directly, it'll be safe to * do things requiring null termination like strlen. */ p[message->elements[i].values[j].length] = 0; p += message->elements[i].values[j].length + NULL_PAD_BYTE_LEN; } } /* * If we didn't end up at the end of the data here, something has * gone very wrong. */ if (p != data->data + size) { errno = ENOMEM; return -1; } return 0; } /* pack a ldb message into a linear buffer in a ldb_val note that this routine avoids saving elements with zero values, as these are equivalent to having no element caller frees the data buffer after use */ int ldb_pack_data(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_val *data, uint32_t pack_format_version) { if (pack_format_version == LDB_PACKING_FORMAT) { return ldb_pack_data_v1(ldb, message, data); } else if (pack_format_version == LDB_PACKING_FORMAT_V2) { return ldb_pack_data_v2(ldb, message, data); } else { errno = EINVAL; return -1; } } /* * Unpack a ldb message from a linear buffer in ldb_val */ static int ldb_unpack_data_flags_v1(struct ldb_context *ldb, const struct ldb_val *data, struct ldb_message *message, unsigned int flags, unsigned format) { uint8_t *p; size_t remaining; size_t dn_len; unsigned int i, j; unsigned int nelem = 0; size_t len; struct ldb_val *ldb_val_single_array = NULL; message->elements = NULL; p = data->data; /* Format (U32, already read) + U32 for num_elements */ if (data->length < U32_LEN * 2) { errno = EIO; goto failed; } /* Skip first 4 bytes, format already read */ p += U32_LEN; message->num_elements = PULL_LE_U32(p, 0); p += U32_LEN; remaining = data->length - U32_LEN * 2; switch (format) { case LDB_PACKING_FORMAT_NODN: message->dn = NULL; break; case LDB_PACKING_FORMAT: /* * With this check, we know that the DN at p is \0 * terminated. */ dn_len = strnlen((char *)p, remaining); if (dn_len == remaining) { errno = EIO; goto failed; } if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) { message->dn = NULL; } else { struct ldb_val blob; blob.data = discard_const_p(uint8_t, p); blob.length = dn_len; message->dn = ldb_dn_from_ldb_val(message, ldb, &blob); if (message->dn == NULL) { errno = ENOMEM; goto failed; } } /* * Redundant: by definition, remaining must be more * than one less than dn_len, as otherwise it would be * == dn_len */ if (remaining < dn_len + NULL_PAD_BYTE_LEN) { errno = EIO; goto failed; } remaining -= dn_len + NULL_PAD_BYTE_LEN; p += dn_len + NULL_PAD_BYTE_LEN; break; default: errno = EIO; goto failed; } if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) { return 0; } if (message->num_elements == 0) { return 0; } if (message->num_elements > remaining / 6) { errno = EIO; goto failed; } message->elements = talloc_zero_array(message, struct ldb_message_element, message->num_elements); if (!message->elements) { errno = ENOMEM; goto failed; } /* * In typical use, most values are single-valued. This makes * it quite expensive to allocate an array of ldb_val for each * of these, just to then hold the pointer to the data buffer * So with LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this * ahead of time and use it for the single values where possible. * (This is used the the normal search case, but not in the * index case because of caller requirements). */ if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) { ldb_val_single_array = talloc_array(message->elements, struct ldb_val, message->num_elements); if (ldb_val_single_array == NULL) { errno = ENOMEM; goto failed; } } for (i=0;inum_elements;i++) { const char *attr = NULL; size_t attr_len; struct ldb_message_element *element = NULL; /* * Sanity check: Element must be at least the size of empty * attr name and value and NULL terms for each. */ if (remaining < U32_LEN * 2 + NULL_PAD_BYTE_LEN * 2) { errno = EIO; goto failed; } /* * With this check, we know that the attribute name at * p is \0 terminated. */ attr_len = strnlen((char *)p, remaining-6); if (attr_len == remaining-6) { errno = EIO; goto failed; } if (attr_len == 0) { errno = EIO; goto failed; } attr = (char *)p; element = &message->elements[nelem]; element->name = attr; element->flags = 0; if (remaining < (attr_len + NULL_PAD_BYTE_LEN)) { errno = EIO; goto failed; } remaining -= attr_len + NULL_PAD_BYTE_LEN; p += attr_len + NULL_PAD_BYTE_LEN; element->num_values = PULL_LE_U32(p, 0); element->values = NULL; if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) { element->values = &ldb_val_single_array[nelem]; } else if (element->num_values != 0) { element->values = talloc_array(message->elements, struct ldb_val, element->num_values); if (!element->values) { errno = ENOMEM; goto failed; } } p += U32_LEN; if (remaining < U32_LEN) { errno = EIO; goto failed; } remaining -= U32_LEN; for (j = 0; j < element->num_values; j++) { /* * Sanity check: Value must be at least the size of * empty val and NULL terminator. */ if (remaining < U32_LEN + NULL_PAD_BYTE_LEN) { errno = EIO; goto failed; } remaining -= U32_LEN + NULL_PAD_BYTE_LEN; len = PULL_LE_U32(p, 0); if (remaining < len) { errno = EIO; goto failed; } if (len + NULL_PAD_BYTE_LEN < len) { errno = EIO; goto failed; } element->values[j].length = len; element->values[j].data = p + U32_LEN; remaining -= len; p += len + U32_LEN + NULL_PAD_BYTE_LEN; } nelem++; } /* * Adapt the number of elements to the real number of unpacked elements, * it means that we overallocated elements array. */ message->num_elements = nelem; /* * Shrink the allocated size. On current talloc behaviour * this will help if we skipped 32 or more attributes. */ message->elements = talloc_realloc(message, message->elements, struct ldb_message_element, message->num_elements); if (remaining != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: %zu bytes unread in ldb_unpack_data_flags", remaining); } return 0; failed: talloc_free(message->elements); return -1; } /* * Unpack a ldb message from a linear buffer in ldb_val */ static int ldb_unpack_data_flags_v2(struct ldb_context *ldb, const struct ldb_val *data, struct ldb_message *message, unsigned int flags) { uint8_t *p, *q, *end_p, *value_section_p; unsigned int i, j; unsigned int nelem = 0; size_t len; struct ldb_val *ldb_val_single_array = NULL; uint8_t val_len_width; message->elements = NULL; p = data->data; end_p = p + data->length; /* Skip first 4 bytes, format already read */ p += U32_LEN; /* First fields are fixed: num_elements, DN length */ if (p + U32_LEN * 2 > end_p) { errno = EIO; goto failed; } message->num_elements = PULL_LE_U32(p, 0); p += U32_LEN; len = PULL_LE_U32(p, 0); p += U32_LEN; if (p + len + NULL_PAD_BYTE_LEN > end_p) { errno = EIO; goto failed; } if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) { message->dn = NULL; } else { struct ldb_val blob; blob.data = discard_const_p(uint8_t, p); blob.length = len; message->dn = ldb_dn_from_ldb_val(message, ldb, &blob); if (message->dn == NULL) { errno = ENOMEM; goto failed; } } p += len + NULL_PAD_BYTE_LEN; if (*(p-NULL_PAD_BYTE_LEN) != '\0') { errno = EINVAL; goto failed; } /* Now skip the canonicalized DN and its length */ len = PULL_LE_U32(p, 0) + NULL_PAD_BYTE_LEN; p += U32_LEN; if (p + len > end_p) { errno = EIO; goto failed; } p += len; if (*(p-NULL_PAD_BYTE_LEN) != '\0') { errno = EINVAL; goto failed; } if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) { return 0; } if (message->num_elements == 0) { return 0; } /* * Sanity check (17 bytes is the minimum element size) */ if (message->num_elements > (end_p - p) / 17) { errno = EIO; goto failed; } message->elements = talloc_zero_array(message, struct ldb_message_element, message->num_elements); if (!message->elements) { errno = ENOMEM; goto failed; } /* * In typical use, most values are single-valued. This makes * it quite expensive to allocate an array of ldb_val for each * of these, just to then hold the pointer to the data buffer. * So with LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this * ahead of time and use it for the single values where possible. * (This is used the the normal search case, but not in the * index case because of caller requirements). */ if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) { ldb_val_single_array = talloc_array(message->elements, struct ldb_val, message->num_elements); if (ldb_val_single_array == NULL) { errno = ENOMEM; goto failed; } } q = p + PULL_LE_U32(p, 0); value_section_p = q; p += U32_LEN; for (i=0;inum_elements;i++) { const char *attr = NULL; size_t attr_len; struct ldb_message_element *element = NULL; /* Sanity check: minimum element size */ if (p + (U32_LEN * 2) + /* attr name len, num values */ (U8_LEN * 2) + /* value length width, one val length */ (NULL_PAD_BYTE_LEN * 2) /* null for attr name + val */ > value_section_p) { errno = EIO; goto failed; } attr_len = PULL_LE_U32(p, 0); p += U32_LEN; if (attr_len == 0) { errno = EIO; goto failed; } attr = (char *)p; p += attr_len + NULL_PAD_BYTE_LEN; /* * num_values, val_len_width * * val_len_width is the width specifier * for the variable length encoding */ if (p + U32_LEN + U8_LEN > value_section_p) { errno = EIO; goto failed; } if (*(p-NULL_PAD_BYTE_LEN) != '\0') { errno = EINVAL; goto failed; } element = &message->elements[nelem]; element->name = attr; element->flags = 0; element->num_values = PULL_LE_U32(p, 0); element->values = NULL; if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) { element->values = &ldb_val_single_array[nelem]; } else if (element->num_values != 0) { element->values = talloc_array(message->elements, struct ldb_val, element->num_values); if (!element->values) { errno = ENOMEM; goto failed; } } p += U32_LEN; /* * Here we read how wide the remaining lengths are * which avoids storing and parsing a lot of leading * 0s */ val_len_width = *p; p += U8_LEN; if (p + val_len_width * element->num_values > value_section_p) { errno = EIO; goto failed; } /* * This is structured weird for compiler optimization * purposes, but we need to pull the array of widths * with different macros depending on how wide the * biggest one is (specified by val_len_width) */ if (val_len_width == U8_LEN) { for (j = 0; j < element->num_values; j++) { element->values[j].length = PULL_LE_U8(p, 0); p += U8_LEN; } } else if (val_len_width == U16_LEN) { for (j = 0; j < element->num_values; j++) { element->values[j].length = PULL_LE_U16(p, 0); p += U16_LEN; } } else if (val_len_width == U32_LEN) { for (j = 0; j < element->num_values; j++) { element->values[j].length = PULL_LE_U32(p, 0); p += U32_LEN; } } else { errno = ERANGE; goto failed; } for (j = 0; j < element->num_values; j++) { len = element->values[j].length; if (len + NULL_PAD_BYTE_LEN < len) { errno = EIO; goto failed; } if (q + len + NULL_PAD_BYTE_LEN > end_p) { errno = EIO; goto failed; } element->values[j].data = q; q += len + NULL_PAD_BYTE_LEN; } nelem++; } /* * If p isn't now pointing at the beginning of the value section, * something went very wrong. */ if (p != value_section_p) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Data corruption in ldb_unpack_data_flags"); errno = EIO; goto failed; } /* * Adapt the number of elements to the real number of unpacked * elements it means that we overallocated elements array. */ message->num_elements = nelem; /* * Shrink the allocated size. On current talloc behaviour * this will help if we skipped 32 or more attributes. */ message->elements = talloc_realloc(message, message->elements, struct ldb_message_element, message->num_elements); if (q != end_p) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: %zu bytes unread in ldb_unpack_data_flags", end_p - q); errno = EIO; goto failed; } return 0; failed: talloc_free(message->elements); return -1; } int ldb_unpack_get_format(const struct ldb_val *data, uint32_t *pack_format_version) { if (data->length < U32_LEN) { return LDB_ERR_OPERATIONS_ERROR; } *pack_format_version = PULL_LE_U32(data->data, 0); return LDB_SUCCESS; } /* * Unpack a ldb message from a linear buffer in ldb_val */ int ldb_unpack_data_flags(struct ldb_context *ldb, const struct ldb_val *data, struct ldb_message *message, unsigned int flags) { unsigned format; if (data->length < U32_LEN) { errno = EIO; return -1; } format = PULL_LE_U32(data->data, 0); if (format == LDB_PACKING_FORMAT_V2) { return ldb_unpack_data_flags_v2(ldb, data, message, flags); } /* * The v1 function we're about to call takes either LDB_PACKING_FORMAT * or LDB_PACKING_FORMAT_NODN packing format versions, and will error * if given some other version, so we don't need to do any further * checks on 'format'. */ return ldb_unpack_data_flags_v1(ldb, data, message, flags, format); } /* * Unpack a ldb message from a linear buffer in ldb_val * * Free with ldb_unpack_data_free() */ int ldb_unpack_data(struct ldb_context *ldb, const struct ldb_val *data, struct ldb_message *message) { return ldb_unpack_data_flags(ldb, data, message, 0); } /* add the special distinguishedName element */ static int msg_add_distinguished_name(struct ldb_message *msg) { const char *dn_attr = "distinguishedName"; char *dn = NULL; if (ldb_msg_find_element(msg, dn_attr)) { /* * This should not happen, but this is * existing behaviour... */ return LDB_SUCCESS; } dn = ldb_dn_alloc_linearized(msg, msg->dn); if (dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_msg_add_steal_string(msg, dn_attr, dn); } /* * filter the specified list of attributes from msg, * adding requested attributes, and perhaps all for *, * but not the DN to filtered_msg. */ int ldb_filter_attrs(struct ldb_context *ldb, const struct ldb_message *msg, const char *const *attrs, struct ldb_message *filtered_msg) { unsigned int i; bool keep_all = false; bool add_dn = false; uint32_t num_elements; uint32_t elements_size; if (attrs) { /* check for special attrs */ for (i = 0; attrs[i]; i++) { int cmp = strcmp(attrs[i], "*"); if (cmp == 0) { keep_all = true; break; } cmp = ldb_attr_cmp(attrs[i], "distinguishedName"); if (cmp == 0) { add_dn = true; } } } else { keep_all = true; } if (keep_all) { add_dn = true; elements_size = msg->num_elements + 1; /* Shortcuts for the simple cases */ } else if (add_dn && i == 1) { if (msg_add_distinguished_name(filtered_msg) != 0) { goto failed; } return 0; } else if (i == 0) { return 0; /* * Otherwise we are copying at most as many elements as we * have attributes */ } else { elements_size = i; } filtered_msg->elements = talloc_array(filtered_msg, struct ldb_message_element, elements_size); if (filtered_msg->elements == NULL) goto failed; num_elements = 0; for (i = 0; i < msg->num_elements; i++) { struct ldb_message_element *el = &msg->elements[i]; /* * el2 is assigned after the Pigeonhole principle * check below for clarity */ struct ldb_message_element *el2 = NULL; unsigned int j; if (keep_all == false) { bool found = false; for (j = 0; attrs[j]; j++) { int cmp = ldb_attr_cmp(el->name, attrs[j]); if (cmp == 0) { found = true; break; } } if (found == false) { continue; } } /* * Pigeonhole principle: we can't have more elements * than the number of attributes if they are unique in * the DB. */ if (num_elements >= elements_size) { goto failed; } el2 = &filtered_msg->elements[num_elements]; *el2 = *el; el2->name = talloc_strdup(filtered_msg->elements, el->name); if (el2->name == NULL) { goto failed; } el2->values = talloc_array(filtered_msg->elements, struct ldb_val, el->num_values); if (el2->values == NULL) { goto failed; } for (j=0;jnum_values;j++) { el2->values[j] = ldb_val_dup(el2->values, &el->values[j]); if (el2->values[j].data == NULL && el->values[j].length != 0) { goto failed; } } num_elements++; } filtered_msg->num_elements = num_elements; if (add_dn) { if (msg_add_distinguished_name(filtered_msg) != 0) { goto failed; } } if (filtered_msg->num_elements > 0) { filtered_msg->elements = talloc_realloc(filtered_msg, filtered_msg->elements, struct ldb_message_element, filtered_msg->num_elements); if (filtered_msg->elements == NULL) { goto failed; } } else { TALLOC_FREE(filtered_msg->elements); } return 0; failed: TALLOC_FREE(filtered_msg->elements); return -1; } ldb-2.0.8/common/ldb_parse.c0000660000000000000000000005076013573675413015633 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldb expression parsing * * Description: parse LDAP-like search expressions * * Author: Andrew Tridgell */ /* TODO: - add RFC2254 binary string handling - possibly add ~=, <= and >= handling - expand the test suite - add better parse error handling */ #include "ldb_private.h" #include "system/locale.h" static int ldb_parse_hex2char(const char *x) { if (isxdigit(x[0]) && isxdigit(x[1])) { const char h1 = x[0], h2 = x[1]; int c = 0; if (h1 >= 'a') c = h1 - (int)'a' + 10; else if (h1 >= 'A') c = h1 - (int)'A' + 10; else if (h1 >= '0') c = h1 - (int)'0'; c = c << 4; if (h2 >= 'a') c += h2 - (int)'a' + 10; else if (h2 >= 'A') c += h2 - (int)'A' + 10; else if (h2 >= '0') c += h2 - (int)'0'; return c; } return -1; } /* a filter is defined by: ::= '(' ')' ::= | | | ::= '&' ::= '|' ::= '!' ::= | ::= ::= '=' | '~=' | '<=' | '>=' */ /* decode a RFC2254 binary string representation of a buffer. Used in LDAP filters. */ struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str) { size_t i, j; struct ldb_val ret; size_t slen = str?strlen(str):0; ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); ret.length = 0; if (ret.data == NULL) return ret; for (i=j=0;i 0x7E || strchr(" *()\\&|!\"", cval)) { return true; } return false; } /* encode a blob as a RFC2254 binary string, escaping any non-printable or '\' characters */ char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val) { size_t i; char *ret; size_t len = val.length; unsigned char *buf = val.data; for (i=0;idata == NULL) return NULL; val++; } if (ret != NULL) { ret[val] = NULL; } return ret; } static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s); /* parse an extended match possible forms: (attr:oid:=value) (attr:dn:oid:=value) (attr:dn:=value) (:dn:oid:=value) the ':dn' part sets the dnAttributes boolean if present the oid sets the rule_id string */ static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, char *attr, char *value) { char *p1, *p2; ret->operation = LDB_OP_EXTENDED; ret->u.extended.value = ldb_binary_decode(ret, value); if (ret->u.extended.value.data == NULL) goto failed; p1 = strchr(attr, ':'); if (p1 == NULL) goto failed; p2 = strchr(p1+1, ':'); *p1 = 0; if (p2) *p2 = 0; ret->u.extended.attr = attr; if (strcmp(p1+1, "dn") == 0) { ret->u.extended.dnAttributes = 1; if (p2) { ret->u.extended.rule_id = talloc_strdup(ret, p2+1); if (ret->u.extended.rule_id == NULL) goto failed; } else { ret->u.extended.rule_id = NULL; } } else { ret->u.extended.dnAttributes = 0; ret->u.extended.rule_id = talloc_strdup(ret, p1+1); if (ret->u.extended.rule_id == NULL) goto failed; } return ret; failed: talloc_free(ret); return NULL; } static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s) { enum ldb_parse_op filter = 0; char *name, *val, *k; const char *p = *s; const char *t, *t1; /* retrieve attributetype name */ t = p; if (*p == '@') { /* for internal attributes the first char can be @ */ p++; } while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { /* attribute names can only be alphanums */ p++; } if (*p == ':') { /* but extended searches have : and . chars too */ p = strstr(p, ":="); if (p == NULL) { /* malformed attribute name */ return 0; } } t1 = p; while (isspace((unsigned char)*p)) p++; if (!strchr("=<>~:", *p)) { return 0; } /* save name */ name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1); if (name == NULL) return 0; name[t1 - t] = '\0'; /* retrieve filtertype */ if (*p == '=') { filter = LDB_OP_EQUALITY; } else if (*p != '\0' && *(p + 1) == '=') { switch (*p) { case '<': filter = LDB_OP_LESS; p++; break; case '>': filter = LDB_OP_GREATER; p++; break; case '~': filter = LDB_OP_APPROX; p++; break; case ':': filter = LDB_OP_EXTENDED; p++; break; } } if (!filter) { talloc_free(name); return 0; } p++; while (isspace((unsigned char)*p)) p++; /* retrieve value */ t = p; while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++; val = (char *)talloc_memdup(mem_ctx, t, p - t + 1); if (val == NULL) { talloc_free(name); return 0; } val[p - t] = '\0'; k = &(val[p - t]); /* remove trailing spaces from value */ while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--; *k = '\0'; *type = name; *value = val; *s = p; return filter; } /* ::= */ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s) { char *attr, *value; struct ldb_parse_tree *ret; enum ldb_parse_op filtertype; ret = talloc_zero(mem_ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; } filtertype = ldb_parse_filtertype(ret, &attr, &value, s); if (!filtertype) { talloc_free(ret); return NULL; } switch (filtertype) { case LDB_OP_PRESENT: ret->operation = LDB_OP_PRESENT; ret->u.present.attr = attr; break; case LDB_OP_EQUALITY: if (strcmp(value, "*") == 0) { ret->operation = LDB_OP_PRESENT; ret->u.present.attr = attr; break; } if (ldb_parse_find_wildcard(value) != NULL) { ret->operation = LDB_OP_SUBSTRING; ret->u.substring.attr = attr; ret->u.substring.start_with_wildcard = 0; ret->u.substring.end_with_wildcard = 0; ret->u.substring.chunks = ldb_wildcard_decode(ret, value); if (ret->u.substring.chunks == NULL){ talloc_free(ret); return NULL; } if (value[0] == '*') ret->u.substring.start_with_wildcard = 1; if (value[strlen(value) - 1] == '*') ret->u.substring.end_with_wildcard = 1; talloc_free(value); break; } ret->operation = LDB_OP_EQUALITY; ret->u.equality.attr = attr; ret->u.equality.value = ldb_binary_decode(ret, value); if (ret->u.equality.value.data == NULL) { talloc_free(ret); return NULL; } talloc_free(value); break; case LDB_OP_GREATER: ret->operation = LDB_OP_GREATER; ret->u.comparison.attr = attr; ret->u.comparison.value = ldb_binary_decode(ret, value); if (ret->u.comparison.value.data == NULL) { talloc_free(ret); return NULL; } talloc_free(value); break; case LDB_OP_LESS: ret->operation = LDB_OP_LESS; ret->u.comparison.attr = attr; ret->u.comparison.value = ldb_binary_decode(ret, value); if (ret->u.comparison.value.data == NULL) { talloc_free(ret); return NULL; } talloc_free(value); break; case LDB_OP_APPROX: ret->operation = LDB_OP_APPROX; ret->u.comparison.attr = attr; ret->u.comparison.value = ldb_binary_decode(ret, value); if (ret->u.comparison.value.data == NULL) { talloc_free(ret); return NULL; } talloc_free(value); break; case LDB_OP_EXTENDED: ret = ldb_parse_extended(ret, attr, value); break; default: talloc_free(ret); return NULL; } return ret; } /* parse a filterlist ::= '&' ::= '|' ::= | */ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s) { struct ldb_parse_tree *ret, *next; enum ldb_parse_op op; const char *p = *s; switch (*p) { case '&': op = LDB_OP_AND; break; case '|': op = LDB_OP_OR; break; default: return NULL; } p++; while (isspace((unsigned char)*p)) p++; ret = talloc(mem_ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; } ret->operation = op; ret->u.list.num_elements = 1; ret->u.list.elements = talloc(ret, struct ldb_parse_tree *); if (!ret->u.list.elements) { errno = ENOMEM; talloc_free(ret); return NULL; } ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); if (!ret->u.list.elements[0]) { talloc_free(ret); return NULL; } while (isspace((unsigned char)*p)) p++; while (*p) { struct ldb_parse_tree **e; if (*p == ')') { break; } next = ldb_parse_filter(ret->u.list.elements, &p); if (next == NULL) { /* an invalid filter element */ talloc_free(ret); return NULL; } e = talloc_realloc(ret, ret->u.list.elements, struct ldb_parse_tree *, ret->u.list.num_elements + 1); if (!e) { errno = ENOMEM; talloc_free(ret); return NULL; } ret->u.list.elements = e; ret->u.list.elements[ret->u.list.num_elements] = next; ret->u.list.num_elements++; while (isspace((unsigned char)*p)) p++; } *s = p; return ret; } /* ::= '!' */ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) { struct ldb_parse_tree *ret; const char *p = *s; if (*p != '!') { return NULL; } p++; ret = talloc(mem_ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; } ret->operation = LDB_OP_NOT; ret->u.isnot.child = ldb_parse_filter(ret, &p); if (!ret->u.isnot.child) { talloc_free(ret); return NULL; } *s = p; return ret; } /* parse a filtercomp ::= | | | */ static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s) { struct ldb_parse_tree *ret; const char *p = *s; while (isspace((unsigned char)*p)) p++; switch (*p) { case '&': ret = ldb_parse_filterlist(mem_ctx, &p); break; case '|': ret = ldb_parse_filterlist(mem_ctx, &p); break; case '!': ret = ldb_parse_not(mem_ctx, &p); break; case '(': case ')': return NULL; default: ret = ldb_parse_simple(mem_ctx, &p); } *s = p; return ret; } /* ::= '(' ')' */ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s) { struct ldb_parse_tree *ret; const char *p = *s; if (*p != '(') { return NULL; } p++; ret = ldb_parse_filtercomp(mem_ctx, &p); if (*p != ')') { return NULL; } p++; while (isspace((unsigned char)*p)) { p++; } *s = p; return ret; } /* main parser entry point. Takes a search string and returns a parse tree expression ::= | */ struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) { while (s && isspace((unsigned char)*s)) s++; if (s == NULL || *s == 0) { s = "(|(objectClass=*)(distinguishedName=*))"; } if (*s == '(') { return ldb_parse_filter(mem_ctx, &s); } return ldb_parse_simple(mem_ctx, &s); } /* construct a ldap parse filter given a parse tree */ char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree) { char *s, *s2, *ret; unsigned int i; if (tree == NULL) { return NULL; } switch (tree->operation) { case LDB_OP_AND: case LDB_OP_OR: ret = talloc_asprintf(mem_ctx, "(%c", tree->operation==LDB_OP_AND?'&':'|'); if (ret == NULL) return NULL; for (i=0;iu.list.num_elements;i++) { s = ldb_filter_from_tree(mem_ctx, tree->u.list.elements[i]); if (s == NULL) { talloc_free(ret); return NULL; } s2 = talloc_asprintf_append(ret, "%s", s); talloc_free(s); if (s2 == NULL) { talloc_free(ret); return NULL; } ret = s2; } s = talloc_asprintf_append(ret, ")"); if (s == NULL) { talloc_free(ret); return NULL; } return s; case LDB_OP_NOT: s = ldb_filter_from_tree(mem_ctx, tree->u.isnot.child); if (s == NULL) return NULL; ret = talloc_asprintf(mem_ctx, "(!%s)", s); talloc_free(s); return ret; case LDB_OP_EQUALITY: s = ldb_binary_encode(mem_ctx, tree->u.equality.value); if (s == NULL) return NULL; ret = talloc_asprintf(mem_ctx, "(%s=%s)", tree->u.equality.attr, s); talloc_free(s); return ret; case LDB_OP_SUBSTRING: ret = talloc_asprintf(mem_ctx, "(%s=%s", tree->u.substring.attr, tree->u.substring.start_with_wildcard?"*":""); if (ret == NULL) return NULL; for (i = 0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) { s2 = ldb_binary_encode(mem_ctx, *(tree->u.substring.chunks[i])); if (s2 == NULL) { talloc_free(ret); return NULL; } if (tree->u.substring.chunks[i+1] || tree->u.substring.end_with_wildcard) { s = talloc_asprintf_append(ret, "%s*", s2); } else { s = talloc_asprintf_append(ret, "%s", s2); } if (s == NULL) { talloc_free(ret); return NULL; } ret = s; } s = talloc_asprintf_append(ret, ")"); if (s == NULL) { talloc_free(ret); return NULL; } ret = s; return ret; case LDB_OP_GREATER: s = ldb_binary_encode(mem_ctx, tree->u.equality.value); if (s == NULL) return NULL; ret = talloc_asprintf(mem_ctx, "(%s>=%s)", tree->u.equality.attr, s); talloc_free(s); return ret; case LDB_OP_LESS: s = ldb_binary_encode(mem_ctx, tree->u.equality.value); if (s == NULL) return NULL; ret = talloc_asprintf(mem_ctx, "(%s<=%s)", tree->u.equality.attr, s); talloc_free(s); return ret; case LDB_OP_PRESENT: ret = talloc_asprintf(mem_ctx, "(%s=*)", tree->u.present.attr); return ret; case LDB_OP_APPROX: s = ldb_binary_encode(mem_ctx, tree->u.equality.value); if (s == NULL) return NULL; ret = talloc_asprintf(mem_ctx, "(%s~=%s)", tree->u.equality.attr, s); talloc_free(s); return ret; case LDB_OP_EXTENDED: s = ldb_binary_encode(mem_ctx, tree->u.extended.value); if (s == NULL) return NULL; ret = talloc_asprintf(mem_ctx, "(%s%s%s%s:=%s)", tree->u.extended.attr?tree->u.extended.attr:"", tree->u.extended.dnAttributes?":dn":"", tree->u.extended.rule_id?":":"", tree->u.extended.rule_id?tree->u.extended.rule_id:"", s); talloc_free(s); return ret; } return NULL; } /* walk a parse tree, calling the provided callback on each node */ int ldb_parse_tree_walk(struct ldb_parse_tree *tree, int (*callback)(struct ldb_parse_tree *tree, void *), void *private_context) { unsigned int i; int ret; ret = callback(tree, private_context); if (ret != LDB_SUCCESS) { return ret; } switch (tree->operation) { case LDB_OP_AND: case LDB_OP_OR: for (i=0;iu.list.num_elements;i++) { ret = ldb_parse_tree_walk(tree->u.list.elements[i], callback, private_context); if (ret != LDB_SUCCESS) { return ret; } } break; case LDB_OP_NOT: ret = ldb_parse_tree_walk(tree->u.isnot.child, callback, private_context); if (ret != LDB_SUCCESS) { return ret; } break; case LDB_OP_EQUALITY: case LDB_OP_GREATER: case LDB_OP_LESS: case LDB_OP_APPROX: case LDB_OP_SUBSTRING: case LDB_OP_PRESENT: case LDB_OP_EXTENDED: break; } return LDB_SUCCESS; } struct parse_tree_attr_replace_ctx { const char *attr; const char *replace; }; /* callback for ldb_parse_tree_attr_replace() */ static int parse_tree_attr_replace(struct ldb_parse_tree *tree, void *private_context) { struct parse_tree_attr_replace_ctx *ctx = private_context; switch (tree->operation) { case LDB_OP_EQUALITY: case LDB_OP_GREATER: case LDB_OP_LESS: case LDB_OP_APPROX: if (ldb_attr_cmp(tree->u.equality.attr, ctx->attr) == 0) { tree->u.equality.attr = ctx->replace; } break; case LDB_OP_SUBSTRING: if (ldb_attr_cmp(tree->u.substring.attr, ctx->attr) == 0) { tree->u.substring.attr = ctx->replace; } break; case LDB_OP_PRESENT: if (ldb_attr_cmp(tree->u.present.attr, ctx->attr) == 0) { tree->u.present.attr = ctx->replace; } break; case LDB_OP_EXTENDED: if (tree->u.extended.attr && ldb_attr_cmp(tree->u.extended.attr, ctx->attr) == 0) { tree->u.extended.attr = ctx->replace; } break; default: break; } return LDB_SUCCESS; } /* replace any occurrences of an attribute name in the parse tree with a new name */ void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, const char *attr, const char *replace) { struct parse_tree_attr_replace_ctx ctx; ctx.attr = attr; ctx.replace = replace; ldb_parse_tree_walk(tree, parse_tree_attr_replace, &ctx); } /* shallow copy a tree - copying only the elements array so that the caller can safely add new elements without changing the message */ struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *ot) { unsigned int i; struct ldb_parse_tree *nt; nt = talloc(mem_ctx, struct ldb_parse_tree); if (!nt) { return NULL; } *nt = *ot; switch (ot->operation) { case LDB_OP_AND: case LDB_OP_OR: nt->u.list.elements = talloc_array(nt, struct ldb_parse_tree *, ot->u.list.num_elements); if (!nt->u.list.elements) { talloc_free(nt); return NULL; } for (i=0;iu.list.num_elements;i++) { nt->u.list.elements[i] = ldb_parse_tree_copy_shallow(nt->u.list.elements, ot->u.list.elements[i]); if (!nt->u.list.elements[i]) { talloc_free(nt); return NULL; } } break; case LDB_OP_NOT: nt->u.isnot.child = ldb_parse_tree_copy_shallow(nt, ot->u.isnot.child); if (!nt->u.isnot.child) { talloc_free(nt); return NULL; } break; case LDB_OP_EQUALITY: case LDB_OP_GREATER: case LDB_OP_LESS: case LDB_OP_APPROX: case LDB_OP_SUBSTRING: case LDB_OP_PRESENT: case LDB_OP_EXTENDED: break; } return nt; } ldb-2.0.8/common/ldb_utf8.c0000660000000000000000000000606112406075657015400 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldb utf8 handling * * Description: case folding and case comparison for UTF8 strings * * Author: Andrew Tridgell */ #include "ldb_private.h" #include "system/locale.h" /* this allow the user to pass in a caseless comparison function to handle utf8 caseless comparisons */ void ldb_set_utf8_fns(struct ldb_context *ldb, void *context, char *(*casefold)(void *, void *, const char *, size_t)) { if (context) ldb->utf8_fns.context = context; if (casefold) ldb->utf8_fns.casefold = casefold; } /* a simple case folding function NOTE: does not handle UTF8 */ char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n) { size_t i; char *ret = talloc_strndup(mem_ctx, s, n); if (!s) { errno = ENOMEM; return NULL; } for (i=0;ret[i];i++) { ret[i] = toupper((unsigned char)ret[i]); } return ret; } void ldb_set_utf8_default(struct ldb_context *ldb) { ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); } char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n) { return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n); } /* check the attribute name is valid according to rfc2251 returns 1 if the name is ok */ int ldb_valid_attr_name(const char *s) { size_t i; if (!s || !s[0]) return 0; /* handle special ldb_tdb wildcard */ if (strcmp(s, "*") == 0) return 1; for (i = 0; s[i]; i++) { if (! isascii(s[i])) { return 0; } if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ if (! (isalpha(s[i]) || (s[i] == '@'))) { return 0; } } else { if (! (isalnum(s[i]) || (s[i] == '-'))) { return 0; } } } return 1; } char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s) { size_t i; char *ret = talloc_strdup(mem_ctx, s); if (!ret) { errno = ENOMEM; return NULL; } for (i = 0; ret[i]; i++) { ret[i] = toupper((unsigned char)ret[i]); } return ret; } /* we accept either 'dn' or 'distinguishedName' for a distinguishedName */ int ldb_attr_dn(const char *attr) { if (ldb_attr_cmp(attr, "dn") == 0 || ldb_attr_cmp(attr, "distinguishedName") == 0) { return 0; } return -1; } ldb-2.0.8/common/qsort.c0000660000000000000000000002044413444661620015034 0ustar rootroot00000000000000/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Douglas C. Schmidt (schmidt@ics.uci.edu). The GNU C 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 2.1 of the License, or (at your option) any later version. The GNU C 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 the GNU C Library; if not, see . */ /* If you consider tuning this algorithm, you should consult first: Engineering a sort function; Jon Bentley and M. Douglas McIlroy; Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ /* Modified to be used in samba4 by * Simo Sorce 2005 */ #include "ldb_private.h" /* Byte-wise swap two items of size SIZE. */ #define SWAP(a, b, size) \ do \ { \ register size_t __size = (size); \ register char *__a = (a), *__b = (b); \ do \ { \ char __tmp = *__a; \ *__a++ = *__b; \ *__b++ = __tmp; \ } while (--__size > 0); \ } while (0) /* Discontinue quicksort algorithm when partition gets below this size. This particular magic number was chosen to work best on a Sun 4/260. */ #define MAX_THRESH 4 /* Stack node declarations used to store unfulfilled partition obligations. */ typedef struct { char *lo; char *hi; } stack_node; /* The next 4 #defines implement a very fast in-line stack abstraction. */ /* The stack needs log (total_elements) entries (we could even subtract log(MAX_THRESH)). Since total_elements has type size_t, we get as upper bound for log (total_elements): bits per byte (CHAR_BIT) * sizeof(size_t). */ #ifndef CHAR_BIT #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))) /* Order size using quicksort. This implementation incorporates four optimizations discussed in Sedgewick: 1. Non-recursive, using an explicit stack of pointer that store the next array partition to sort. To save time, this maximum amount of space required to store an array of SIZE_MAX is allocated on the stack. Assuming a 32-bit (64 bit) integer for size_t, this needs only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). Pretty cheap, actually. 2. Chose the pivot element using a median-of-three decision tree. This reduces the probability of selecting a bad pivot value and eliminates certain extraneous comparisons. 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving insertion sort to order the MAX_THRESH items within each partition. This is a big win, since insertion sort is faster for small, mostly sorted array segments. 4. The larger of the two sub-partitions is always pushed onto the stack first, with the algorithm then concentrating on the smaller partition. This *guarantees* no more than log (total_elems) stack size is needed (actually O(1) in this case)! */ void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp) { register char *base_ptr = (char *) pbase; const size_t max_thresh = MAX_THRESH * size; if (total_elems == 0) /* Avoid lossage with unsigned arithmetic below. */ return; if (total_elems > MAX_THRESH) { char *lo = base_ptr; char *hi = &lo[size * (total_elems - 1)]; stack_node stack[STACK_SIZE]; size_t i = 0; PUSH (NULL, NULL); do { char *left_ptr; char *right_ptr; /* Select median value from among LO, MID, and HI. Rearrange LO and HI so the three values are sorted. This lowers the probability of picking a pathological pivot value and skips a comparison for both the LEFT_PTR and RIGHT_PTR in the while loops. */ char *mid = lo + size * ((hi - lo) / size >> 1); if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) SWAP (mid, lo, size); if ((*cmp) ((void *) hi, (void *) mid, opaque) < 0) SWAP (mid, hi, size); else goto jump_over; if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) SWAP (mid, lo, size); jump_over:; left_ptr = lo + size; right_ptr = hi - size; /* Here's the famous ``collapse the walls'' section of quicksort. Gotta like those tight inner loops! They are the main reason that this algorithm runs much faster than others. */ do { while ((*cmp) ((void *) left_ptr, (void *) mid, opaque) < 0) left_ptr += size; while ((*cmp) ((void *) mid, (void *) right_ptr, opaque) < 0) right_ptr -= size; if (left_ptr < right_ptr) { SWAP (left_ptr, right_ptr, size); if (mid == left_ptr) mid = right_ptr; else if (mid == right_ptr) mid = left_ptr; left_ptr += size; right_ptr -= size; } else if (left_ptr == right_ptr) { left_ptr += size; right_ptr -= size; break; } } while (left_ptr <= right_ptr); /* Set up pointers for next iteration. First determine whether left and right partitions are below the threshold size. If so, ignore one or both. Otherwise, push the larger partition's bounds on the stack and continue sorting the smaller one. */ if ((size_t) (right_ptr - lo) <= max_thresh) { if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */ POP (lo, hi); else /* Ignore small left partition. */ lo = left_ptr; } else if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore small right partition. */ hi = right_ptr; else if ((right_ptr - lo) > (hi - left_ptr)) { /* Push larger left partition indices. */ PUSH (lo, right_ptr); lo = left_ptr; } else { /* Push larger right partition indices. */ PUSH (left_ptr, hi); hi = right_ptr; } } while (i > 0 && i < STACK_SIZE); } /* Once the BASE_PTR array is partially sorted by quicksort the rest is completely sorted using insertion sort, since this is efficient for partitions below MAX_THRESH size. BASE_PTR points to the beginning of the array to sort, and END_PTR points at the very last element in the array (*not* one beyond it!). */ #define min(x, y) ((x) < (y) ? (x) : (y)) { char *const end_ptr = &base_ptr[size * (total_elems - 1)]; char *tmp_ptr = base_ptr; char *thresh = min(end_ptr, base_ptr + max_thresh); register char *run_ptr; /* Find smallest element in first threshold and place it at the array's beginning. This is the smallest array element, and the operation speeds up insertion sort's inner loop. */ for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) tmp_ptr = run_ptr; if (tmp_ptr != base_ptr) SWAP (tmp_ptr, base_ptr, size); /* Insertion sort, running from left-hand-side up to right-hand-side. */ run_ptr = base_ptr + size; while ((run_ptr += size) <= end_ptr) { tmp_ptr = run_ptr - size; while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) tmp_ptr -= size; tmp_ptr += size; if (tmp_ptr != run_ptr) { char *trav; trav = run_ptr + size; while (--trav >= run_ptr) { char c = *trav; char *hi, *lo; for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) *hi = *lo; *hi = c; } } } } } ldb-2.0.8/configure0000770000000000000000000000065413573675413014147 0ustar rootroot00000000000000#!/bin/sh PREVPATH=`dirname $0` if [ -f $PREVPATH/../../buildtools/bin/waf ]; then WAF=../../buildtools/bin/waf elif [ -f $PREVPATH/buildtools/bin/waf ]; then WAF=./buildtools/bin/waf else echo "ldb: Unable to find waf" exit 1 fi # using JOBS=1 gives maximum compatibility with # systems like AIX which have broken threading in python JOBS=1 export JOBS cd . || exit 1 $PYTHON $WAF configure "$@" || exit 1 cd $PREVPATH ldb-2.0.8/docs/builddocs.sh0000770000000000000000000000226212406075657015472 0ustar rootroot00000000000000#!/bin/sh # build ldb docs # tridge@samba.org August 2006 XSLTPROC="$1" SRCDIR="$2" if [ -z "$XSLTPROC" ] || [ ! -x "$XSLTPROC" ]; then echo "xsltproc not installed" exit 0 fi MANXSL="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl" HTMLXSL="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl" mkdir -p man for f in $SRCDIR/man/*.xml; do base=`basename $f .xml` out=man/"`basename $base`" if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then echo Processing manpage $f $XSLTPROC --nonet -o "$out" "$MANXSL" $f ret=$? if [ "$ret" = "4" ]; then echo "ignoring stylesheet error 4 for $MANXSL" exit 0 fi if [ "$ret" != "0" ]; then echo "xsltproc failed with error $ret" exit $ret fi fi done for f in $SRCDIR/man/*.xml; do base=`basename $f .xml` out=man/"`basename $base`".html if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then echo Processing html $f $XSLTPROC --nonet -o "$out" "$HTMLXSL" $f ret=$? if [ "$ret" = "4" ]; then echo "ignoring stylesheet error 4 for $HTMLXSL" exit 0 fi if [ "$ret" != "0" ]; then echo "xsltproc failed with error $ret" exit $ret fi fi done ldb-2.0.8/docs/design.txt0000660000000000000000000000155612406075657015203 0ustar rootroot00000000000000The list of indexed fields -------------------------- dn=@INDEXLIST list of field names that are indexed contains fields of type @IDXATTR which contain attriute names of indexed fields Data records ------------ for each user record in the db there is: main record key: DN=dn data: packed attribute/value list a index record for each indexed field in the record Index Records ------------- The index records contain the list of dn's that contain records matching the index key All index records are of the form: dn=@INDEX:field:value and contain fields of type @IDX which are the dns of the records that have that value for some attribute Search Expressions ------------------ Very similar to LDAP search expressions, but does not allow ~=, <= or >= attrib0 := (field=value) attrib := attrib0 | (attrib&&attrib) | (attrib||attrib) | !attrib ldb-2.0.8/docs/installdocs.sh0000770000000000000000000000051312406075657016036 0ustar rootroot00000000000000#!/bin/sh # install ldb docs # tridge@samba.org August 2006 MANDIR="$1" MAN1="`/bin/ls man/*.1`" MAN3="`/bin/ls man/*.3`" if [ -z "$MAN1" ] && [ -z "$MAN3" ]; then echo "No manpages have been built" exit 0 fi mkdir -p "$MANDIR/man1" "$MANDIR/man3" cp $MAN1 "$MANDIR/man1/" || exit 1 cp $MAN3 "$MANDIR/man3/" || exit 1 ldb-2.0.8/examples.dox0000660000000000000000000000044312406075657014565 0ustar rootroot00000000000000/** \example ldbreader.c The code below shows a simple LDB application. It lists / dumps the records in a LDB database to standard output. */ /** \example ldifreader.c The code below shows a simple LDB application. It lists / dumps the entries in an LDIF file to standard output. */ ldb-2.0.8/examples/ldbreader.c0000660000000000000000000000676512406075657016156 0ustar rootroot00000000000000/* example code for the ldb database library Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 ** 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 . */ /** \example ldbreader.c The code below shows a simple LDB application. It lists / dumps the records in a LDB database to standard output. */ #include "ldb.h" /* ldb_ldif_write takes a function pointer to a custom output function. This version is about as simple as the output function can be. In a more complex example, you'd likely be doing something with the private data function (e.g. holding a file handle). */ static int vprintf_fn(void *private_data, const char *fmt, ...) { int retval; va_list ap; va_start(ap, fmt); /* We just write to standard output */ retval = vprintf(fmt, ap); va_end(ap); /* Note that the function should return the number of bytes written, or a negative error code */ return retval; } int main(int argc, const char **argv) { struct ldb_context *ldb; const char *expression = "(dn=*)"; struct ldb_result *resultMsg; int i; /* This is the always the first thing you want to do in an LDB application - initialise up the context structure. Note that you can use the context structure as a parent for talloc allocations as well */ ldb = ldb_init(NULL, NULL); /* We now open the database. In this example we just hard code the connection path. Also note that the database is being opened read-only. This means that the call will fail unless the database already exists. */ if (LDB_SUCCESS != ldb_connect(ldb, "tdb://tdbtest.ldb", LDB_FLG_RDONLY, NULL) ){ printf("Problem on connection\n"); exit(-1); } /* At this stage we have an open database, and can start using it. It is opened read-only, so a query is possible. We construct a search that just returns all the (sensible) contents. You can do quite fine grained results with the LDAP search syntax, however it is a bit confusing to start with. See RFC2254. */ if (LDB_SUCCESS != ldb_search(ldb, ldb, &resultMsg, NULL, LDB_SCOPE_DEFAULT, NULL, "%s", expression)) { printf("Problem in search\n"); exit(-1); } printf("%i records returned\n", resultMsg->count); /* We can now iterate through the results, writing them out (to standard output) with our custom output routine as defined at the top of this file */ for (i = 0; i < resultMsg->count; ++i) { struct ldb_ldif ldifMsg; printf("Message: %i\n", i+1); ldifMsg.changetype = LDB_CHANGETYPE_NONE; ldifMsg.msg = resultMsg->msgs[i]; ldb_ldif_write(ldb, vprintf_fn, NULL, &ldifMsg); } /* There are two objects to clean up - the result from the ldb_search() query, and the original ldb context. */ talloc_free(resultMsg); talloc_free(ldb); return 0; } ldb-2.0.8/examples/ldifreader.c0000660000000000000000000000625412406075657016324 0ustar rootroot00000000000000/* example code for the ldb database library Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 ** 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 . */ /** \example ldifreader.c The code below shows a simple LDB application. It lists / dumps the entries in an LDIF file to standard output. */ #include "ldb.h" /* ldb_ldif_write takes a function pointer to a custom output function. This version is about as simple as the output function can be. In a more complex example, you'd likely be doing something with the private data function (e.g. holding a file handle). */ static int vprintf_fn(void *private_data, const char *fmt, ...) { int retval; va_list ap; va_start(ap, fmt); /* We just write to standard output */ retval = vprintf(fmt, ap); va_end(ap); /* Note that the function should return the number of bytes written, or a negative error code */ return retval; } int main(int argc, const char **argv) { struct ldb_context *ldb; FILE *fileStream; struct ldb_ldif *ldifMsg; if (argc != 2) { printf("Usage %s filename.ldif\n", argv[0]); exit(1); } /* This is the always the first thing you want to do in an LDB application - initialise up the context structure. Note that you can use the context structure as a parent for talloc allocations as well */ ldb = ldb_init(NULL, NULL); fileStream = fopen(argv[1], "r"); if (0 == fileStream) { perror(argv[1]); exit(1); } /* We now work through the filestream to get each entry. */ while ( (ldifMsg = ldb_ldif_read_file(ldb, fileStream)) ) { /* Each message has a particular change type. For Add, Modify and Delete, this will also appear in the output listing (as changetype: add, changetype: modify or changetype:delete, respectively). */ switch (ldifMsg->changetype) { case LDB_CHANGETYPE_NONE: printf("ChangeType: None\n"); break; case LDB_CHANGETYPE_ADD: printf("ChangeType: Add\n"); break; case LDB_CHANGETYPE_MODIFY: printf("ChangeType: Modify\n"); break; case LDB_CHANGETYPE_DELETE: printf("ChangeType: Delete\n"); break; default: printf("ChangeType: Unknown\n"); } /* We can now write out the results, using our custom output routine as defined at the top of this file. */ ldb_ldif_write(ldb, vprintf_fn, NULL, ldifMsg); /* Clean up the message */ ldb_ldif_read_free(ldb, ldifMsg); } /* Clean up the context */ talloc_free(ldb); return 0; } ldb-2.0.8/include/dlinklist.h0000660000000000000000000001105713573675413016031 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. some simple double linked list macros Copyright (C) Andrew Tridgell 1998-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 . */ /* To use these macros you must have a structure containing a next and prev pointer */ #ifndef _DLINKLIST_H #define _DLINKLIST_H /* February 2010 - changed list format to have a prev pointer from the list head. This makes DLIST_ADD_END() O(1) even though we only have one list pointer. The scheme is as follows: 1) with no entries in the list: list_head == NULL 2) with 1 entry in the list: list_head->next == NULL list_head->prev == list_head 3) with 2 entries in the list: list_head->next == element2 list_head->prev == element2 element2->prev == list_head element2->next == NULL 4) with N entries in the list: list_head->next == element2 list_head->prev == elementN elementN->prev == element{N-1} elementN->next == NULL This allows us to find the tail of the list by using list_head->prev, which means we can add to the end of the list in O(1) time */ /* add an element at the front of a list */ #define DLIST_ADD(list, p) \ do { \ if (!(list)) { \ (p)->prev = (list) = (p); \ (p)->next = NULL; \ } else { \ (p)->prev = (list)->prev; \ (list)->prev = (p); \ (p)->next = (list); \ (list) = (p); \ } \ } while (0) /* remove an element from a list Note that the element doesn't have to be in the list. If it isn't then this is a no-op */ #define DLIST_REMOVE(list, p) \ do { \ if ((p) == (list)) { \ if ((p)->next) (p)->next->prev = (p)->prev; \ (list) = (p)->next; \ } else if ((p)->prev && (list) && (p) == (list)->prev) { \ (p)->prev->next = NULL; \ (list)->prev = (p)->prev; \ } else { \ if ((p)->prev) (p)->prev->next = (p)->next; \ if ((p)->next) (p)->next->prev = (p)->prev; \ } \ if ((p) != (list)) (p)->next = (p)->prev = NULL; \ } while (0) /* find the head of the list given any element in it. Note that this costs O(N), so you should avoid this macro if at all possible! */ #define DLIST_HEAD(p, result_head) \ do { \ (result_head) = (p); \ while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ } while(0) /* return the last element in the list */ #define DLIST_TAIL(list) ((list)?(list)->prev:NULL) /* return the previous element in the list. */ #define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) /* insert 'p' after the given element 'el' in a list. If el is NULL then this is the same as a DLIST_ADD() */ #define DLIST_ADD_AFTER(list, p, el) \ do { \ if (!(list) || !(el)) { \ DLIST_ADD(list, p); \ } else { \ (p)->prev = (el); \ (p)->next = (el)->next; \ (el)->next = (p); \ if ((p)->next) (p)->next->prev = (p); \ if ((list)->prev == (el)) (list)->prev = (p); \ }\ } while (0) /* add to the end of a list. */ #define DLIST_ADD_END(list, p) \ do { \ if (!(list)) { \ DLIST_ADD(list, p); \ } else { \ DLIST_ADD_AFTER(list, p, (list)->prev); \ } \ } while (0) /* promote an element to the front of a list */ #define DLIST_PROMOTE(list, p) \ do { \ DLIST_REMOVE(list, p); \ DLIST_ADD(list, p); \ } while (0) /* demote an element to the end of a list. */ #define DLIST_DEMOTE(list, p) \ do { \ DLIST_REMOVE(list, p); \ DLIST_ADD_END(list, p); \ } while (0) /* concatenate two lists - putting all elements of the 2nd list at the end of the first list. */ #define DLIST_CONCATENATE(list1, list2) \ do { \ if (!(list1)) { \ (list1) = (list2); \ } else { \ (list1)->prev->next = (list2); \ if (list2) { \ void *_tmplist = (void *)(list1)->prev; \ (list1)->prev = (list2)->prev; \ (list2)->prev = _tmplist; \ } \ } \ } while (0) #endif /* _DLINKLIST_H */ ldb-2.0.8/include/ldb.h0000660000000000000000000021540513573675413014600 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 Copyright (C) Stefan Metzmacher 2004 Copyright (C) Simo Sorce 2005-2006 ** 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 . */ /* * Name: ldb * * Component: ldb header * * Description: defines for base ldb API * * Author: Andrew Tridgell * Author: Stefan Metzmacher */ /** \file ldb.h Samba's ldb database This header file provides the main API for ldb. */ #ifndef _LDB_H_ /*! \cond DOXYGEN_IGNORE */ #define _LDB_H_ 1 /*! \endcond */ #include #include #include #include #include /* major restrictions as compared to normal LDAP: - each record must have a unique key field - the key must be representable as a NULL terminated C string and may not contain a comma or braces major restrictions as compared to tdb: - no explicit locking calls, but we have transactions when using ldb_tdb */ #ifndef ldb_val /** Result value An individual lump of data in a result comes in this format. The pointer will usually be to a UTF-8 string if the application is sensible, but it can be to anything you like, including binary data blobs of arbitrary size. \note the data is null (0x00) terminated, but the length does not include the terminator. */ struct ldb_val { uint8_t *data; /*!< result data */ size_t length; /*!< length of data */ }; #endif /*! \cond DOXYGEN_IGNORE */ #ifndef PRINTF_ATTRIBUTE #define PRINTF_ATTRIBUTE(a,b) #endif #ifndef _DEPRECATED_ #if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) #define _DEPRECATED_ __attribute__ ((deprecated)) #else #define _DEPRECATED_ #endif #endif /*! \endcond */ /* opaque ldb_dn structures, see ldb_dn.c for internals */ struct ldb_dn_component; struct ldb_dn; /** There are a number of flags that are used with ldap_modify() in ldb_message_element.flags fields. The LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_DELETE and LDB_FLAG_MOD_REPLACE are better thought of as an enumeration, not flags, and are used in ldap_modify() calls to specify whether attributes are being added, deleted or modified respectively. */ #define LDB_FLAG_MOD_MASK 0x3 /** use this to extract the mod type (enum) from the operation */ #define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK) /** Value used in ldap_modify() to indicate that attributes are being added. \sa LDB_FLAG_MOD_MASK */ #define LDB_FLAG_MOD_ADD 1 /** Value used in ldap_modify() to indicate that attributes are being replaced. \sa LDB_FLAG_MOD_MASK */ #define LDB_FLAG_MOD_REPLACE 2 /** Value used in ldap_modify() to indicate that attributes are being deleted. \sa LDB_FLAG_MOD_MASK */ #define LDB_FLAG_MOD_DELETE 3 /** Flag value used in ldb_ldif_write_trace() to enforce binary encoded attribute values per attribute. This is a genuine flag, being outside LDB_FLAG_MOD_MASK and also outside LDB_FLAG_INTERNAL_MASK */ #define LDB_FLAG_FORCE_NO_BASE64_LDIF 4 /** flag bits on an element usable only by the internal implementation */ #define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0 /** OID for logic AND comaprison. This is the well known object ID for a logical AND comparitor. */ #define LDB_OID_COMPARATOR_AND "1.2.840.113556.1.4.803" /** OID for logic OR comparison. This is the well known object ID for a logical OR comparitor. */ #define LDB_OID_COMPARATOR_OR "1.2.840.113556.1.4.804" /** results are given back as arrays of ldb_message_element */ struct ldb_message_element { unsigned int flags; const char *name; unsigned int num_values; struct ldb_val *values; }; /** a ldb_message represents all or part of a record. It can contain an arbitrary number of elements. */ struct ldb_message { struct ldb_dn *dn; unsigned int num_elements; struct ldb_message_element *elements; }; enum ldb_changetype { LDB_CHANGETYPE_NONE=0, LDB_CHANGETYPE_ADD, LDB_CHANGETYPE_DELETE, LDB_CHANGETYPE_MODIFY, LDB_CHANGETYPE_MODRDN }; /** LDIF record This structure contains a LDIF record, as returned from ldif_read() and equivalent functions. */ struct ldb_ldif { enum ldb_changetype changetype; /*!< The type of change */ struct ldb_message *msg; /*!< The changes */ }; enum ldb_scope {LDB_SCOPE_DEFAULT=-1, LDB_SCOPE_BASE=0, LDB_SCOPE_ONELEVEL=1, LDB_SCOPE_SUBTREE=2}; struct ldb_context; struct tevent_context; /* debugging uses one of the following levels */ enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; /* alias for something that's not a fatal error but we really want to log */ #define LDB_DEBUG_ALWAYS_LOG LDB_DEBUG_FATAL /** the user can optionally supply a debug function. The function is based on the vfprintf() style of interface, but with the addition of a severity level */ struct ldb_debug_ops { void (*debug)(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); void *context; }; /** The user can optionally supply a custom utf8 functions, to handle comparisons and casefolding. */ struct ldb_utf8_fns { void *context; char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); }; /** Flag value for database connection mode. If LDB_FLG_RDONLY is used in ldb_connect, then the database will be opened read-only, if possible. */ #define LDB_FLG_RDONLY 1 /** Flag value for database connection mode. If LDB_FLG_NOSYNC is used in ldb_connect, then the database will be opened without synchronous operations, if possible. */ #define LDB_FLG_NOSYNC 2 /** Flag value to specify autoreconnect mode. If LDB_FLG_RECONNECT is used in ldb_connect, then the backend will be opened in a way that makes it try to auto reconnect if the connection is dropped (actually make sense only with ldap). */ #define LDB_FLG_RECONNECT 4 /** Flag to tell backends not to use mmap */ #define LDB_FLG_NOMMAP 8 /** Flag to tell ldif handlers not to force encoding of binary structures in base64 */ #define LDB_FLG_SHOW_BINARY 16 /** Flags to enable ldb tracing */ #define LDB_FLG_ENABLE_TRACING 32 /** Flags to tell LDB not to create a new database file: Without this flag ldb_tdb (for example) will create a blank file during an invocation of ldb_connect(), even when the caller only wanted read operations, for example in ldbsearch. */ #define LDB_FLG_DONT_CREATE_DB 64 /* structures for ldb_parse_tree handling code */ enum ldb_parse_op { LDB_OP_AND=1, LDB_OP_OR=2, LDB_OP_NOT=3, LDB_OP_EQUALITY=4, LDB_OP_SUBSTRING=5, LDB_OP_GREATER=6, LDB_OP_LESS=7, LDB_OP_PRESENT=8, LDB_OP_APPROX=9, LDB_OP_EXTENDED=10 }; struct ldb_parse_tree { enum ldb_parse_op operation; union { struct { struct ldb_parse_tree *child; } isnot; struct { const char *attr; struct ldb_val value; } equality; struct { const char *attr; int start_with_wildcard; int end_with_wildcard; struct ldb_val **chunks; } substring; struct { const char *attr; } present; struct { const char *attr; struct ldb_val value; } comparison; struct { const char *attr; int dnAttributes; const char *rule_id; struct ldb_val value; } extended; struct { unsigned int num_elements; struct ldb_parse_tree **elements; } list; } u; }; struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s); char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree); /** Encode a binary blob This function encodes a binary blob using the encoding rules in RFC 2254 (Section 4). This function also escapes any non-printable characters. \param mem_ctx the memory context to allocate the return string in. \param val the (potentially) binary data to be encoded \return the encoded data as a null terminated string \sa RFC 2252. */ char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val); /** Encode a string This function encodes a string using the encoding rules in RFC 2254 (Section 4). This function also escapes any non-printable characters. \param mem_ctx the memory context to allocate the return string in. \param string the string to be encoded \return the encoded data as a null terminated string \sa RFC 2252. */ char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string); /* functions for controlling attribute handling */ typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *); typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *); struct ldb_schema_attribute; typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation, const struct ldb_schema_attribute *a, const struct ldb_val *, const struct ldb_val *, bool *matched); /* attribute handler structure attr -> The attribute name ldif_read_fn -> convert from ldif to binary format ldif_write_fn -> convert from binary to ldif format canonicalise_fn -> canonicalise a value, for use by indexing and dn construction index_form_fn -> get lexicographically sorted format for index comparison_fn -> compare two values operator_fn -> override function for optimizing out unnecessary calls to canonicalise_fn and comparison_fn */ struct ldb_schema_syntax { const char *name; ldb_attr_handler_t ldif_read_fn; ldb_attr_handler_t ldif_write_fn; ldb_attr_handler_t canonicalise_fn; ldb_attr_handler_t index_format_fn; ldb_attr_comparison_t comparison_fn; ldb_attr_operator_t operator_fn; }; struct ldb_schema_attribute { const char *name; unsigned flags; const struct ldb_schema_syntax *syntax; }; const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, const char *name); struct ldb_dn_extended_syntax { const char *name; ldb_attr_handler_t read_fn; ldb_attr_handler_t write_clear_fn; ldb_attr_handler_t write_hex_fn; }; const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, const char *name); /** The attribute is not returned by default */ #define LDB_ATTR_FLAG_HIDDEN (1<<0) /* the attribute handler name should be freed when released */ #define LDB_ATTR_FLAG_ALLOCATED (1<<1) /** The attribute is supplied by the application and should not be removed */ #define LDB_ATTR_FLAG_FIXED (1<<2) /* when this is set, attempts to create two records which have the same value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS */ #define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3) /* when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION */ #define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4) /* * The values should always be base64 encoded */ #define LDB_ATTR_FLAG_FORCE_BASE64_LDIF (1<<5) /* * The attribute was loaded from a DB, rather than via the C API */ #define LDB_ATTR_FLAG_FROM_DB (1<<6) /* * The attribute is indexed */ #define LDB_ATTR_FLAG_INDEXED (1<<7) /** LDAP attribute syntax for a DN This is the well-known LDAP attribute syntax for a DN. See RFC 2252, Section 4.3.2 */ #define LDB_SYNTAX_DN "1.3.6.1.4.1.1466.115.121.1.12" /** LDAP attribute syntax for a Directory String This is the well-known LDAP attribute syntax for a Directory String. \sa RFC 2252, Section 4.3.2 */ #define LDB_SYNTAX_DIRECTORY_STRING "1.3.6.1.4.1.1466.115.121.1.15" /** LDAP attribute syntax for an integer This is the well-known LDAP attribute syntax for an integer. See RFC 2252, Section 4.3.2 */ #define LDB_SYNTAX_INTEGER "1.3.6.1.4.1.1466.115.121.1.27" /** Custom attribute syntax for an integer whose index is lexicographically ordered by attribute value in the database. */ #define LDB_SYNTAX_ORDERED_INTEGER "LDB_SYNTAX_ORDERED_INTEGER" /** LDAP attribute syntax for a boolean This is the well-known LDAP attribute syntax for a boolean. See RFC 2252, Section 4.3.2 */ #define LDB_SYNTAX_BOOLEAN "1.3.6.1.4.1.1466.115.121.1.7" /** LDAP attribute syntax for an octet string This is the well-known LDAP attribute syntax for an octet string. See RFC 2252, Section 4.3.2 */ #define LDB_SYNTAX_OCTET_STRING "1.3.6.1.4.1.1466.115.121.1.40" /** LDAP attribute syntax for UTC time. This is the well-known LDAP attribute syntax for a UTC time. See RFC 2252, Section 4.3.2 */ #define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" #define LDB_SYNTAX_GENERALIZED_TIME "1.3.6.1.4.1.1466.115.121.1.24" #define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" /* sorting helpers */ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); /* Individual controls */ /** OID for getting and manipulating attributes from the ldb without interception in the operational module. It can be used to access attribute that used to be stored in the sam and that are now calculated. */ #define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13" #define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational" /** OID for recalculate RDN (rdn attribute and 'name') control. This control forces the rdn_name module to the recalculate the rdn and name attributes as if the object was just created. */ #define LDB_CONTROL_RECALCULATE_RDN_OID "1.3.6.1.4.1.7165.4.3.30" /** OID for recalculate SD control. This control force the dsdb code to recalculate the SD of the object as if the object was just created. */ #define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5" #define LDB_CONTROL_RECALCULATE_SD_NAME "recalculate_sd" /** REVEAL_INTERNALS is used to reveal internal attributes and DN components which are not normally shown to the user */ #define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6" #define LDB_CONTROL_REVEAL_INTERNALS_NAME "reveal_internals" /** LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations that are performed by the system, but with a user's credentials, e.g. updating prefix map */ #define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7" /** LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is mainly thought to be used for the provisioning. */ #define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16" #define LDB_CONTROL_PROVISION_NAME "provision" /* AD controls */ /** OID for the paged results control. This control is included in the searchRequest and searchResultDone messages as part of the controls field of the LDAPMessage, as defined in Section 4.1.12 of LDAP v3. \sa RFC 2696. */ #define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319" #define LDB_CONTROL_PAGED_RESULTS_NAME "paged_results" /** OID for specifying the returned elements of the ntSecurityDescriptor \sa Microsoft documentation of this OID */ #define LDB_CONTROL_SD_FLAGS_OID "1.2.840.113556.1.4.801" #define LDB_CONTROL_SD_FLAGS_NAME "sd_flags" /** OID for specifying an advanced scope for the search (one partition) \sa Microsoft documentation of this OID */ #define LDB_CONTROL_DOMAIN_SCOPE_OID "1.2.840.113556.1.4.1339" #define LDB_CONTROL_DOMAIN_SCOPE_NAME "domain_scope" /** OID for specifying an advanced scope for a search \sa Microsoft documentation of this OID */ #define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340" #define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options" /** OID for notification \sa Microsoft documentation of this OID */ #define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528" #define LDB_CONTROL_NOTIFICATION_NAME "notification" /** OID for performing subtree deletes \sa Microsoft documentation of this OID */ #define LDB_CONTROL_TREE_DELETE_OID "1.2.840.113556.1.4.805" #define LDB_CONTROL_TREE_DELETE_NAME "tree_delete" /** OID for getting deleted objects \sa Microsoft documentation of this OID */ #define LDB_CONTROL_SHOW_DELETED_OID "1.2.840.113556.1.4.417" #define LDB_CONTROL_SHOW_DELETED_NAME "show_deleted" /** OID for getting recycled objects \sa Microsoft documentation of this OID */ #define LDB_CONTROL_SHOW_RECYCLED_OID "1.2.840.113556.1.4.2064" #define LDB_CONTROL_SHOW_RECYCLED_NAME "show_recycled" /** OID for getting deactivated linked attributes \sa Microsoft documentation of this OID */ #define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065" #define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME "show_deactivated_link" /** OID for extended DN \sa Microsoft documentation of this OID */ #define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" #define LDB_CONTROL_EXTENDED_DN_NAME "extended_dn" /** OID for LDAP server sort result extension. This control is included in the searchRequest message as part of the controls field of the LDAPMessage, as defined in Section 4.1.12 of LDAP v3. The controlType is set to "1.2.840.113556.1.4.473". The criticality MAY be either TRUE or FALSE (where absent is also equivalent to FALSE) at the client's option. \sa RFC 2891. */ #define LDB_CONTROL_SERVER_SORT_OID "1.2.840.113556.1.4.473" #define LDB_CONTROL_SERVER_SORT_NAME "server_sort" /** OID for LDAP server sort result response extension. This control is included in the searchResultDone message as part of the controls field of the LDAPMessage, as defined in Section 4.1.12 of LDAP v3. \sa RFC 2891. */ #define LDB_CONTROL_SORT_RESP_OID "1.2.840.113556.1.4.474" #define LDB_CONTROL_SORT_RESP_NAME "server_sort_resp" /** OID for LDAP Attribute Scoped Query extension. This control is included in SearchRequest or SearchResponse messages as part of the controls field of the LDAPMessage. */ #define LDB_CONTROL_ASQ_OID "1.2.840.113556.1.4.1504" #define LDB_CONTROL_ASQ_NAME "asq" /** OID for LDAP Directory Sync extension. This control is included in SearchRequest or SearchResponse messages as part of the controls field of the LDAPMessage. */ #define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" #define LDB_CONTROL_DIRSYNC_NAME "dirsync" #define LDB_CONTROL_DIRSYNC_EX_OID "1.2.840.113556.1.4.2090" #define LDB_CONTROL_DIRSYNC_EX_NAME "dirsync_ex" /** OID for LDAP Virtual List View Request extension. This control is included in SearchRequest messages as part of the controls field of the LDAPMessage. */ #define LDB_CONTROL_VLV_REQ_OID "2.16.840.1.113730.3.4.9" #define LDB_CONTROL_VLV_REQ_NAME "vlv" /** OID for LDAP Virtual List View Response extension. This control is included in SearchResponse messages as part of the controls field of the LDAPMessage. */ #define LDB_CONTROL_VLV_RESP_OID "2.16.840.1.113730.3.4.10" #define LDB_CONTROL_VLV_RESP_NAME "vlv_resp" /** OID to let modifies don't give an error when adding an existing attribute with the same value or deleting an nonexisting one attribute \sa Microsoft documentation of this OID */ #define LDB_CONTROL_PERMISSIVE_MODIFY_OID "1.2.840.113556.1.4.1413" #define LDB_CONTROL_PERMISSIVE_MODIFY_NAME "permissive_modify" /** OID to allow the server to be more 'fast and loose' with the data being added. \sa Microsoft documentation of this OID */ #define LDB_CONTROL_SERVER_LAZY_COMMIT "1.2.840.113556.1.4.619" /** Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23 \sa Microsoft documentation of this OID */ #define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341" #define LDB_CONTROL_RODC_DCPROMO_NAME "rodc_join" /* Other standardised controls */ /** OID for the allowing client to request temporary relaxed enforcement of constraints of the x.500 model. Mainly used for the OpenLDAP backend. \sa draft managedit. */ #define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12" #define LDB_CONTROL_RELAX_NAME "relax" /** OID for the allowing some kind of relax check for attributes with DNs \sa 3.1.1.3.4.1.16 in [MS-ADTS].pdf */ #define LDB_CONTROL_VERIFY_NAME_OID "1.2.840.113556.1.4.1338" #define LDB_CONTROL_VERIFY_NAME_NAME "verify_name" /* Extended operations */ /** OID for LDAP Extended Operation SEQUENCE_NUMBER This extended operation is used to retrieve the extended sequence number. */ #define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3" /** OID for LDAP Extended Operation PASSWORD_CHANGE. This Extended operation is used to allow user password changes by the user itself. */ #define LDB_EXTENDED_PASSWORD_CHANGE_OID "1.3.6.1.4.1.4203.1.11.1" /** OID for LDAP Extended Operation FAST_BIND This Extended operations is used to perform a fast bind. */ #define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781" /** OID for LDAP Extended Operation START_TLS. This Extended operation is used to start a new TLS channel on top of a clear text channel. */ #define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037" /** OID for LDAP Extended Operation DYNAMIC_REFRESH. This Extended operation is used to create and maintain objects which exist only a specific time, e.g. when a certain client or a certain person is logged in. Data refreshes have to be periodically sent in a specific interval. Otherwise the entry is going to be removed. */ #define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" struct ldb_sd_flags_control { /* * request the owner 0x00000001 * request the group 0x00000002 * request the DACL 0x00000004 * request the SACL 0x00000008 */ unsigned secinfo_flags; }; /* * DOMAIN_SCOPE 0x00000001 * this limits the search to one partition, * and no referrals will be returned. * (Note this doesn't limit the entries by there * objectSid belonging to a domain! Builtin and Foreign Sids * are still returned) * * PHANTOM_ROOT 0x00000002 * this search on the whole tree on a domain controller * over multiple partitions without referrals. * (This is the default behavior on the Global Catalog Port) */ #define LDB_SEARCH_OPTION_DOMAIN_SCOPE 0x00000001 #define LDB_SEARCH_OPTION_PHANTOM_ROOT 0x00000002 struct ldb_search_options_control { unsigned search_options; }; struct ldb_paged_control { int size; int cookie_len; char *cookie; }; struct ldb_extended_dn_control { int type; }; struct ldb_server_sort_control { const char *attributeName; const char *orderingRule; int reverse; }; struct ldb_sort_resp_control { int result; char *attr_desc; }; struct ldb_asq_control { int request; char *source_attribute; int src_attr_len; int result; }; struct ldb_dirsync_control { int flags; int max_attributes; int cookie_len; char *cookie; }; struct ldb_vlv_req_control { int beforeCount; int afterCount; int type; union { struct { int offset; int contentCount; } byOffset; struct { int value_len; char *value; } gtOrEq; } match; int ctxid_len; uint8_t *contextId; }; struct ldb_vlv_resp_control { int targetPosition; int contentCount; int vlv_result; int ctxid_len; uint8_t *contextId; }; struct ldb_verify_name_control { int flags; size_t gc_len; char *gc; }; struct ldb_control { const char *oid; int critical; void *data; }; enum ldb_request_type { LDB_SEARCH, LDB_ADD, LDB_MODIFY, LDB_DELETE, LDB_RENAME, LDB_EXTENDED, LDB_REQ_REGISTER_CONTROL, LDB_REQ_REGISTER_PARTITION }; enum ldb_reply_type { LDB_REPLY_ENTRY, LDB_REPLY_REFERRAL, LDB_REPLY_DONE }; enum ldb_wait_type { LDB_WAIT_ALL, LDB_WAIT_NONE }; enum ldb_state { LDB_ASYNC_INIT, LDB_ASYNC_PENDING, LDB_ASYNC_DONE }; struct ldb_extended { const char *oid; void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ }; enum ldb_sequence_type { LDB_SEQ_HIGHEST_SEQ, LDB_SEQ_HIGHEST_TIMESTAMP, LDB_SEQ_NEXT }; #define LDB_SEQ_GLOBAL_SEQUENCE 0x01 #define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02 struct ldb_seqnum_request { enum ldb_sequence_type type; }; struct ldb_seqnum_result { uint64_t seq_num; uint32_t flags; }; struct ldb_result { unsigned int count; struct ldb_message **msgs; struct ldb_extended *extended; struct ldb_control **controls; char **refs; }; struct ldb_reply { int error; enum ldb_reply_type type; struct ldb_message *message; struct ldb_extended *response; struct ldb_control **controls; char *referral; }; struct ldb_request; struct ldb_handle; struct ldb_search { struct ldb_dn *base; enum ldb_scope scope; struct ldb_parse_tree *tree; const char * const *attrs; struct ldb_result *res; }; struct ldb_add { const struct ldb_message *message; }; struct ldb_modify { const struct ldb_message *message; }; struct ldb_delete { struct ldb_dn *dn; }; struct ldb_rename { struct ldb_dn *olddn; struct ldb_dn *newdn; }; struct ldb_register_control { const char *oid; }; struct ldb_register_partition { struct ldb_dn *dn; }; typedef int (*ldb_request_callback_t)(struct ldb_request *, struct ldb_reply *); struct ldb_request { enum ldb_request_type operation; union { struct ldb_search search; struct ldb_add add; struct ldb_modify mod; struct ldb_delete del; struct ldb_rename rename; struct ldb_extended extended; struct ldb_register_control reg_control; struct ldb_register_partition reg_partition; } op; struct ldb_control **controls; void *context; ldb_request_callback_t callback; int timeout; time_t starttime; struct ldb_handle *handle; }; int ldb_request(struct ldb_context *ldb, struct ldb_request *request); int ldb_request_done(struct ldb_request *req, int status); bool ldb_request_is_done(struct ldb_request *req); int ldb_modules_wait(struct ldb_handle *handle); int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type); int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout); int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq); void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms); void ldb_set_modules_dir(struct ldb_context *ldb, const char *path); struct tevent_context; void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev); struct tevent_context * ldb_get_event_context(struct ldb_context *ldb); /** Initialise ldbs' global information This is required before any other LDB call \return 0 if initialisation succeeded, -1 otherwise */ int ldb_global_init(void); /** Initialise an ldb context This is required before any other LDB call. \param mem_ctx pointer to a talloc memory context. Pass NULL if there is no suitable context available. \note The LDB modules will be loaded from directory specified by the environment variable LDB_MODULES_PATH. If the variable is not specified, the compiled-in default is used. \return pointer to ldb_context that should be free'd (using talloc_free()) at the end of the program. */ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); typedef void (*ldb_async_timeout_fn) (void *); typedef bool (*ldb_async_callback_fn) (void *); typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn); typedef int (*ldb_async_ctx_wait_op_fn)(void *); void ldb_async_ctx_set_private_data(struct ldb_context *ldb, void *private_data); void ldb_async_ctx_set_add_op(struct ldb_context *ldb, ldb_async_ctx_add_op_fn add_op); void ldb_async_ctx_set_wait_op(struct ldb_context *ldb, ldb_async_ctx_wait_op_fn wait_op); /** Connect to a database. This is typically called soon after ldb_init(), and is required prior to any search or database modification operations. The URL can be one of the following forms: - tdb://path - ldapi://path - ldap://host - sqlite://path \param ldb the context associated with the database (from ldb_init()) \param url the URL of the database to connect to, as noted above \param flags a combination of LDB_FLG_* to modify the connection behaviour \param options backend specific options - passed uninterpreted to the backend \return result code (LDB_SUCCESS on success, or a failure code) \note It is an error to connect to a database that does not exist in readonly mode (that is, with LDB_FLG_RDONLY). However in read-write mode, the database will be created if it does not exist. */ int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]); /* return an automatic basedn from the rootDomainNamingContext of the rootDSE This value have been set in an opaque pointer at connection time */ struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb); /* return an automatic basedn from the configurationNamingContext of the rootDSE This value have been set in an opaque pointer at connection time */ struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb); /* return an automatic basedn from the schemaNamingContext of the rootDSE This value have been set in an opaque pointer at connection time */ struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb); /* return an automatic baseDN from the defaultNamingContext of the rootDSE This value have been set in an opaque pointer at connection time */ struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb); /** The default async search callback function \param req the request we are callback of \param ares a single reply from the async core \return result code (LDB_SUCCESS on success, or a failure code) \note this function expects req->context to always be an struct ldb_result pointer AND a talloc context, this function will steal on the context each message from the ares reply passed on by the async core so that in the end all the messages will be in the context (ldb_result) memory tree. Freeing the passed context (ldb_result tree) will free all the resources (the request need to be freed separately and the result doe not depend on the request that can be freed as sson as the search request is finished) */ int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares); /** The default async extended operation callback function \param req the request we are callback of \param ares a single reply from the async core \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares); int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares); /** Helper function to build a search request \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) \param mem_ctx a talloc memory context (used as parent of ret_req) \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) \param scope the search scope for the query \param expression the search expression to use for this query \param attrs the search attributes for the query (pass NULL if none required) \param controls an array of controls \param context the callback function context \param the callback function to handle the async replies \param the parent request if any \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_build_search_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *base, enum ldb_scope scope, const char *expression, const char * const *attrs, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent); int ldb_build_search_req_ex(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const *attrs, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent); /** Helper function to build an add request \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) \param mem_ctx a talloc memory context (used as parent of ret_req) \param message contains the entry to be added \param controls an array of controls \param context the callback function context \param the callback function to handle the async replies \param the parent request if any \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_build_add_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *message, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent); /** Helper function to build a modify request \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) \param mem_ctx a talloc memory context (used as parent of ret_req) \param message contains the entry to be modified \param controls an array of controls \param context the callback function context \param the callback function to handle the async replies \param the parent request if any \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_build_mod_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *message, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent); /** Helper function to build a delete request \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) \param mem_ctx a talloc memory context (used as parent of ret_req) \param dn the DN to be deleted \param controls an array of controls \param context the callback function context \param the callback function to handle the async replies \param the parent request if any \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_build_del_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent); /** Helper function to build a rename request \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) \param mem_ctx a talloc memory context (used as parent of ret_req) \param olddn the old DN \param newdn the new DN \param controls an array of controls \param context the callback function context \param the callback function to handle the async replies \param the parent request if any \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_build_rename_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *olddn, struct ldb_dn *newdn, struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent); /** Add a ldb_control to a ldb_request \param req the request struct where to add the control \param oid the object identifier of the control as string \param critical whether the control should be critical or not \param data a talloc pointer to the control specific data \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data); /** replace a ldb_control in a ldb_request \param req the request struct where to add the control \param oid the object identifier of the control as string \param critical whether the control should be critical or not \param data a talloc pointer to the control specific data \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data); /** check if a control with the specified "oid" exist and return it \param req the request struct where to add the control \param oid the object identifier of the control as string \return the control, NULL if not found */ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid); /** check if a control with the specified "oid" exist and return it \param rep the reply struct where to add the control \param oid the object identifier of the control as string \return the control, NULL if not found */ struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid); /** Search the database This function searches the database, and returns records that match an LDAP-like search expression \param ldb the context associated with the database (from ldb_init()) \param mem_ctx the memory context to use for the request and the results \param result the return result \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) \param scope the search scope for the query \param attrs the search attributes for the query (pass NULL if none required) \param exp_fmt the search expression to use for this query (printf like) \return result code (LDB_SUCCESS on success, or a failure code) \note use talloc_free() to free the ldb_result returned */ int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result **result, struct ldb_dn *base, enum ldb_scope scope, const char * const *attrs, const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8); /** Add a record to the database. This function adds a record to the database. This function will fail if a record with the specified class and key already exists in the database. \param ldb the context associated with the database (from ldb_init()) \param message the message containing the record to add. \return result code (LDB_SUCCESS if the record was added, otherwise a failure code) */ int ldb_add(struct ldb_context *ldb, const struct ldb_message *message); /** Modify the specified attributes of a record This function modifies a record that is in the database. \param ldb the context associated with the database (from ldb_init()) \param message the message containing the changes required. \return result code (LDB_SUCCESS if the record was modified as requested, otherwise a failure code) */ int ldb_modify(struct ldb_context *ldb, const struct ldb_message *message); /** Rename a record in the database This function renames a record in the database. \param ldb the context associated with the database (from ldb_init()) \param olddn the DN for the record to be renamed. \param newdn the new DN \return result code (LDB_SUCCESS if the record was renamed as requested, otherwise a failure code) */ int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn); /** Delete a record from the database This function deletes a record from the database. \param ldb the context associated with the database (from ldb_init()) \param dn the DN for the record to be deleted. \return result code (LDB_SUCCESS if the record was deleted, otherwise a failure code) */ int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn); /** The default async extended operation callback function \param req the request we are callback of \param ares a single reply from the async core \return result code (LDB_SUCCESS on success, or a failure code) \note this function expects req->context to always be an struct ldb_result pointer AND a talloc context, this function will steal on the context each message from the ares reply passed on by the async core so that in the end all the messages will be in the context (ldb_result) memory tree. Freeing the passed context (ldb_result tree) will free all the resources (the request need to be freed separately and the result doe not depend on the request that can be freed as sson as the search request is finished) */ int ldb_extended_default_callback(struct ldb_request *req, struct ldb_reply *ares); /** Helper function to build a extended request \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) \param mem_ctx a talloc memory context (used as parent of ret_req) \param oid the OID of the extended operation. \param data a void pointer a the extended operation specific parameters, it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it \param controls an array of controls \param context the callback function context \param the callback function to handle the async replies \param the parent request if any \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_build_extended_req(struct ldb_request **ret_req, struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *oid, void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ struct ldb_control **controls, void *context, ldb_request_callback_t callback, struct ldb_request *parent); /** call an extended operation \param ldb the context associated with the database (from ldb_init()) \param oid the OID of the extended operation. \param data a void pointer a the extended operation specific parameters, it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it \param res the result of the extended operation \return result code (LDB_SUCCESS if the extended operation returned fine, otherwise a failure code) */ int ldb_extended(struct ldb_context *ldb, const char *oid, void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ struct ldb_result **res); /** Obtain current/next database sequence number */ int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num); /** start a transaction */ int ldb_transaction_start(struct ldb_context *ldb); /** first phase of two phase commit */ int ldb_transaction_prepare_commit(struct ldb_context *ldb); /** commit a transaction */ int ldb_transaction_commit(struct ldb_context *ldb); /** cancel a transaction */ int ldb_transaction_cancel(struct ldb_context *ldb); /* cancel a transaction with no error if no transaction is pending used when we fork() to clear any parent transactions */ int ldb_transaction_cancel_noerr(struct ldb_context *ldb); /** return extended error information from the last call */ const char *ldb_errstring(struct ldb_context *ldb); /** return a string explaining what a ldb error constant means */ const char *ldb_strerror(int ldb_err); /** setup the default utf8 functions FIXME: these functions do not yet handle utf8 */ void ldb_set_utf8_default(struct ldb_context *ldb); /** Casefold a string \param ldb the ldb context \param mem_ctx the memory context to allocate the result string memory from. \param s the string that is to be folded \return a copy of the string, converted to upper case \note The default function is not yet UTF8 aware. Provide your own set of functions through ldb_set_utf8_fns() */ char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n); /** Check the attribute name is valid according to rfc2251 \param s the string to check \return 1 if the name is ok */ int ldb_valid_attr_name(const char *s); /* ldif manipulation functions */ /** Write an LDIF message This function writes an LDIF message using a caller supplied write function. \param ldb the ldb context (from ldb_init()) \param fprintf_fn a function pointer for the write function. This must take a private data pointer, followed by a format string, and then a variable argument list. \param private_data pointer that will be provided back to the write function. This is useful for maintaining state or context. \param ldif the message to write out \return the total number of bytes written, or an error code as returned from the write function. \sa ldb_ldif_write_file for a more convenient way to write to a file stream. \sa ldb_ldif_read for the reader equivalent to this function. */ int ldb_ldif_write(struct ldb_context *ldb, int (*fprintf_fn)(void *, const char *, ...) PRINTF_ATTRIBUTE(2,3), void *private_data, const struct ldb_ldif *ldif); /** Clean up an LDIF message This function cleans up a LDIF message read using ldb_ldif_read() or related functions (such as ldb_ldif_read_string() and ldb_ldif_read_file(). \param ldb the ldb context (from ldb_init()) \param msg the message to clean up and free */ void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *msg); /** Read an LDIF message This function creates an LDIF message using a caller supplied read function. \param ldb the ldb context (from ldb_init()) \param fgetc_fn a function pointer for the read function. This must take a private data pointer, and must return a pointer to an integer corresponding to the next byte read (or EOF if there is no more data to be read). \param private_data pointer that will be provided back to the read function. This is udeful for maintaining state or context. \return the LDIF message that has been read in \note You must free the LDIF message when no longer required, using ldb_ldif_read_free(). \sa ldb_ldif_read_file for a more convenient way to read from a file stream. \sa ldb_ldif_read_string for a more convenient way to read from a string (char array). \sa ldb_ldif_write for the writer equivalent to this function. */ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, int (*fgetc_fn)(void *), void *private_data); /** Read an LDIF message from a file This function reads the next LDIF message from the contents of a file stream. If you want to get all of the LDIF messages, you will need to repeatedly call this function, until it returns NULL. \param ldb the ldb context (from ldb_init()) \param f the file stream to read from (typically from fdopen()) \sa ldb_ldif_read_string for an equivalent function that will read from a string (char array). \sa ldb_ldif_write_file for the writer equivalent to this function. */ struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f); /** Read an LDIF message from a string This function reads the next LDIF message from the contents of a char array. If you want to get all of the LDIF messages, you will need to repeatedly call this function, until it returns NULL. \param ldb the ldb context (from ldb_init()) \param s pointer to the char array to read from \sa ldb_ldif_read_file for an equivalent function that will read from a file stream. \sa ldb_ldif_write for a more general (arbitrary read function) version of this function. */ struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); /** Parse a modrdn LDIF message from a struct ldb_message \param ldb the ldb context (from ldb_init()) \param ldif the preparsed LDIF chunk (from ldb_ldif_read()) \param mem_ctx the memory context that's used for return values \param olddn the old dn as struct ldb_dn, if not needed pass NULL \param newrdn the new rdn as struct ldb_dn, if not needed pass NULL \param deleteoldrdn the deleteoldrdn value as bool, if not needed pass NULL \param newsuperior the newsuperior dn as struct ldb_dn, if not needed pass NULL *newsuperior can be NULL as it is optional in the LDIF \param newdn the full constructed new dn as struct ldb_dn, if not needed pass NULL */ int ldb_ldif_parse_modrdn(struct ldb_context *ldb, const struct ldb_ldif *ldif, TALLOC_CTX *mem_ctx, struct ldb_dn **olddn, struct ldb_dn **newrdn, bool *deleteoldrdn, struct ldb_dn **newsuperior, struct ldb_dn **newdn); /** Write an LDIF message to a file \param ldb the ldb context (from ldb_init()) \param f the file stream to write to (typically from fdopen()) \param msg the message to write out \return the total number of bytes written, or a negative error code \sa ldb_ldif_read_file for the reader equivalent to this function. */ int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); /** Write an LDIF message to a string \param ldb the ldb context (from ldb_init()) \param mem_ctx the talloc context on which to attach the string) \param msg the message to write out \return the string containing the LDIF, or NULL on error \sa ldb_ldif_read_string for the reader equivalent to this function. */ char * ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *msg); /** Write an LDB message to a string \param ldb the ldb context (from ldb_init()) \param mem_ctx the talloc context on which to attach the string) \param changetype LDB_CHANGETYPE_ADD or LDB_CHANGETYPE_MODIFY \param msg the message to write out \return the string containing the LDIF, or NULL on error \sa ldb_ldif_message_redacted_string for a safer version of this function */ char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, enum ldb_changetype changetype, const struct ldb_message *msg); /** Write an LDB message to a string \param ldb the ldb context (from ldb_init()) \param mem_ctx the talloc context on which to attach the string) \param changetype LDB_CHANGETYPE_ADD or LDB_CHANGETYPE_MODIFY \param msg the message to write out \return the string containing the LDIF, or NULL on error, but with secret attributes redacted \note The secret attributes are specified in a 'const char * const *' within the LDB_SECRET_ATTRIBUTE_LIST opaque set on the ldb \sa ldb_ldif_message_string for an exact representiation of the message as LDIF */ char *ldb_ldif_message_redacted_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, enum ldb_changetype changetype, const struct ldb_message *msg); /** Base64 encode a buffer \param mem_ctx the memory context that the result is allocated from. \param buf pointer to the array that is to be encoded \param len the number of elements in the array to be encoded \return pointer to an array containing the encoded data \note The caller is responsible for freeing the result */ char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len); /** Base64 decode a buffer This function decodes a base64 encoded string in place. \param s the string to decode. \return the length of the returned (decoded) string. \note the string is null terminated, but the null terminator is not included in the length. */ int ldb_base64_decode(char *s); /* The following definitions come from lib/ldb/common/ldb_dn.c */ /** Get the linear form of a DN (without any extended components) \param dn The DN to linearize */ const char *ldb_dn_get_linearized(struct ldb_dn *dn); /** Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context \param dn The DN to linearize \param mem_ctx TALLOC context to return result on */ char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); /** Get the linear form of a DN (with any extended components) \param mem_ctx TALLOC context to return result on \param dn The DN to linearize \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form) */ char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode); const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name); int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val); void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list); void ldb_dn_remove_extended_components(struct ldb_dn *dn); bool ldb_dn_has_extended(struct ldb_dn *dn); int ldb_dn_extended_add_syntax(struct ldb_context *ldb, unsigned flags, const struct ldb_dn_extended_syntax *syntax); /** Allocate a new DN from a string \param mem_ctx TALLOC context to return resulting ldb_dn structure on \param dn The new DN \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct */ struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn); /** Allocate a new DN from a printf style format string and arguments \param mem_ctx TALLOC context to return resulting ldb_dn structure on \param new_fms The new DN as a format string (plus arguments) \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct */ struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4); /** Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun) \param mem_ctx TALLOC context to return resulting ldb_dn structure on \param dn The new DN \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct */ struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); /** Determine if this DN is syntactically valid \param dn The DN to validate */ bool ldb_dn_validate(struct ldb_dn *dn); char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value); const char *ldb_dn_get_casefold(struct ldb_dn *dn); char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn); int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1); bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base); bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) PRINTF_ATTRIBUTE(2,3); bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child); bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) PRINTF_ATTRIBUTE(2,3); bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num); bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num); bool ldb_dn_add_child_val(struct ldb_dn *dn, const char *rdn, struct ldb_val value); struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); int ldb_dn_get_comp_num(struct ldb_dn *dn); int ldb_dn_get_extended_comp_num(struct ldb_dn *dn); const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num); const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num); const char *ldb_dn_get_rdn_name(struct ldb_dn *dn); const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn); int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val); bool ldb_dn_is_valid(struct ldb_dn *dn); bool ldb_dn_is_special(struct ldb_dn *dn); bool ldb_dn_check_special(struct ldb_dn *dn, const char *check); bool ldb_dn_is_null(struct ldb_dn *dn); int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn); /** Compare two attributes This function compares to attribute names. Note that this is a case-insensitive comparison. \param a the first attribute name to compare \param b the second attribute name to compare \return 0 if the attribute names are the same, or only differ in case; non-zero if there are any differences attribute names are restricted by rfc2251 so using strcasecmp and toupper here is ok. return 0 for match */ #define ldb_attr_cmp(a, b) strcasecmp(a, b) char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s); int ldb_attr_dn(const char *attr); /** Create an empty message \param mem_ctx the memory context to create in. You can pass NULL to get the top level context, however the ldb context (from ldb_init()) may be a better choice */ struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx); /** Find an element within an message */ struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, const char *attr_name); /** Compare two ldb_val values \param v1 first ldb_val structure to be tested \param v2 second ldb_val structure to be tested \return 1 for a match, 0 if there is any difference */ int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2); /** find a value within an ldb_message_element \param el the element to search \param val the value to search for \note This search is case sensitive */ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, struct ldb_val *val); /** add a new empty element to a ldb_message */ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags, struct ldb_message_element **return_el); /** add a element to a ldb_message */ int ldb_msg_add(struct ldb_message *msg, const struct ldb_message_element *el, int flags); int ldb_msg_add_value(struct ldb_message *msg, const char *attr_name, const struct ldb_val *val, struct ldb_message_element **return_el); int ldb_msg_add_steal_value(struct ldb_message *msg, const char *attr_name, struct ldb_val *val); int ldb_msg_add_steal_string(struct ldb_message *msg, const char *attr_name, char *str); int ldb_msg_add_string(struct ldb_message *msg, const char *attr_name, const char *str); int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, struct ldb_dn *dn); int ldb_msg_add_fmt(struct ldb_message *msg, const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); /** compare two message elements - return 0 on match */ int ldb_msg_element_compare(struct ldb_message_element *el1, struct ldb_message_element *el2); int ldb_msg_element_compare_name(struct ldb_message_element *el1, struct ldb_message_element *el2); /** Find elements in a message. This function finds elements and converts to a specific type, with a give default value if not found. Assumes that elements are single valued. */ const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name); int ldb_msg_find_attr_as_int(const struct ldb_message *msg, const char *attr_name, int default_value); unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, const char *attr_name, unsigned int default_value); int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, const char *attr_name, int64_t default_value); uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, const char *attr_name, uint64_t default_value); double ldb_msg_find_attr_as_double(const struct ldb_message *msg, const char *attr_name, double default_value); int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, const char *attr_name, int default_value); const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, const char *attr_name, const char *default_value); struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg, const char *attr_name); void ldb_msg_sort_elements(struct ldb_message *msg); struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, const struct ldb_message *msg); struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, const struct ldb_message *msg); /* * ldb_msg_canonicalize() is now depreciated * Please use ldb_msg_normalize() instead * * NOTE: Returned ldb_message object is allocated * into *ldb's context. Callers are recommended * to steal the returned object into a TALLOC_CTX * with short lifetime. */ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, const struct ldb_message *msg) _DEPRECATED_; int ldb_msg_normalize(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg, struct ldb_message **_msg_out); /* * ldb_msg_diff() is now depreciated * Please use ldb_msg_difference() instead * * NOTE: Returned ldb_message object is allocated * into *ldb's context. Callers are recommended * to steal the returned object into a TALLOC_CTX * with short lifetime. */ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, struct ldb_message *msg1, struct ldb_message *msg2) _DEPRECATED_; /** * return a ldb_message representing the differences between msg1 and msg2. * If you then use this in a ldb_modify() call, * it can be used to save edits to a message * * Result message is constructed as follows: * - LDB_FLAG_MOD_ADD - elements found only in msg2 * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have * different value in msg1 * Value for msg2 element is used * - LDB_FLAG_MOD_DELETE - elements found only in msg2 * * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR */ int ldb_msg_difference(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg1, struct ldb_message *msg2, struct ldb_message **_msg_out); /** Tries to find a certain string attribute in a message \param msg the message to check \param name attribute name \param value attribute value \return 1 on match and 0 otherwise. */ int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value); /** Integrity check an ldb_message This function performs basic sanity / integrity checks on an ldb_message. \param ldb context in which to perform the checks \param msg the message to check \return LDB_SUCCESS if the message is OK, or a non-zero error code (one of LDB_ERR_INVALID_DN_SYNTAX, LDB_ERR_ENTRY_ALREADY_EXISTS or LDB_ERR_INVALID_ATTRIBUTE_SYNTAX) if there is a problem with a message. */ int ldb_msg_sanity_check(struct ldb_context *ldb, const struct ldb_message *msg); /** Duplicate an ldb_val structure This function copies an ldb value structure. \param mem_ctx the memory context that the duplicated value will be allocated from \param v the ldb_val to be duplicated. \return the duplicated ldb_val structure. */ struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v); /** this allows the user to set a debug function for error reporting */ int ldb_set_debug(struct ldb_context *ldb, void (*debug)(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0), void *context); /** this allows the user to set custom utf8 function for error reporting */ void ldb_set_utf8_fns(struct ldb_context *ldb, void *context, char *(*casefold)(void *, void *, const char *, size_t n)); /** this sets up debug to print messages on stderr */ int ldb_set_debug_stderr(struct ldb_context *ldb); /* control backend specific opaque values */ int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value); void *ldb_get_opaque(struct ldb_context *ldb, const char *name); const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs); const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr); int ldb_attr_in_list(const char * const *attrs, const char *attr); int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace); int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace); void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr); void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el); void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, const char *attr, const char *replace); /* shallow copy a tree - copying only the elements array so that the caller can safely add new elements without changing the message */ struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *ot); /** Convert a time structure to a string This function converts a time_t structure to an LDAP formatted GeneralizedTime string. \param mem_ctx the memory context to allocate the return string in \param t the time structure to convert \return the formatted string, or NULL if the time structure could not be converted */ char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t); /** Convert a string to a time structure This function converts an LDAP formatted GeneralizedTime string to a time_t structure. \param s the string to convert \return the time structure, or 0 if the string cannot be converted */ time_t ldb_string_to_time(const char *s); /** convert a LDAP GeneralizedTime string in ldb_val format to a time_t. */ int ldb_val_to_time(const struct ldb_val *v, time_t *t); /** Convert a time structure to a string This function converts a time_t structure to an LDAP formatted UTCTime string. \param mem_ctx the memory context to allocate the return string in \param t the time structure to convert \return the formatted string, or NULL if the time structure could not be converted */ char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t); /** Convert a string to a time structure This function converts an LDAP formatted UTCTime string to a time_t structure. \param s the string to convert \return the time structure, or 0 if the string cannot be converted */ time_t ldb_string_utc_to_time(const char *s); void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); #ifndef discard_const #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) #endif /* a wrapper around ldb_qsort() that ensures the comparison function is type safe. This will produce a compilation warning if the types don't match */ #define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison) \ do { \ if (numel > 1) { \ ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \ comparison(&((base)[0]), &((base)[1]), opaque); \ } \ } while (0) /* allow ldb to also call TYPESAFE_QSORT() */ #ifndef TYPESAFE_QSORT #define TYPESAFE_QSORT(base, numel, comparison) \ do { \ if (numel > 1) { \ qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \ comparison(&((base)[0]), &((base)[1])); \ } \ } while (0) #endif /** Convert a control into its string representation. \param mem_ctx TALLOC context to return result on, and to allocate error_string on \param control A struct ldb_control to convert \return string representation of the control */ char* ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control); /** Convert a string representing a control into a ldb_control structure \param ldb LDB context \param mem_ctx TALLOC context to return result on, and to allocate error_string on \param control_strings A string-formatted control \return a ldb_control element */ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings); /** Convert an array of string represention of a control into an array of ldb_control structures \param ldb LDB context \param mem_ctx TALLOC context to return result on, and to allocate error_string on \param control_strings Array of string-formatted controls \return array of ldb_control elements */ struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings); /** return the ldb flags */ unsigned int ldb_get_flags(struct ldb_context *ldb); /* set the ldb flags */ void ldb_set_flags(struct ldb_context *ldb, unsigned flags); struct ldb_dn *ldb_dn_binary_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val); int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val); /* debugging functions for ldb requests */ void ldb_req_set_location(struct ldb_request *req, const char *location); const char *ldb_req_location(struct ldb_request *req); /* set the location marker on a request handle - used for debugging */ #define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__) /* minimise a DN. The caller must pass in a validated DN. If the DN has an extended component then only the first extended component is kept, the DN string is stripped. The existing dn is modified */ bool ldb_dn_minimise(struct ldb_dn *dn); /* compare a ldb_val to a string */ int ldb_val_string_cmp(const struct ldb_val *v, const char *str); #endif ldb-2.0.8/include/ldb_errors.h0000660000000000000000000001673412406075657016176 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2005 ** 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 . */ /* * Name: ldb * * Component: ldb header * * Description: defines error codes following RFC 2251 ldap error codes * * Author: Simo Sorce */ #ifndef _LDB_ERRORS_H_ /*! \cond DOXYGEN_IGNORE */ #define _LDB_ERRORS_H_ 1 /*! \endcond */ /** \file ldb_errors.h This header provides a set of result codes for LDB function calls. Many LDB function calls return an integer value (int). As shown in the function documentation, those return values may indicate whether the function call worked correctly (in which case it returns LDB_SUCCESS) or some problem occurred (in which case some other value will be returned). As a special case, LDB_ERR_COMPARE_FALSE or LDB_ERR_COMPARE_TRUE may be returned, which does not indicate an error. \note Not all error codes make sense for LDB, however they are based on the LDAP error codes, and are kept for reference and to avoid overlap. \note Some of this documentation is based on information in the OpenLDAP documentation, as developed and maintained by the The OpenLDAP Project. */ /** The function call succeeded. If a function returns LDB_SUCCESS, then that function, and the underlying transactions that may have been required, completed successfully. */ #define LDB_SUCCESS 0 /** The function call failed for some non-specific reason. */ #define LDB_ERR_OPERATIONS_ERROR 1 /** The function call failed because of a protocol violation. */ #define LDB_ERR_PROTOCOL_ERROR 2 /** The function call failed because a time limit was exceeded. */ #define LDB_ERR_TIME_LIMIT_EXCEEDED 3 /** The function call failed because a size limit was exceeded. */ #define LDB_ERR_SIZE_LIMIT_EXCEEDED 4 /** The function was for value comparison, and the comparison operation returned false. \note This is a status value, and doesn't normally indicate an error. */ #define LDB_ERR_COMPARE_FALSE 5 /** The function was for value comparison, and the comparison operation returned true. \note This is a status value, and doesn't normally indicate an error. */ #define LDB_ERR_COMPARE_TRUE 6 /** The function used an authentication method that is not supported by the database. */ #define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7 /** The function call required a underlying operation that required strong authentication. This will normally only occur if you are using LDB with a LDAP backend. */ #define LDB_ERR_STRONG_AUTH_REQUIRED 8 /* 9 RESERVED */ /** The function resulted in a referral to another server. */ #define LDB_ERR_REFERRAL 10 /** The function failed because an administrative / policy limit was exceeded. */ #define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11 /** The function required an extension or capability that the database cannot provide. */ #define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12 /** The function involved a transaction or database operation that could not be performed without a secure link. */ #define LDB_ERR_CONFIDENTIALITY_REQUIRED 13 /** This is an intermediate result code for SASL bind operations that have more than one step. \note This is a result code that does not normally indicate an error has occurred. */ #define LDB_ERR_SASL_BIND_IN_PROGRESS 14 /** The function referred to an attribute type that is not present in the entry. */ #define LDB_ERR_NO_SUCH_ATTRIBUTE 16 /** The function referred to an attribute type that is invalid */ #define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17 /** The function required a filter type that is not available for the specified attribute. */ #define LDB_ERR_INAPPROPRIATE_MATCHING 18 /** The function would have violated an attribute constraint. */ #define LDB_ERR_CONSTRAINT_VIOLATION 19 /** The function involved an attribute type or attribute value that already exists in the entry. */ #define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20 /** The function used an invalid (incorrect syntax) attribute value. */ #define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21 /* 22-31 unused */ /** The function referred to an object that does not exist in the database. */ #define LDB_ERR_NO_SUCH_OBJECT 32 /** The function referred to an alias which points to a non-existent object in the database. */ #define LDB_ERR_ALIAS_PROBLEM 33 /** The function used a DN which was invalid (incorrect syntax). */ #define LDB_ERR_INVALID_DN_SYNTAX 34 /* 35 RESERVED */ /** The function required dereferencing of an alias, and something went wrong during the dereferencing process. */ #define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36 /* 37-47 unused */ /** The function passed in the wrong authentication method. */ #define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48 /** The function passed in or referenced incorrect credentials during authentication. */ #define LDB_ERR_INVALID_CREDENTIALS 49 /** The function required access permissions that the user does not possess. */ #define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50 /** The function required a transaction or call that the database could not perform because it is busy. */ #define LDB_ERR_BUSY 51 /** The function required a transaction or call to a database that is not available. */ #define LDB_ERR_UNAVAILABLE 52 /** The function required a transaction or call to a database that the database declined to perform. */ #define LDB_ERR_UNWILLING_TO_PERFORM 53 /** The function failed because it resulted in a loop being detected. */ #define LDB_ERR_LOOP_DETECT 54 /* 55-63 unused */ /** The function failed because it would have violated a naming rule. */ #define LDB_ERR_NAMING_VIOLATION 64 /** The function failed because it would have violated the schema. */ #define LDB_ERR_OBJECT_CLASS_VIOLATION 65 /** The function required an operation that is only allowed on leaf objects, but the object is not a leaf. */ #define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66 /** The function required an operation that cannot be performed on a Relative DN, but the object is a Relative DN. */ #define LDB_ERR_NOT_ALLOWED_ON_RDN 67 /** The function failed because the entry already exists. */ #define LDB_ERR_ENTRY_ALREADY_EXISTS 68 /** The function failed because modifications to an object class are not allowable. */ #define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69 /* 70 RESERVED FOR CLDAP */ /** The function failed because it needed to be applied to multiple databases. */ #define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71 /* 72-79 unused */ /** The function failed for unknown reasons. */ #define LDB_ERR_OTHER 80 /* 81-90 RESERVED for APIs */ #endif /* _LDB_ERRORS_H_ */ ldb-2.0.8/include/ldb_handlers.h0000660000000000000000000000303112406075657016444 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2005 ** 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 . */ /* * Name: ldb * * Component: ldb header * * Description: defines attribute handlers * * Author: Simo Sorce */ #ifndef __LDB_HANDLERS_H__ #define __LDB_HANDLERS_H__ int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out); int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out); int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2); int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2); #endif /* __LDB_HANDLERS_H__ */ ldb-2.0.8/include/ldb_module.h0000660000000000000000000004752013573675413016146 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2008 ** 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 . */ /* * Name: ldb * * Component: ldb module header * * Description: defines ldb modules structures and helpers * */ #ifndef _LDB_MODULE_H_ #define _LDB_MODULE_H_ #include #if defined(_SAMBA_BUILD_) && defined(USING_SYSTEM_LDB) /* * Versions before 1.2.0 doesn't define these values * so we assime 1.1.29 (which was used in Samba 4.6) * * See https://bugzilla.samba.org/show_bug.cgi?id=12859 */ #ifndef EXPECTED_SYSTEM_LDB_VERSION_MAJOR #define EXPECTED_SYSTEM_LDB_VERSION_MAJOR 1 #endif #ifndef EXPECTED_SYSTEM_LDB_VERSION_MINOR #define EXPECTED_SYSTEM_LDB_VERSION_MINOR 1 #endif #ifndef EXPECTED_SYSTEM_LDB_VERSION_MINOR #define EXPECTED_SYSTEM_LDB_VERSION_MINOR 29 #endif /* * Only Samba versions which expect ldb >= 1.4.0 * reopen the ldb after each fork(). * * See https://bugzilla.samba.org/show_bug.cgi?id=13519 */ #if EXPECTED_SYSTEM_LDB_VERSION_MAJOR > 1 #define __LDB_FORK_COMPATIBLE__ 1 #elif EXPECTED_SYSTEM_LDB_VERSION_MINOR > 3 #define __LDB_FORK_COMPATIBLE__ 1 #endif #ifndef __LDB_FORK_COMPATIBLE__ #error "Samba < 4.9 is not compatible with this version of ldb due to assumptions around fork() behaviour" #endif #endif /* defined(_SAMBA_BUILD_) && defined(USING_SYSTEM_LDB) */ struct ldb_context; struct ldb_module; /** internal flag bits on message elements. Must be within LDB_FLAG_INTERNAL_MASK */ #define LDB_FLAG_INTERNAL_DISABLE_VALIDATION 0x10 /* disable any single value checking on this attribute */ #define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20 /* attribute has failed access check and must not be exposed */ #define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x40 /* force single value checking on this attribute */ #define LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK 0x80 /* * ensure that this value is unique on an index * (despite the index not otherwise being configured as UNIQUE). * For example, all words starting with 'a' must be unique, but duplicates of * words starting with b are allowed. This is specifically for Samba's * objectSid index which is unique in the primary domain only. */ #define LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX 0x100 /* an extended match rule that always fails to match */ #define SAMBA_LDAP_MATCH_ALWAYS_FALSE "1.3.6.1.4.1.7165.4.5.1" /* The const char * const * pointer to a list of secret (password) * attributes, not to be printed in trace messages */ #define LDB_SECRET_ATTRIBUTE_LIST_OPAQUE "LDB_SECRET_ATTRIBUTE_LIST" /* * The scheme to be used for referral entries, i.e. ldap or ldaps */ #define LDAP_REFERRAL_SCHEME_OPAQUE "LDAP_REFERRAL_SCHEME" /* these function pointers define the operations that a ldb module can intercept */ struct ldb_module_ops { const char *name; int (*init_context) (struct ldb_module *); int (*search)(struct ldb_module *, struct ldb_request *); /* search */ int (*add)(struct ldb_module *, struct ldb_request *); /* add */ int (*modify)(struct ldb_module *, struct ldb_request *); /* modify */ int (*del)(struct ldb_module *, struct ldb_request *); /* delete */ int (*rename)(struct ldb_module *, struct ldb_request *); /* rename */ int (*request)(struct ldb_module *, struct ldb_request *); /* match any other operation */ int (*extended)(struct ldb_module *, struct ldb_request *); /* extended operations */ int (*start_transaction)(struct ldb_module *); int (*prepare_commit)(struct ldb_module *); int (*end_transaction)(struct ldb_module *); int (*del_transaction)(struct ldb_module *); int (*sequence_number)(struct ldb_module *, struct ldb_request *); int (*read_lock)(struct ldb_module *); int (*read_unlock)(struct ldb_module *); void *private_data; }; /* The following definitions come from lib/ldb/common/ldb_debug.c */ void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level); void ldb_vdebug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); #define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__) #define ldb_module_error(module, ecode, reason) ldb_error_at(ldb_module_get_ctx(module), ecode, reason, __FILE__, __LINE__) #define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory") #define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module)) #define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error") #define ldb_module_operr(module) ldb_error(ldb_module_get_ctx(module), LDB_ERR_OPERATIONS_ERROR, "operations error") /* The following definitions come from lib/ldb/common/ldb.c */ void ldb_request_set_state(struct ldb_request *req, int state); int ldb_request_get_status(struct ldb_request *req); unsigned int ldb_get_create_perms(struct ldb_context *ldb); const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, const char *syntax); /* The following definitions come from lib/ldb/common/ldb_attributes.c */ int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, const char *name, unsigned flags, const struct ldb_schema_syntax *syntax); int ldb_schema_attribute_add(struct ldb_context *ldb, const char *name, unsigned flags, const char *syntax); void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name); /* we allow external code to override the name -> schema_attribute function */ typedef const struct ldb_schema_attribute *(*ldb_attribute_handler_override_fn_t)(struct ldb_context *, void *, const char *); /** Allow the caller to define a callback for the attribute handler \param ldb The ldb context \param override The callback to be used for attribute lookups \param private_data Private data for the callback */ void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, ldb_attribute_handler_override_fn_t override, void *private_data); /** Allow the caller to define that the callback for the attribute handler also overrides the index list \param ldb The ldb context \param one_level_indexes Indicates that the index for SCOPE_ONELEVEL should also be maintained */ void ldb_schema_set_override_indexlist(struct ldb_context *ldb, bool one_level_indexes); /** \param ldb The ldb context \param GUID_index_attribute The globally attribute (eg objectGUID) on each entry \param GUID_index_attribute The DN component matching the globally attribute on each entry (eg GUID) The caller must ensure the supplied strings do not go out of scope (they are typically constant memory). */ void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, const char *GUID_index_attribute, const char *GUID_index_dn_component); /* A useful function to build comparison functions with */ int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx, ldb_attr_handler_t canonicalise_fn, const struct ldb_val *v1, const struct ldb_val *v2); /* The following definitions come from lib/ldb/common/ldb_controls.c */ int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); /* Returns a list of controls, except the one specified. Included * controls become a child of returned list if they were children of * controls_in */ struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, TALLOC_CTX *mem_ctx, struct ldb_control *exclude); int ldb_check_critical_controls(struct ldb_control **controls); /* The following definitions come from lib/ldb/common/ldb_ldif.c */ int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val); /* The following definitions come from lib/ldb/common/ldb_match.c */ int ldb_match_msg(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, struct ldb_dn *base, enum ldb_scope scope); int ldb_match_msg_error(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, struct ldb_dn *base, enum ldb_scope scope, bool *matched); int ldb_match_msg_objectclass(const struct ldb_message *msg, const char *objectclass); int ldb_register_extended_match_rules(struct ldb_context *ldb); /* The following definitions come from lib/ldb/common/ldb_modules.c */ struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, struct ldb_context *ldb, const char *module_name, const struct ldb_module_ops *ops); const char * ldb_module_get_name(struct ldb_module *module); struct ldb_context *ldb_module_get_ctx(struct ldb_module *module); void *ldb_module_get_private(struct ldb_module *module); void ldb_module_set_private(struct ldb_module *module, void *private_data); const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module); int ldb_next_request(struct ldb_module *module, struct ldb_request *request); int ldb_next_start_trans(struct ldb_module *module); int ldb_next_end_trans(struct ldb_module *module); int ldb_next_del_trans(struct ldb_module *module); int ldb_next_prepare_commit(struct ldb_module *module); int ldb_next_init(struct ldb_module *module); int ldb_next_read_lock(struct ldb_module *module); int ldb_next_read_unlock(struct ldb_module *module); void ldb_set_errstring(struct ldb_context *ldb, const char *err_string); void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3); void ldb_reset_err_string(struct ldb_context *ldb); int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line); const char *ldb_default_modules_dir(void); int ldb_register_module(const struct ldb_module_ops *); typedef int (*ldb_connect_fn)(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[], struct ldb_module **module); /** Require that LDB use a private event context for each request A private event context may need to be created to avoid nested event loops during ldb_tdb with the locks held. This indicates that a backend is in use that requires this to hold locks safely. \param handle The ldb handle to set the flag on */ void ldb_set_require_private_event_context(struct ldb_context *ldb); struct ldb_backend_ops { const char *name; ldb_connect_fn connect_fn; }; const char *ldb_default_modules_dir(void); int ldb_register_backend(const char *url_prefix, ldb_connect_fn, bool); struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); /** Obtains the private event context for the handle, A private event context may have been created to avoid nested event loops during ldb_tdb with the locks held. Otherwise return the global one. \param handle The ldb handle to obtain the event context for \return the tevent event context for this handle (private or global) */ struct tevent_context *ldb_handle_get_event_context(struct ldb_handle *handle); int ldb_module_send_entry(struct ldb_request *req, struct ldb_message *msg, struct ldb_control **ctrls); int ldb_module_send_referral(struct ldb_request *req, char *ref); int ldb_module_done(struct ldb_request *req, struct ldb_control **ctrls, struct ldb_extended *response, int error); int ldb_mod_register_control(struct ldb_module *module, const char *oid); void ldb_set_default_dns(struct ldb_context *ldb); /** Add a ldb_control to a ldb_reply \param ares the reply struct where to add the control \param oid the object identifier of the control as string \param critical whether the control should be critical or not \param data a talloc pointer to the control specific data \return result code (LDB_SUCCESS on success, or a failure code) */ int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data); /** mark a request as untrusted. This tells the rootdse module to remove unregistered controls \param req the request to mark as untrusted */ void ldb_req_mark_untrusted(struct ldb_request *req); /** mark a request as trusted. This tells the rootdse module to allow unregistered controls \param req the request to mark as trusted */ void ldb_req_mark_trusted(struct ldb_request *req); /** return true is a request is untrusted This indicates the request came across a trust boundary for example over LDAP \param req the request check \return is req trusted */ bool ldb_req_is_untrusted(struct ldb_request *req); /** set custom flags. Those flags are set by applications using ldb, they are application dependent and the same bit can have different meaning in different application. */ void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags); /** get custom flags. Those flags are set by applications using ldb, they are application dependent and the same bit can have different meaning in different application. */ uint32_t ldb_req_get_custom_flags(struct ldb_request *req); /* load all modules from the given directory */ int ldb_modules_load(const char *modules_path, const char *version); /* init functions prototype */ typedef int (*ldb_module_init_fn)(const char *); /* general ldb hook function */ enum ldb_module_hook_type { LDB_MODULE_HOOK_CMDLINE_OPTIONS = 1, LDB_MODULE_HOOK_CMDLINE_PRECONNECT = 2, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT = 3 }; typedef int (*ldb_hook_fn)(struct ldb_context *, enum ldb_module_hook_type ); /* register a ldb hook function */ int ldb_register_hook(ldb_hook_fn hook_fn); /* call ldb hooks of a given type */ int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t); #define LDB_MODULE_CHECK_VERSION(version) do { \ if (strcmp(version, LDB_VERSION) != 0) { \ fprintf(stderr, "ldb: module version mismatch in %s : ldb_version=%s module_version=%s\n", \ __FILE__, version, LDB_VERSION); \ return LDB_ERR_UNAVAILABLE; \ }} while (0) /* return a string representation of the calling chain for the given ldb request */ char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx); /* return the next module in the chain */ struct ldb_module *ldb_module_next(struct ldb_module *module); /* set the next module in the module chain */ void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next); /* load a list of modules */ int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out); /* get the popt_options pointer in the ldb structure. This allows a ldb module to change the command line parsing */ struct poptOption **ldb_module_popt_options(struct ldb_context *ldb); /* modules are called in inverse order on the stack. Lets place them as an admin would think the right order is. Modules order is important */ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); /* return the current ldb flags LDB_FLG_* */ uint32_t ldb_module_flags(struct ldb_context *ldb); int ldb_module_connect_backend(struct ldb_context *ldb, const char *url, const char *options[], struct ldb_module **backend_module); /* initialise a chain of modules */ int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module); /* * prototype for the init function defined by dynamically loaded modules */ int ldb_init_module(const char *version); /* replace the components of a DN with those from another DN, without * touching the extended components * * return true if successful and false if not * if false is returned the dn may be marked invalid */ bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn); /* walk a parse tree, calling the provided callback on each node */ int ldb_parse_tree_walk(struct ldb_parse_tree *tree, int (*callback)(struct ldb_parse_tree *tree, void *), void *private_context); /* compare two message elements with ordering - used by modify */ bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1, const struct ldb_message_element *el2); struct ldb_extended_match_rule { const char *oid; int (*callback)(struct ldb_context *, const char *oid, const struct ldb_message *, const char *, const struct ldb_val *, bool *); }; int ldb_register_extended_match_rule(struct ldb_context *ldb, const struct ldb_extended_match_rule *rule); /* * these pack/unpack functions are exposed in the library for use by * ldb tools like ldbdump and for use in tests, * but are not part of the public API */ int ldb_pack_data(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_val *data, uint32_t pack_format_version); /* * Unpack a ldb message from a linear buffer in ldb_val */ int ldb_unpack_data(struct ldb_context *ldb, const struct ldb_val *data, struct ldb_message *message); /* * filter the specified list of attributes from msg, * adding requested attributes, and perhaps all for *, * but not the DN to filtered_msg. */ int ldb_filter_attrs(struct ldb_context *ldb, const struct ldb_message *msg, const char *const *attrs, struct ldb_message *filtered_msg); /* * Unpack a ldb message from a linear buffer in ldb_val * * If LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC is specified, then values * array are not allocated individually (for single-valued * attributes), instead they point into a single buffer per message. * * Likewise if LDB_UNPACK_DATA_FLAG_NO_DN is specified, the DN is omitted. * * If LDB_UNPACK_DATA_FLAG_NO_ATTRS is specified, then no attributes * are unpacked or returned. * */ int ldb_unpack_data_flags(struct ldb_context *ldb, const struct ldb_val *data, struct ldb_message *message, unsigned int flags); int ldb_unpack_get_format(const struct ldb_val *data, uint32_t *pack_format_version); /* currently unused (was NO_DATA_ALLOC) 0x0001 */ #define LDB_UNPACK_DATA_FLAG_NO_DN 0x0002 #define LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC 0x0004 #define LDB_UNPACK_DATA_FLAG_NO_ATTRS 0x0008 #define LDB_UNPACK_DATA_FLAG_READ_LOCKED 0x0010 enum ldb_pack_format { /* Old packing format (based on a somewhat arbitrary date) */ LDB_PACKING_FORMAT_NODN = 0x26011966, /* In-use packing formats */ LDB_PACKING_FORMAT, LDB_PACKING_FORMAT_V2 }; /** Forces a specific ldb handle to use the global event context. This allows a nested event loop to operate, so any open transaction also needs to be aborted. Any events on this event context will be lost. This is used in Samba when sending an IRPC to another part of the same process instead of making a local DB modification. \param handle The ldb handle to force to use the global context */ void ldb_handle_use_global_event_context(struct ldb_handle *handle); /** * Get the options passed to ldb_connect. * * This allows the options to be inspected by elements in the module stack * */ const char **ldb_options_get(struct ldb_context *ldb); #endif ldb-2.0.8/include/ldb_private.h0000660000000000000000000002334313573675413016330 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 Copyright (C) Stefan Metzmacher 2004 Copyright (C) Simo Sorce 2004-2005 ** 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 . */ /* * Name: ldb * * Component: ldb private header * * Description: defines internal ldb structures used by the subsystem and modules * * Author: Andrew Tridgell * Author: Stefan Metzmacher */ #ifndef _LDB_PRIVATE_H_ #define _LDB_PRIVATE_H_ 1 #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb.h" #include "ldb_module.h" struct ldb_context; struct ldb_module_ops; struct ldb_backend_ops; #define LDB_HANDLE_FLAG_DONE_CALLED 1 /* call is from an untrusted source - eg. over ldap:// */ #define LDB_HANDLE_FLAG_UNTRUSTED 2 struct ldb_handle { int status; enum ldb_state state; struct ldb_context *ldb; unsigned flags; /* flags dedicated to be set by application using ldb */ uint32_t custom_flags; unsigned nesting; /* Private event context (if not NULL) */ struct tevent_context *event_context; /* used for debugging */ struct ldb_request *parent; const char *location; }; /* basic module structure */ struct ldb_module { struct ldb_module *prev, *next; struct ldb_context *ldb; void *private_data; const struct ldb_module_ops *ops; }; /* schema related information needed for matching rules */ struct ldb_schema { void *attribute_handler_override_private; ldb_attribute_handler_override_fn_t attribute_handler_override; /* attribute handling table */ unsigned num_attributes; struct ldb_schema_attribute *attributes; unsigned num_dn_extended_syntax; struct ldb_dn_extended_syntax *dn_extended_syntax; /* * If set, the attribute_handler_override has the details of * what attributes have an index */ bool index_handler_override; bool one_level_indexes; const char *GUID_index_attribute; const char *GUID_index_dn_component; }; /* every ldb connection is started by establishing a ldb_context */ struct ldb_context { /* the operations provided by the backend */ struct ldb_module *modules; /* debugging operations */ struct ldb_debug_ops debug_ops; /* extended matching rules */ struct ldb_extended_match_entry { const struct ldb_extended_match_rule *rule; struct ldb_extended_match_entry *prev, *next; } *extended_match_rules; /* custom utf8 functions */ struct ldb_utf8_fns utf8_fns; /* backend specific opaque parameters */ struct ldb_opaque { struct ldb_opaque *next; const char *name; void *value; } *opaque; struct ldb_schema schema; char *err_string; int transaction_active; int default_timeout; unsigned int flags; unsigned int create_perms; struct tevent_context *ev_ctx; /* * If the backend holds locks, we must not use a global event * context, so this flag will be set and ldb_handle_new() will * build a new event context */ bool require_private_event_context; bool prepare_commit_done; char *partial_debug; struct poptOption *popt_options; /* * The ldb options passed to ldb_connect * A NULL terminated array of zero terminated strings */ const char **options; }; /* The following definitions come from lib/ldb/common/ldb.c */ extern const struct ldb_module_ops ldb_objectclass_module_ops; extern const struct ldb_module_ops ldb_paged_results_module_ops; extern const struct ldb_module_ops ldb_rdn_name_module_ops; extern const struct ldb_module_ops ldb_schema_module_ops; extern const struct ldb_module_ops ldb_asq_module_ops; extern const struct ldb_module_ops ldb_server_sort_module_ops; extern const struct ldb_module_ops ldb_ldap_module_ops; extern const struct ldb_module_ops ldb_ildap_module_ops; extern const struct ldb_module_ops ldb_paged_searches_module_ops; extern const struct ldb_module_ops ldb_tdb_module_ops; extern const struct ldb_module_ops ldb_skel_module_ops; extern const struct ldb_module_ops ldb_subtree_rename_module_ops; extern const struct ldb_module_ops ldb_subtree_delete_module_ops; extern const struct ldb_module_ops ldb_sqlite3_module_ops; extern const struct ldb_module_ops ldb_wins_ldb_module_ops; extern const struct ldb_module_ops ldb_ranged_results_module_ops; extern const struct ldb_backend_ops ldb_tdb_backend_ops; extern const struct ldb_backend_ops ldb_sqlite3_backend_ops; extern const struct ldb_backend_ops ldb_ldap_backend_ops; extern const struct ldb_backend_ops ldb_ldapi_backend_ops; extern const struct ldb_backend_ops ldb_ldaps_backend_ops; int ldb_setup_wellknown_attributes(struct ldb_context *ldb); /* remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context This is to permit correct reloads */ void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag); int ldb_schema_attribute_fill_with_syntax(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *attribute, unsigned flags, const struct ldb_schema_syntax *syntax, struct ldb_schema_attribute *a); const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname); void ldb_subclass_remove(struct ldb_context *ldb, const char *classname); int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass); /* The following definitions come from lib/ldb/common/ldb_utf8.c */ char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); /* The following definitions come from lib/ldb/common/ldb_modules.c */ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); int ldb_load_modules(struct ldb_context *ldb, const char *options[]); struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str); /* The following definitions come from lib/ldb/common/ldb_options.c */ const char *ldb_options_find(struct ldb_context *ldb, const char *options[], const char *option_name); const char **ldb_options_copy(TALLOC_CTX *ctx, const char *options[]); /* The following definitions come from lib/ldb/common/ldb_ldif.c */ struct ldif_read_file_state { FILE *f; size_t line_no; }; struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, struct ldif_read_file_state *state); char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *ldif); /* * Get the LDB context in use on an LDB DN. * * This is helpful to the python LDB code, which may use as part of * adding base and child components to an existing DN. */ struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn); #define LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES 1 /** Determine whether any values in an element are also in another element, and optionally fix that. \param ldb an ldb context \param mem_ctx a talloc context \param el an element \param other_el another element \param options flags controlling the function behaviour Without the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS if the elements share values, and LDB_SUCCESS if they don't. That is, determine whether there is an intersection without changing anything. With the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, any values in common are removed from the first element and LDB_SUCCESS is returned. LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown option. LDB_ERR_INAPPROPRIATE_MATCHING means the elements differ in name. */ int ldb_msg_find_common_values(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_message_element *el, struct ldb_message_element *other_el, uint32_t options); /** Detect whether an element contains duplicate values \param ldb a currently unused ldb_context struct \param mem_ctx a talloc context \param el the element to search \param duplicate will point to a duplicate value if there are duplicates, or NULL otherwise. \param options is a flags field. All values are reserved. \return an ldb error code. LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown option flag. Otherwise LDB_SUCCESS. \note This search is case sensitive */ int ldb_msg_find_duplicate_val(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message_element *el, struct ldb_val **duplicate, uint32_t options); /** Check if a particular message will match the given filter \param ldb an ldb context \param msg the message to be checked \param tree the filter tree to check against \param scope the scope to match against (to avoid matching special DNs except on a base search) \param matched a pointer to a boolean set true if it matches, false otherwise returns LDB_SUCCESS or an error \note this is a recursive function, and does short-circuit evaluation */ int ldb_match_message(struct ldb_context *ldb, const struct ldb_message *msg, const struct ldb_parse_tree *tree, enum ldb_scope scope, bool *matched); #endif ldb-2.0.8/ldb.pc.in0000660000000000000000000000056412406075657013731 0ustar rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ modulesdir=@LDB_MODULESDIR@ Name: ldb Description: An LDAP-like embedded database Version: @PACKAGE_VERSION@ Requires.private: tdb Requires: talloc Libs: @LIB_RPATH@ -L${libdir} -lldb Libs.private: @LDAP_LIBS@ Cflags: -I${includedir} Modulesdir: ${modulesdir} URL: http://ldb.samba.org/ ldb-2.0.8/ldb_key_value/ldb_kv.c0000660000000000000000000016130113573675413016450 0ustar rootroot00000000000000/* 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 . */ /* * Name: ldb_kv * * Component: ldb key value backend * * Description: core functions for ldb key value 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_kv.h" #include "ldb_private.h" #include "lib/util/attr.h" /* prevent memory errors on callbacks */ struct ldb_kv_req_spy { struct ldb_kv_context *ctx; }; /* * Determine if this key could hold a record. We allow the new GUID * index, the old DN index and a possible future ID= */ bool ldb_kv_key_is_normal_record(struct ldb_val key) { if (key.length < 4) { return false; } /* * @ records are not normal records, we don't want to index * them nor search on them */ if (key.length > 4 && memcmp(key.data, "DN=@", 4) == 0) { return false; } /* All other DN= records are however */ if (memcmp(key.data, "DN=", 3) == 0) { return true; } if (memcmp(key.data, "ID=", 3) == 0) { return true; } if (key.length < sizeof(LDB_KV_GUID_KEY_PREFIX)) { return false; } if (memcmp(key.data, LDB_KV_GUID_KEY_PREFIX, sizeof(LDB_KV_GUID_KEY_PREFIX) - 1) == 0) { return true; } return false; } /* form a ldb_val for a record key caller frees note that the key for a record can depend on whether the dn refers to a case sensitive index record or not */ struct ldb_val ldb_kv_key_dn(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { struct ldb_val key; char *key_str = NULL; const char *dn_folded = NULL; /* most DNs are case insensitive. The exception is index DNs for case sensitive attributes there are 3 cases dealt with in this code: 1) if the dn doesn't start with @ then uppercase the attribute names and the attributes values of case insensitive attributes 2) if the dn starts with @ then leave it alone - the indexing code handles the rest */ dn_folded = ldb_dn_get_casefold(dn); if (!dn_folded) { goto failed; } key_str = talloc_strdup(mem_ctx, "DN="); if (!key_str) { goto failed; } key_str = talloc_strdup_append_buffer(key_str, dn_folded); if (!key_str) { goto failed; } key.data = (uint8_t *)key_str; key.length = strlen(key_str) + 1; return key; failed: errno = ENOMEM; key.data = NULL; key.length = 0; return key; } /* The caller is to provide a correctly sized key */ int ldb_kv_guid_to_key(const struct ldb_val *GUID_val, struct ldb_val *key) { const char *GUID_prefix = LDB_KV_GUID_KEY_PREFIX; const int GUID_prefix_len = sizeof(LDB_KV_GUID_KEY_PREFIX) - 1; if (key->length != (GUID_val->length+GUID_prefix_len)) { return LDB_ERR_OPERATIONS_ERROR; } memcpy(key->data, GUID_prefix, GUID_prefix_len); memcpy(&key->data[GUID_prefix_len], GUID_val->data, GUID_val->length); return LDB_SUCCESS; } /* * The caller is to provide a correctly sized key, used only in * the GUID index mode */ int ldb_kv_idx_to_key(struct ldb_module *module, struct ldb_kv_private *ldb_kv, TALLOC_CTX *mem_ctx, const struct ldb_val *idx_val, struct ldb_val *key) { struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_dn *dn; if (ldb_kv->cache->GUID_index_attribute != NULL) { return ldb_kv_guid_to_key(idx_val, key); } dn = ldb_dn_from_ldb_val(mem_ctx, ldb, idx_val); if (dn == NULL) { /* * LDB_ERR_INVALID_DN_SYNTAX would just be confusing * to the caller, as this in an invalid index value */ return LDB_ERR_OPERATIONS_ERROR; } /* form the key */ *key = ldb_kv_key_dn(mem_ctx, dn); TALLOC_FREE(dn); if (!key->data) { return ldb_module_oom(module); } return LDB_SUCCESS; } /* form a TDB_DATA for a record key caller frees mem_ctx, which may or may not have the key as a child. note that the key for a record can depend on whether a GUID index is in use, or the DN is used as the key */ struct ldb_val ldb_kv_key_msg(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct ldb_message *msg) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_val key; const struct ldb_val *guid_val; int ret; if (ldb_kv->cache->GUID_index_attribute == NULL) { return ldb_kv_key_dn(mem_ctx, msg->dn); } if (ldb_dn_is_special(msg->dn)) { return ldb_kv_key_dn(mem_ctx, msg->dn); } guid_val = ldb_msg_find_ldb_val(msg, ldb_kv->cache->GUID_index_attribute); if (guid_val == NULL) { ldb_asprintf_errstring(ldb_module_get_ctx(module), "Did not find GUID attribute %s " "in %s, required for TDB record " "key in " LDB_KV_IDXGUID " mode.", ldb_kv->cache->GUID_index_attribute, ldb_dn_get_linearized(msg->dn)); errno = EINVAL; key.data = NULL; key.length = 0; return key; } /* In this case, allocate with talloc */ key.data = talloc_size(mem_ctx, LDB_KV_GUID_KEY_SIZE); if (key.data == NULL) { errno = ENOMEM; key.data = NULL; key.length = 0; return key; } key.length = talloc_get_size(key.data); ret = ldb_kv_guid_to_key(guid_val, &key); if (ret != LDB_SUCCESS) { errno = EINVAL; key.data = NULL; key.length = 0; return key; } return key; } /* check special dn's have valid attributes currently only @ATTRIBUTES is checked */ static int ldb_kv_check_special_dn(struct ldb_module *module, const struct ldb_message *msg) { struct ldb_context *ldb = ldb_module_get_ctx(module); unsigned int i, j; if (! ldb_dn_is_special(msg->dn) || ! ldb_dn_check_special(msg->dn, LDB_KV_ATTRIBUTES)) { return LDB_SUCCESS; } /* we have @ATTRIBUTES, let's check attributes are fine */ /* should we check that we deny multivalued attributes ? */ for (i = 0; i < msg->num_elements; i++) { if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue; for (j = 0; j < msg->elements[i].num_values; j++) { if (ldb_kv_check_at_attributes_values( &msg->elements[i].values[j]) != 0) { ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry"); return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } } } return LDB_SUCCESS; } /* * Called after modifies and when starting a transaction. Checks target pack * format version and current pack format version, which are set by cache_load, * and repacks if necessary. */ static int ldb_kv_maybe_repack(struct ldb_kv_private *ldb_kv) { /* Override option taken from ldb options */ if (ldb_kv->pack_format_override != 0) { ldb_kv->target_pack_format_version = ldb_kv->pack_format_override; } if (ldb_kv->pack_format_version != ldb_kv->target_pack_format_version) { int r; struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); r = ldb_kv_repack(ldb_kv->module); if (r != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Database repack failed."); } return r; } return LDB_SUCCESS; } /* we've made a modification to a dn - possibly reindex and update sequence number */ static int ldb_kv_modified(struct ldb_module *module, struct ldb_dn *dn) { int ret = LDB_SUCCESS; struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); /* only allow modifies inside a transaction, otherwise the * ldb is unsafe */ if (ldb_kv->kv_ops->transaction_active(ldb_kv) == false) { ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction"); return LDB_ERR_OPERATIONS_ERROR; } if (ldb_dn_is_special(dn) && (ldb_dn_check_special(dn, LDB_KV_INDEXLIST) || ldb_dn_check_special(dn, LDB_KV_ATTRIBUTES)) ) { if (ldb_kv->warn_reindex) { ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, "Reindexing %s due to modification on %s", ldb_kv->kv_ops->name(ldb_kv), ldb_dn_get_linearized(dn)); } ret = ldb_kv_reindex(module); } /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */ if (ret == LDB_SUCCESS && !(ldb_dn_is_special(dn) && ldb_dn_check_special(dn, LDB_KV_BASEINFO)) ) { ret = ldb_kv_increase_sequence_number(module); } /* If the modify was to @OPTIONS, reload the cache */ if (ret == LDB_SUCCESS && ldb_dn_is_special(dn) && (ldb_dn_check_special(dn, LDB_KV_OPTIONS)) ) { ret = ldb_kv_cache_reload(module); } if (ret != LDB_SUCCESS) { ldb_kv->reindex_failed = true; } return ret; } /* store a record into the db */ int ldb_kv_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_val key; struct ldb_val ldb_data; int ret = LDB_SUCCESS; TALLOC_CTX *key_ctx = talloc_new(module); if (key_ctx == NULL) { return ldb_module_oom(module); } if (ldb_kv->read_only) { talloc_free(key_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; } key = ldb_kv_key_msg(module, key_ctx, msg); if (key.data == NULL) { TALLOC_FREE(key_ctx); return LDB_ERR_OTHER; } ret = ldb_pack_data(ldb_module_get_ctx(module), msg, &ldb_data, ldb_kv->pack_format_version); if (ret == -1) { TALLOC_FREE(key_ctx); return LDB_ERR_OTHER; } ret = ldb_kv->kv_ops->store(ldb_kv, key, ldb_data, flgs); if (ret != 0) { bool is_special = ldb_dn_is_special(msg->dn); ret = ldb_kv->kv_ops->error(ldb_kv); /* * LDB_ERR_ENTRY_ALREADY_EXISTS means the DN, not * the GUID, so re-map */ if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS && !is_special && ldb_kv->cache->GUID_index_attribute != NULL) { ret = LDB_ERR_CONSTRAINT_VIOLATION; } goto done; } done: TALLOC_FREE(key_ctx); talloc_free(ldb_data.data); return ret; } /* check if a attribute is a single valued, for a given element */ static bool ldb_kv_single_valued(const struct ldb_schema_attribute *a, struct ldb_message_element *el) { if (!a) return false; if (el != NULL) { if (el->flags & LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK) { /* override from a ldb module, for example used for the description field, which is marked multi-valued in the schema but which should not actually accept multiple values */ return true; } if (el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK) { /* override from a ldb module, for example used for deleted linked attribute entries */ return false; } } if (a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { return true; } return false; } /* * Starts a sub transaction if they are supported by the backend * and the ldb connection has not been opened in batch mode. */ static int ldb_kv_sub_transaction_start(struct ldb_kv_private *ldb_kv) { int ret = LDB_SUCCESS; if (ldb_kv->batch_mode) { return ret; } ret = ldb_kv->kv_ops->begin_nested_write(ldb_kv); if (ret == LDB_SUCCESS) { ret = ldb_kv_index_sub_transaction_start(ldb_kv); } return ret; } /* * Commits a sub transaction if they are supported by the backend * and the ldb connection has not been opened in batch mode. */ static int ldb_kv_sub_transaction_commit(struct ldb_kv_private *ldb_kv) { int ret = LDB_SUCCESS; if (ldb_kv->batch_mode) { return ret; } ret = ldb_kv_index_sub_transaction_commit(ldb_kv); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_kv->kv_ops->finish_nested_write(ldb_kv); return ret; } /* * Cancels a sub transaction if they are supported by the backend * and the ldb connection has not been opened in batch mode. */ static int ldb_kv_sub_transaction_cancel(struct ldb_kv_private *ldb_kv) { int ret = LDB_SUCCESS; if (ldb_kv->batch_mode) { return ret; } ret = ldb_kv_index_sub_transaction_cancel(ldb_kv); if (ret != LDB_SUCCESS) { struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); /* * In the event of a failure we log the failure and continue * as we need to cancel the database transaction. */ ldb_debug(ldb, LDB_DEBUG_ERROR, __location__": ldb_kv_index_sub_transaction_cancel " "failed: %s", ldb_errstring(ldb)); } ret = ldb_kv->kv_ops->abort_nested_write(ldb_kv); return ret; } static int ldb_kv_add_internal(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, bool check_single_value) { 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;inum_elements;i++) { struct ldb_message_element *el = &msg->elements[i]; const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); if (el->num_values == 0) { ldb_asprintf_errstring(ldb, "attribute '%s' on '%s' specified, but with 0 values (illegal)", el->name, ldb_dn_get_linearized(msg->dn)); return LDB_ERR_CONSTRAINT_VIOLATION; } if (check_single_value && el->num_values > 1 && ldb_kv_single_valued(a, el)) { ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", el->name, ldb_dn_get_linearized(msg->dn)); return LDB_ERR_CONSTRAINT_VIOLATION; } /* Do not check "@ATTRIBUTES" for duplicated values */ if (ldb_dn_is_special(msg->dn) && ldb_dn_check_special(msg->dn, LDB_KV_ATTRIBUTES)) { continue; } if (check_single_value && !(el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { struct ldb_val *duplicate = NULL; ret = ldb_msg_find_duplicate_val(ldb, discard_const(msg), el, &duplicate, 0); if (ret != LDB_SUCCESS) { return ret; } if (duplicate != NULL) { ldb_asprintf_errstring( ldb, "attribute '%s': value '%.*s' on '%s' " "provided more than once in ADD object", el->name, (int)duplicate->length, duplicate->data, ldb_dn_get_linearized(msg->dn)); return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } } } ret = ldb_kv_store(module, msg, TDB_INSERT); if (ret != LDB_SUCCESS) { /* * Try really hard to get the right error code for * a re-add situation, as this can matter! */ if (ret == LDB_ERR_CONSTRAINT_VIOLATION) { int ret2; struct ldb_dn *dn2 = NULL; TALLOC_CTX *mem_ctx = talloc_new(module); if (mem_ctx == NULL) { return ldb_module_operr(module); } ret2 = ldb_kv_search_base(module, mem_ctx, msg->dn, &dn2); TALLOC_FREE(mem_ctx); if (ret2 == LDB_SUCCESS) { ret = LDB_ERR_ENTRY_ALREADY_EXISTS; } } if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { ldb_asprintf_errstring(ldb, "Entry %s already exists", ldb_dn_get_linearized(msg->dn)); } return ret; } ret = ldb_kv_index_add_new(module, ldb_kv, msg); if (ret != LDB_SUCCESS) { /* * If we failed to index, delete the message again. * * This is particularly important for the GUID index * case, which will only fail for a duplicate DN * in the index add. * * Note that the caller may not cancel the transation * and this means the above add might really show up! */ ldb_kv_delete_noindex(module, msg); return ret; } ret = ldb_kv_modified(module, msg->dn); /* * To allow testing of the error recovery code in ldb_kv_add * cmocka tests can define CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL * to inject failures at this point. */ #ifdef CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL #endif return ret; } /* add a record to the database */ static int ldb_kv_add(struct ldb_kv_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int ret = LDB_SUCCESS; if (ldb_kv->max_key_length != 0 && ldb_kv->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 " LDB_KV_IDXGUID " not set."); return LDB_ERR_UNWILLING_TO_PERFORM; } ret = ldb_kv_check_special_dn(module, req->op.add.message); if (ret != LDB_SUCCESS) { return ret; } ldb_request_set_state(req, LDB_ASYNC_PENDING); if (ldb_kv_cache_load(module) != 0) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_sub_transaction_start(ldb_kv); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_kv_add_internal(module, ldb_kv, req->op.add.message, true); if (ret != LDB_SUCCESS) { int r = ldb_kv_sub_transaction_cancel(ldb_kv); if (r != LDB_SUCCESS) { ldb_debug( ldb_module_get_ctx(module), LDB_DEBUG_FATAL, __location__ ": Unable to roll back sub transaction"); } ldb_kv->operation_failed = true; return ret; } ret = ldb_kv_sub_transaction_commit(ldb_kv); return ret; } /* delete a record from the database, not updating indexes (used for deleting index records) */ int ldb_kv_delete_noindex(struct ldb_module *module, const struct ldb_message *msg) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_val key; int ret; TALLOC_CTX *tdb_key_ctx = talloc_new(module); if (tdb_key_ctx == NULL) { return ldb_module_oom(module); } if (ldb_kv->read_only) { talloc_free(tdb_key_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; } key = ldb_kv_key_msg(module, tdb_key_ctx, msg); if (!key.data) { TALLOC_FREE(tdb_key_ctx); return LDB_ERR_OTHER; } ret = ldb_kv->kv_ops->delete(ldb_kv, key); TALLOC_FREE(tdb_key_ctx); if (ret != 0) { ret = ldb_kv->kv_ops->error(ldb_kv); } return ret; } static int ldb_kv_delete_internal(struct ldb_module *module, struct ldb_dn *dn) { struct ldb_message *msg; int ret = LDB_SUCCESS; msg = ldb_msg_new(module); if (msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* in case any attribute of the message was indexed, we need to fetch the old record */ ret = ldb_kv_search_dn1(module, dn, msg, 0); if (ret != LDB_SUCCESS) { /* not finding the old record is an error */ goto done; } ret = ldb_kv_delete_noindex(module, msg); if (ret != LDB_SUCCESS) { goto done; } /* remove any indexed attributes */ ret = ldb_kv_index_delete(module, msg); if (ret != LDB_SUCCESS) { goto done; } ret = ldb_kv_modified(module, dn); if (ret != LDB_SUCCESS) { goto done; } done: talloc_free(msg); /* * To allow testing of the error recovery code in ldb_kv_delete * cmocka tests can define CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL * to inject failures at this point. */ #ifdef CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL #endif return ret; } /* delete a record from the database */ static int ldb_kv_delete(struct ldb_kv_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int ret = LDB_SUCCESS; ldb_request_set_state(req, LDB_ASYNC_PENDING); if (ldb_kv_cache_load(module) != 0) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_sub_transaction_start(ldb_kv); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_kv_delete_internal(module, req->op.del.dn); if (ret != LDB_SUCCESS) { int r = ldb_kv_sub_transaction_cancel(ldb_kv); if (r != LDB_SUCCESS) { ldb_debug( ldb_module_get_ctx(module), LDB_DEBUG_FATAL, __location__ ": Unable to roll back sub transaction"); } if (ret != LDB_ERR_NO_SUCH_OBJECT) { ldb_kv->operation_failed = true; } return ret; } ret = ldb_kv_sub_transaction_commit(ldb_kv); return ret; } /* find an element by attribute name. At the moment this does a linear search, it should be re-coded to use a binary search once all places that modify records guarantee sorted order return the index of the first matching element if found, otherwise -1 */ static int ldb_kv_find_element(const struct ldb_message *msg, const char *name) { unsigned int i; for (i=0;inum_elements;i++) { if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { return i; } } return -1; } /* add an element to an existing record. Assumes a elements array that we can call re-alloc on, and assumed that we can re-use the data pointers from the passed in additional values. Use with care! returns 0 on success, -1 on failure (and sets errno) */ static int ldb_kv_msg_add_element(struct ldb_message *msg, struct ldb_message_element *el) { struct ldb_message_element *e2; unsigned int i; if (el->num_values == 0) { /* nothing to do here - we don't add empty elements */ return 0; } e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements+1); if (!e2) { errno = ENOMEM; return -1; } msg->elements = e2; e2 = &msg->elements[msg->num_elements]; e2->name = el->name; e2->flags = el->flags; e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values); if (!e2->values) { errno = ENOMEM; return -1; } for (i=0;inum_values;i++) { e2->values[i] = el->values[i]; } e2->num_values = el->num_values; ++msg->num_elements; return 0; } /* delete all elements having a specified attribute name */ static int ldb_kv_msg_delete_attribute(struct ldb_module *module, struct ldb_kv_private *ldb_kv, struct ldb_message *msg, const char *name) { int ret; struct ldb_message_element *el; bool is_special = ldb_dn_is_special(msg->dn); if (!is_special && ldb_kv->cache->GUID_index_attribute != NULL && ldb_attr_cmp(name, ldb_kv->cache->GUID_index_attribute) == 0) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, "Must not modify GUID " "attribute %s (used as DB index)", ldb_kv->cache->GUID_index_attribute); return LDB_ERR_CONSTRAINT_VIOLATION; } el = ldb_msg_find_element(msg, name); if (el == NULL) { return LDB_ERR_NO_SUCH_ATTRIBUTE; } ret = ldb_kv_index_del_element(module, ldb_kv, msg, el); if (ret != LDB_SUCCESS) { return ret; } talloc_free(el->values); ldb_msg_remove_element(msg, el); msg->elements = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements); return LDB_SUCCESS; } /* delete all elements matching an attribute name/value return LDB Error on failure */ static int ldb_kv_msg_delete_element(struct ldb_module *module, struct ldb_kv_private *ldb_kv, struct ldb_message *msg, const char *name, const struct ldb_val *val) { struct ldb_context *ldb = ldb_module_get_ctx(module); unsigned int i; int found, ret; struct ldb_message_element *el; const struct ldb_schema_attribute *a; found = ldb_kv_find_element(msg, name); if (found == -1) { return LDB_ERR_NO_SUCH_ATTRIBUTE; } i = (unsigned int) found; el = &(msg->elements[i]); a = ldb_schema_attribute_by_name(ldb, el->name); for (i=0;inum_values;i++) { bool matched; if (a->syntax->operator_fn) { ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, &el->values[i], val, &matched); if (ret != LDB_SUCCESS) return ret; } else { matched = (a->syntax->comparison_fn(ldb, ldb, &el->values[i], val) == 0); } if (matched) { if (el->num_values == 1) { return ldb_kv_msg_delete_attribute( module, ldb_kv, msg, name); } ret = ldb_kv_index_del_value(module, ldb_kv, msg, el, i); if (ret != LDB_SUCCESS) { return ret; } if (inum_values-1) { memmove(&el->values[i], &el->values[i+1], sizeof(el->values[i])* (el->num_values-(i+1))); } el->num_values--; /* per definition we find in a canonicalised message an attribute value only once. So we are finished here */ return LDB_SUCCESS; } } /* Not found */ return LDB_ERR_NO_SUCH_ATTRIBUTE; } /* modify a record - internal interface yuck - this is O(n^2). Luckily n is usually small so we probably get away with it, but if we ever have really large attribute lists then we'll need to look at this again 'req' is optional, and is used to specify controls if supplied */ int ldb_kv_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_message *msg2; unsigned int i, j; int ret = LDB_SUCCESS, idx; struct ldb_control *control_permissive = NULL; TALLOC_CTX *mem_ctx = talloc_new(req); if (mem_ctx == NULL) { return ldb_module_oom(module); } if (req) { control_permissive = ldb_request_get_control(req, LDB_CONTROL_PERMISSIVE_MODIFY_OID); } msg2 = ldb_msg_new(mem_ctx); if (msg2 == NULL) { ret = LDB_ERR_OTHER; goto done; } ret = ldb_kv_search_dn1(module, msg->dn, msg2, 0); if (ret != LDB_SUCCESS) { goto done; } for (i=0; inum_elements; i++) { struct ldb_message_element *el = &msg->elements[i], *el2; struct ldb_val *vals; const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); const char *dn; uint32_t options = 0; if (control_permissive != NULL) { options |= LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; } switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { case LDB_FLAG_MOD_ADD: if (el->num_values == 0) { ldb_asprintf_errstring(ldb, "attribute '%s': attribute on '%s' specified, but with 0 values (illegal)", el->name, ldb_dn_get_linearized(msg2->dn)); ret = LDB_ERR_CONSTRAINT_VIOLATION; goto done; } /* make a copy of the array so that a permissive * control can remove duplicates without changing the * original values, but do not copy data as we do not * need to keep it around once the operation is * finished */ if (control_permissive) { el = talloc(msg2, struct ldb_message_element); if (!el) { ret = LDB_ERR_OTHER; goto done; } *el = msg->elements[i]; el->values = talloc_array(el, struct ldb_val, el->num_values); if (el->values == NULL) { ret = LDB_ERR_OTHER; goto done; } for (j = 0; j < el->num_values; j++) { el->values[j] = msg->elements[i].values[j]; } } if (el->num_values > 1 && ldb_kv_single_valued(a, el)) { ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", el->name, ldb_dn_get_linearized(msg2->dn)); ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; goto done; } /* Checks if element already exists */ idx = ldb_kv_find_element(msg2, el->name); if (idx == -1) { if (ldb_kv_msg_add_element(msg2, el) != 0) { ret = LDB_ERR_OTHER; goto done; } ret = ldb_kv_index_add_element( module, ldb_kv, msg2, el); if (ret != LDB_SUCCESS) { goto done; } } else { j = (unsigned int) idx; el2 = &(msg2->elements[j]); /* We cannot add another value on a existing one if the attribute is single-valued */ if (ldb_kv_single_valued(a, el)) { ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", el->name, ldb_dn_get_linearized(msg2->dn)); ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; goto done; } /* Check that values don't exist yet on multi- valued attributes or aren't provided twice */ if (!(el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { struct ldb_val *duplicate = NULL; ret = ldb_msg_find_common_values(ldb, msg2, el, el2, options); if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { ldb_asprintf_errstring(ldb, "attribute '%s': value " "#%u on '%s' already " "exists", el->name, j, ldb_dn_get_linearized(msg2->dn)); goto done; } else if (ret != LDB_SUCCESS) { goto done; } ret = ldb_msg_find_duplicate_val( ldb, msg2, el, &duplicate, 0); if (ret != LDB_SUCCESS) { goto done; } if (duplicate != NULL) { ldb_asprintf_errstring( ldb, "attribute '%s': value " "'%.*s' on '%s' " "provided more than " "once in ADD", el->name, (int)duplicate->length, duplicate->data, ldb_dn_get_linearized(msg->dn)); ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; goto done; } } /* Now combine existing and new values to a new attribute record */ vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val, el2->num_values + el->num_values); if (vals == NULL) { ldb_oom(ldb); ret = LDB_ERR_OTHER; goto done; } for (j=0; jnum_values; j++) { vals[el2->num_values + j] = ldb_val_dup(vals, &el->values[j]); } el2->values = vals; el2->num_values += el->num_values; ret = ldb_kv_index_add_element( module, ldb_kv, msg2, el); if (ret != LDB_SUCCESS) { goto done; } } break; case LDB_FLAG_MOD_REPLACE: if (el->num_values > 1 && ldb_kv_single_valued(a, el)) { ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", el->name, ldb_dn_get_linearized(msg2->dn)); ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; goto done; } /* * We don't need to check this if we have been * pre-screened by the repl_meta_data module * in Samba, or someone else who can claim to * know what they are doing. */ if (!(el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { struct ldb_val *duplicate = NULL; ret = ldb_msg_find_duplicate_val(ldb, msg2, el, &duplicate, 0); if (ret != LDB_SUCCESS) { goto done; } if (duplicate != NULL) { ldb_asprintf_errstring( ldb, "attribute '%s': value '%.*s' " "on '%s' provided more than " "once in REPLACE", el->name, (int)duplicate->length, duplicate->data, ldb_dn_get_linearized(msg2->dn)); ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; goto done; } } /* Checks if element already exists */ idx = ldb_kv_find_element(msg2, el->name); if (idx != -1) { j = (unsigned int) idx; el2 = &(msg2->elements[j]); /* we consider two elements to be * equal only if the order * matches. This allows dbcheck to * fix the ordering on attributes * where order matters, such as * objectClass */ if (ldb_msg_element_equal_ordered(el, el2)) { continue; } /* Delete the attribute if it exists in the DB */ if (ldb_kv_msg_delete_attribute( module, ldb_kv, msg2, el->name) != 0) { ret = LDB_ERR_OTHER; goto done; } } /* Recreate it with the new values */ if (ldb_kv_msg_add_element(msg2, el) != 0) { ret = LDB_ERR_OTHER; goto done; } ret = ldb_kv_index_add_element(module, ldb_kv, msg2, el); if (ret != LDB_SUCCESS) { goto done; } break; case LDB_FLAG_MOD_DELETE: dn = ldb_dn_get_linearized(msg2->dn); if (dn == NULL) { ret = LDB_ERR_OTHER; goto done; } if (msg->elements[i].num_values == 0) { /* Delete the whole attribute */ ret = ldb_kv_msg_delete_attribute( module, ldb_kv, msg2, msg->elements[i].name); if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && control_permissive) { ret = LDB_SUCCESS; } else { ldb_asprintf_errstring(ldb, "attribute '%s': no such attribute for delete on '%s'", msg->elements[i].name, dn); } if (ret != LDB_SUCCESS) { goto done; } } else { /* Delete specified values from an attribute */ for (j=0; j < msg->elements[i].num_values; j++) { ret = ldb_kv_msg_delete_element( module, ldb_kv, msg2, msg->elements[i].name, &msg->elements[i].values[j]); if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && control_permissive) { ret = LDB_SUCCESS; } else if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { ldb_asprintf_errstring(ldb, "attribute '%s': no matching attribute value while deleting attribute on '%s'", msg->elements[i].name, dn); } if (ret != LDB_SUCCESS) { goto done; } } } break; default: ldb_asprintf_errstring(ldb, "attribute '%s': invalid modify flags on '%s': 0x%x", msg->elements[i].name, ldb_dn_get_linearized(msg->dn), msg->elements[i].flags & LDB_FLAG_MOD_MASK); ret = LDB_ERR_PROTOCOL_ERROR; goto done; } } ret = ldb_kv_store(module, msg2, TDB_MODIFY); if (ret != LDB_SUCCESS) { goto done; } ret = ldb_kv_modified(module, msg2->dn); if (ret != LDB_SUCCESS) { goto done; } done: TALLOC_FREE(mem_ctx); /* * To allow testing of the error recovery code in ldb_kv_modify * cmocka tests can define CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL * to inject failures at this point. */ #ifdef CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL #endif return ret; } /* modify a record */ static int ldb_kv_modify(struct ldb_kv_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int ret = LDB_SUCCESS; ret = ldb_kv_check_special_dn(module, req->op.mod.message); if (ret != LDB_SUCCESS) { return ret; } ldb_request_set_state(req, LDB_ASYNC_PENDING); if (ldb_kv_cache_load(module) != 0) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_sub_transaction_start(ldb_kv); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_kv_modify_internal(module, req->op.mod.message, req); if (ret != LDB_SUCCESS) { int r = ldb_kv_sub_transaction_cancel(ldb_kv); if (r != LDB_SUCCESS) { ldb_debug( ldb_module_get_ctx(module), LDB_DEBUG_FATAL, __location__ ": Unable to roll back sub transaction"); } if (ret != LDB_ERR_NO_SUCH_OBJECT) { ldb_kv->operation_failed = true; } return ret; } ret = ldb_kv_sub_transaction_commit(ldb_kv); return ret; } static int ldb_kv_rename_internal(struct ldb_module *module, struct ldb_request *req, struct ldb_message *msg) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int ret = LDB_SUCCESS; /* Always delete first then add, to avoid conflicts with * unique indexes. We rely on the transaction to make this * atomic */ ret = ldb_kv_delete_internal(module, msg->dn); if (ret != LDB_SUCCESS) { return ret; } msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); if (msg->dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* We don't check single value as we can have more than 1 with * deleted attributes. We could go through all elements but that's * maybe not the most efficient way */ ret = ldb_kv_add_internal(module, ldb_kv, msg, false); /* * To allow testing of the error recovery code in ldb_kv_rename * cmocka tests can define CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL * to inject failures at this point. */ #ifdef CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL #endif return ret; } /* rename a record */ static int ldb_kv_rename(struct ldb_kv_context *ctx) { struct ldb_module *module = ctx->module; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_request *req = ctx->req; struct ldb_message *msg; int ret = LDB_SUCCESS; struct ldb_val key, key_old; struct ldb_dn *db_dn; bool valid_dn = false; ldb_request_set_state(req, LDB_ASYNC_PENDING); if (ldb_kv_cache_load(ctx->module) != 0) { return LDB_ERR_OPERATIONS_ERROR; } msg = ldb_msg_new(ctx); if (msg == NULL) { 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 = ldb_kv_search_dn1(module, req->op.rename.olddn, msg, 0); 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; } /* We need to, before changing the DB, check if the new DN * exists, so we can return this error to the caller with an * unmodified DB * * Even in GUID index mode we use ltdb_key_dn() as we are * trying to figure out if this is just a case rename */ key = ldb_kv_key_dn(msg, req->op.rename.newdn); if (!key.data) { talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } key_old = ldb_kv_key_dn(msg, req->op.rename.olddn); if (!key_old.data) { talloc_free(msg); talloc_free(key.data); return LDB_ERR_OPERATIONS_ERROR; } /* * Only declare a conflict if the new DN already exists, * and it isn't a case change on the old DN */ if (key_old.length != key.length || memcmp(key.data, key_old.data, key.length) != 0) { ret = ldb_kv_search_base( module, msg, req->op.rename.newdn, &db_dn); if (ret == LDB_SUCCESS) { ret = LDB_ERR_ENTRY_ALREADY_EXISTS; } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { ret = LDB_SUCCESS; } } /* finding the new record already in the DB is an error */ if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { ldb_asprintf_errstring(ldb_module_get_ctx(module), "Entry %s already exists", ldb_dn_get_linearized(req->op.rename.newdn)); } if (ret != LDB_SUCCESS) { talloc_free(key_old.data); talloc_free(key.data); talloc_free(msg); return ret; } talloc_free(key_old.data); talloc_free(key.data); ret = ldb_kv_sub_transaction_start(ldb_kv); if (ret != LDB_SUCCESS) { talloc_free(msg); return ret; } ret = ldb_kv_rename_internal(module, req, msg); if (ret != LDB_SUCCESS) { int r = ldb_kv_sub_transaction_cancel(ldb_kv); if (r != LDB_SUCCESS) { ldb_debug( ldb_module_get_ctx(module), LDB_DEBUG_FATAL, __location__ ": Unable to roll back sub transaction"); } talloc_free(msg); ldb_kv->operation_failed = true; return ret; } ret = ldb_kv_sub_transaction_commit(ldb_kv); talloc_free(msg); return ret; } static int ldb_kv_start_trans(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } /* Do not take out the transaction lock on a read-only DB */ if (ldb_kv->read_only) { return LDB_ERR_UNWILLING_TO_PERFORM; } if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) { return ldb_kv->kv_ops->error(ldb_kv); } ldb_kv_index_transaction_start( module, ldb_kv->index_transaction_cache_size); ldb_kv->reindex_failed = false; ldb_kv->operation_failed = false; return LDB_SUCCESS; } /* * Forward declaration to allow prepare_commit to in fact abort the * transaction */ static int ldb_kv_del_trans(struct ldb_module *module); static int ldb_kv_prepare_commit(struct ldb_module *module) { int ret; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } if (!ldb_kv->kv_ops->transaction_active(ldb_kv)) { ldb_set_errstring(ldb_module_get_ctx(module), "ltdb_prepare_commit() called " "without transaction active"); return LDB_ERR_OPERATIONS_ERROR; } /* * Check if the last re-index failed. * * This can happen if for example a duplicate value was marked * unique. We must not write a partial re-index into the DB. */ if (ldb_kv->reindex_failed) { /* * We must instead abort the transaction so we get the * old values and old index back */ ldb_kv_del_trans(module); ldb_set_errstring(ldb_module_get_ctx(module), "Failure during re-index, so " "transaction must be aborted."); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_index_transaction_commit(module); if (ret != LDB_SUCCESS) { ldb_kv->kv_ops->abort_write(ldb_kv); return ret; } /* * If GUID indexing was toggled in this transaction, we repack at * format version 2 if GUID indexing was enabled, or version 1 if * it was disabled. */ ret = ldb_kv_maybe_repack(ldb_kv); if (ret != LDB_SUCCESS) { ldb_kv_del_trans(module); ldb_set_errstring(ldb_module_get_ctx(module), "Failure during re-pack, so " "transaction must be aborted."); return ret; } if (ldb_kv->kv_ops->prepare_write(ldb_kv) != 0) { ret = ldb_kv->kv_ops->error(ldb_kv); ldb_debug_set(ldb_module_get_ctx(module), LDB_DEBUG_FATAL, "Failure during " "prepare_write): %s -> %s", ldb_kv->kv_ops->errorstr(ldb_kv), ldb_strerror(ret)); return ret; } ldb_kv->prepared_commit = true; return LDB_SUCCESS; } static int ldb_kv_end_trans(struct ldb_module *module) { int ret; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); /* * If in batch mode and there has been an operation failure * rollback the transaction rather than committing it to avoid * any possible corruption */ if (ldb_kv->batch_mode && ldb_kv->operation_failed) { ret = ldb_kv_del_trans( module); if (ret != LDB_SUCCESS) { ldb_debug_set(ldb_module_get_ctx(module), LDB_DEBUG_FATAL, "An operation failed during a batch mode " "transaction. The transaction could not" "be rolled back, ldb_kv_del_trans " "returned (%s, %s)", ldb_kv->kv_ops->errorstr(ldb_kv), ldb_strerror(ret)); } else { ldb_debug_set(ldb_module_get_ctx(module), LDB_DEBUG_FATAL, "An operation failed during a batch mode " "transaction, the transaction was " "rolled back"); } return LDB_ERR_OPERATIONS_ERROR; } if (!ldb_kv->prepared_commit) { ret = ldb_kv_prepare_commit(module); if (ret != LDB_SUCCESS) { return ret; } } ldb_kv->prepared_commit = false; if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) { ret = ldb_kv->kv_ops->error(ldb_kv); ldb_asprintf_errstring( ldb_module_get_ctx(module), "Failure during tdb_transaction_commit(): %s -> %s", ldb_kv->kv_ops->errorstr(ldb_kv), ldb_strerror(ret)); return ret; } return LDB_SUCCESS; } static int ldb_kv_del_trans(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); if (ldb_kv_index_transaction_cancel(module) != 0) { ldb_kv->kv_ops->abort_write(ldb_kv); return ldb_kv->kv_ops->error(ldb_kv); } ldb_kv->kv_ops->abort_write(ldb_kv); return LDB_SUCCESS; } /* return sequenceNumber from @BASEINFO */ static int ldb_kv_sequence_number(struct ldb_kv_context *ctx, struct ldb_extended **ext) { struct ldb_context *ldb; struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); TALLOC_CTX *tmp_ctx = NULL; struct ldb_seqnum_request *seq; struct ldb_seqnum_result *res; struct ldb_message *msg = NULL; struct ldb_dn *dn; const char *date; int ret = LDB_SUCCESS; ldb = ldb_module_get_ctx(module); seq = talloc_get_type(req->op.extended.data, struct ldb_seqnum_request); if (seq == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ldb_request_set_state(req, LDB_ASYNC_PENDING); if (ldb_kv->kv_ops->lock_read(module) != 0) { return LDB_ERR_OPERATIONS_ERROR; } res = talloc_zero(req, struct ldb_seqnum_result); if (res == NULL) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } tmp_ctx = talloc_new(req); if (tmp_ctx == NULL) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } dn = ldb_dn_new(tmp_ctx, ldb, LDB_KV_BASEINFO); if (dn == NULL) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } ret = ldb_kv_search_dn1(module, dn, msg, 0); if (ret != LDB_SUCCESS) { goto done; } switch (seq->type) { case LDB_SEQ_HIGHEST_SEQ: res->seq_num = ldb_msg_find_attr_as_uint64(msg, LDB_KV_SEQUENCE_NUMBER, 0); break; case LDB_SEQ_NEXT: res->seq_num = ldb_msg_find_attr_as_uint64(msg, LDB_KV_SEQUENCE_NUMBER, 0); res->seq_num++; break; case LDB_SEQ_HIGHEST_TIMESTAMP: date = ldb_msg_find_attr_as_string(msg, LDB_KV_MOD_TIMESTAMP, NULL); if (date) { res->seq_num = ldb_string_to_time(date); } else { res->seq_num = 0; /* zero is as good as anything when we don't know */ } break; } *ext = talloc_zero(req, struct ldb_extended); if (*ext == NULL) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER; (*ext)->data = talloc_steal(*ext, res); done: talloc_free(tmp_ctx); ldb_kv->kv_ops->unlock_read(module); return ret; } static void ldb_kv_request_done(struct ldb_kv_context *ctx, int error) { struct ldb_context *ldb; struct ldb_request *req; struct ldb_reply *ares; ldb = ldb_module_get_ctx(ctx->module); req = ctx->req; /* if we already returned an error just return */ if (ldb_request_get_status(req) != LDB_SUCCESS) { return; } ares = talloc_zero(req, struct ldb_reply); if (!ares) { ldb_oom(ldb); req->callback(req, NULL); return; } ares->type = LDB_REPLY_DONE; ares->error = error; req->callback(req, ares); } static void ldb_kv_timeout(_UNUSED_ struct tevent_context *ev, _UNUSED_ struct tevent_timer *te, _UNUSED_ struct timeval t, void *private_data) { struct ldb_kv_context *ctx; ctx = talloc_get_type(private_data, struct ldb_kv_context); if (!ctx->request_terminated) { /* request is done now */ ldb_kv_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); } if (ctx->spy) { /* neutralize the spy */ ctx->spy->ctx = NULL; ctx->spy = NULL; } talloc_free(ctx); } static void ldb_kv_request_extended_done(struct ldb_kv_context *ctx, struct ldb_extended *ext, int error) { struct ldb_context *ldb; struct ldb_request *req; struct ldb_reply *ares; ldb = ldb_module_get_ctx(ctx->module); req = ctx->req; /* if we already returned an error just return */ if (ldb_request_get_status(req) != LDB_SUCCESS) { return; } ares = talloc_zero(req, struct ldb_reply); if (!ares) { ldb_oom(ldb); req->callback(req, NULL); return; } ares->type = LDB_REPLY_DONE; ares->response = ext; ares->error = error; req->callback(req, ares); } static void ldb_kv_handle_extended(struct ldb_kv_context *ctx) { struct ldb_extended *ext = NULL; int ret; if (strcmp(ctx->req->op.extended.oid, LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { /* get sequence number */ ret = ldb_kv_sequence_number(ctx, &ext); } else { /* not recognized */ ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; } ldb_kv_request_extended_done(ctx, ext, ret); } static void ldb_kv_callback(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct ldb_kv_context *ctx; int ret; ctx = talloc_get_type(private_data, struct ldb_kv_context); if (ctx->request_terminated) { goto done; } switch (ctx->req->operation) { case LDB_SEARCH: ret = ldb_kv_search(ctx); break; case LDB_ADD: ret = ldb_kv_add(ctx); break; case LDB_MODIFY: ret = ldb_kv_modify(ctx); break; case LDB_DELETE: ret = ldb_kv_delete(ctx); break; case LDB_RENAME: ret = ldb_kv_rename(ctx); break; case LDB_EXTENDED: ldb_kv_handle_extended(ctx); goto done; default: /* no other op supported */ ret = LDB_ERR_PROTOCOL_ERROR; } if (!ctx->request_terminated) { /* request is done now */ ldb_kv_request_done(ctx, ret); } done: if (ctx->spy) { /* neutralize the spy */ ctx->spy->ctx = NULL; ctx->spy = NULL; } talloc_free(ctx); } static int ldb_kv_request_destructor(void *ptr) { struct ldb_kv_req_spy *spy = talloc_get_type(ptr, struct ldb_kv_req_spy); if (spy->ctx != NULL) { spy->ctx->spy = NULL; spy->ctx->request_terminated = true; spy->ctx = NULL; } return 0; } static int ldb_kv_handle_request(struct ldb_module *module, struct ldb_request *req) { struct ldb_control *control_permissive; struct ldb_context *ldb; struct tevent_context *ev; struct ldb_kv_context *ac; struct tevent_timer *te; struct timeval tv; unsigned int i; ldb = ldb_module_get_ctx(module); control_permissive = ldb_request_get_control(req, LDB_CONTROL_PERMISSIVE_MODIFY_OID); for (i = 0; req->controls && req->controls[i]; i++) { if (req->controls[i]->critical && req->controls[i] != control_permissive) { ldb_asprintf_errstring(ldb, "Unsupported critical extension %s", req->controls[i]->oid); return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; } } if (req->starttime == 0 || req->timeout == 0) { ldb_set_errstring(ldb, "Invalid timeout settings"); return LDB_ERR_TIME_LIMIT_EXCEEDED; } ev = ldb_handle_get_event_context(req->handle); ac = talloc_zero(ldb, struct ldb_kv_context); if (ac == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } ac->module = module; ac->req = req; tv.tv_sec = 0; tv.tv_usec = 0; te = tevent_add_timer(ev, ac, tv, ldb_kv_callback, ac); if (NULL == te) { talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } if (req->timeout > 0) { tv.tv_sec = req->starttime + req->timeout; tv.tv_usec = 0; ac->timeout_event = tevent_add_timer(ev, ac, tv, ldb_kv_timeout, ac); if (NULL == ac->timeout_event) { talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } } /* set a spy so that we do not try to use the request context * if it is freed before ltdb_callback fires */ ac->spy = talloc(req, struct ldb_kv_req_spy); if (NULL == ac->spy) { talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } ac->spy->ctx = ac; talloc_set_destructor((TALLOC_CTX *)ac->spy, ldb_kv_request_destructor); return LDB_SUCCESS; } static int ldb_kv_init_rootdse(struct ldb_module *module) { /* ignore errors on this - we expect it for non-sam databases */ ldb_mod_register_control(module, LDB_CONTROL_PERMISSIVE_MODIFY_OID); /* there can be no module beyond the backend, just return */ return LDB_SUCCESS; } static int ldb_kv_lock_read(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); return ldb_kv->kv_ops->lock_read(module); } static int ldb_kv_unlock_read(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); return ldb_kv->kv_ops->unlock_read(module); } static const struct ldb_module_ops ldb_kv_ops = { .name = "tdb", .init_context = ldb_kv_init_rootdse, .search = ldb_kv_handle_request, .add = ldb_kv_handle_request, .modify = ldb_kv_handle_request, .del = ldb_kv_handle_request, .rename = ldb_kv_handle_request, .extended = ldb_kv_handle_request, .start_transaction = ldb_kv_start_trans, .end_transaction = ldb_kv_end_trans, .prepare_commit = ldb_kv_prepare_commit, .del_transaction = ldb_kv_del_trans, .read_lock = ldb_kv_lock_read, .read_unlock = ldb_kv_unlock_read, }; int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, const char *name, struct ldb_context *ldb, const char *options[], struct ldb_module **_module) { if (getenv("LDB_WARN_UNINDEXED")) { ldb_kv->warn_unindexed = true; } if (getenv("LDB_WARN_REINDEX")) { ldb_kv->warn_reindex = true; } ldb_kv->sequence_number = 0; ldb_kv->pid = getpid(); ldb_kv->pack_format_override = 0; ldb_kv->module = ldb_module_new(ldb, ldb, name, &ldb_kv_ops); if (!ldb_kv->module) { ldb_oom(ldb); talloc_free(ldb_kv); return LDB_ERR_OPERATIONS_ERROR; } ldb_module_set_private(ldb_kv->module, ldb_kv); talloc_steal(ldb_kv->module, ldb_kv); if (ldb_kv_cache_load(ldb_kv->module) != 0) { ldb_asprintf_errstring(ldb, "Unable to load ltdb cache " "records for backend '%s'", name); talloc_free(ldb_kv->module); return LDB_ERR_OPERATIONS_ERROR; } *_module = ldb_kv->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); ldb_kv->max_key_length = len; } } /* * Usually the presence of GUID indexing determines the pack format * we use but in certain circumstances such as downgrading an * MDB-backed database, we want to override the target pack format. * * We set/get opaques here because in the Samba partitions module, * 'options' are not passed correctly so sub-databases can't see * the options they need. */ { const char *pack_format_override = ldb_options_find(ldb, options, "pack_format_override"); if (pack_format_override != NULL) { int ret; ldb_kv->pack_format_override = strtoul(pack_format_override, NULL, 0); ret = ldb_set_opaque(ldb, "pack_format_override", (void *)(intptr_t)ldb_kv->pack_format_override); if (ret != LDB_SUCCESS) { talloc_free(ldb_kv->module); return ldb_module_operr(ldb_kv->module); } } else { /* * NULL -> 0 is fine, otherwise we get back * the number we needed */ ldb_kv->pack_format_override = (intptr_t)ldb_get_opaque(ldb, "pack_format_override"); } } /* * 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) { ldb_kv->disable_full_db_scan = true; } } /* * Set the size of the transaction index cache. * If the ldb option "transaction_index_cache_size" is set use that * otherwise use DEFAULT_INDEX_CACHE_SIZE */ ldb_kv->index_transaction_cache_size = DEFAULT_INDEX_CACHE_SIZE; { const char *size = ldb_options_find( ldb, options, "transaction_index_cache_size"); if (size != NULL) { size_t cache_size = 0; errno = 0; cache_size = strtoul( size, NULL, 0); if (cache_size == 0 || errno == ERANGE) { ldb_debug( ldb, LDB_DEBUG_WARNING, "Invalid transaction_index_cache_size " "value [%s], using default(%d)\n", size, DEFAULT_INDEX_CACHE_SIZE); } else { ldb_kv->index_transaction_cache_size = cache_size; } } } /* * Set batch mode operation. * This disables the nested sub transactions, and increases the * chance of index corruption. If using this mode the transaction * commit will be aborted if any operation fails. */ { const char *batch_mode = ldb_options_find( ldb, options, "batch_mode"); if (batch_mode != NULL) { ldb_kv->batch_mode = true; } } return LDB_SUCCESS; } ldb-2.0.8/ldb_key_value/ldb_kv.h0000660000000000000000000002416713573675413016465 0ustar rootroot00000000000000#include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "tdb.h" #include "ldb_module.h" #ifndef __LDB_KV_H__ #define __LDB_KV_H__ struct ldb_kv_private; typedef int (*ldb_kv_traverse_fn)(struct ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val data, void *ctx); struct kv_db_ops { uint32_t options; int (*store)(struct ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val data, int flags); int (*delete)(struct ldb_kv_private *ldb_kv, struct ldb_val key); int (*iterate)(struct ldb_kv_private *ldb_kv, ldb_kv_traverse_fn fn, void *ctx); int (*update_in_iterate)(struct ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val key2, struct ldb_val data, void *ctx); int (*fetch_and_parse)(struct ldb_kv_private *ldb_kv, struct ldb_val key, int (*parser)(struct ldb_val key, struct ldb_val data, void *private_data), void *ctx); int (*iterate_range)(struct ldb_kv_private *ldb_kv, struct ldb_val start_key, struct ldb_val end_key, ldb_kv_traverse_fn fn, void *ctx); int (*lock_read)(struct ldb_module *); int (*unlock_read)(struct ldb_module *); int (*begin_write)(struct ldb_kv_private *); int (*prepare_write)(struct ldb_kv_private *); int (*abort_write)(struct ldb_kv_private *); int (*finish_write)(struct ldb_kv_private *); int (*error)(struct ldb_kv_private *ldb_kv); const char *(*errorstr)(struct ldb_kv_private *ldb_kv); const char *(*name)(struct ldb_kv_private *ldb_kv); bool (*has_changed)(struct ldb_kv_private *ldb_kv); bool (*transaction_active)(struct ldb_kv_private *ldb_kv); size_t (*get_size)(struct ldb_kv_private *ldb_kv); int (*begin_nested_write)(struct ldb_kv_private *); int (*finish_nested_write)(struct ldb_kv_private *); int (*abort_nested_write)(struct ldb_kv_private *); }; /* this private structure is used by the key value backends in the ldb_context */ struct ldb_kv_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; uint32_t pack_format_version; uint32_t target_pack_format_version; uint32_t pack_format_override; /* the low level tdb seqnum - used to avoid loading BASEINFO when possible */ int tdb_seqnum; struct ldb_kv_cache { struct ldb_message *indexlist; bool one_level_indexes; bool attribute_indexes; const char *GUID_index_attribute; const char *GUID_index_dn_component; } *cache; bool check_base; bool disallow_dn_filter; /* * To improve the performance of batch operations we maintain a cache * of index records, these entries get written to disk in the * prepare_commit phase. */ struct ldb_kv_idxptr *idxptr; /* * To ensure that the indexes in idxptr are consistent we cache any * index updates during an operation, i.e. ldb_kv_add, ldb_kv_delete ... * Once the changes to the data record have been commited to disk * the contents of this cache are copied to idxptr */ struct ldb_kv_idxptr *nested_idx_ptr; /* * If batch mode is set the sub transactions and index caching * wrapping individual operations is disabled. * This is to improve the performance of large batch operations * i.e. domain joins. */ bool batch_mode; /* * Has an operation failed, if true and we're in batch_mode * the transaction commit will fail. */ bool operation_failed; bool prepared_commit; int read_lock_count; bool warn_unindexed; bool warn_reindex; bool read_only; bool reindex_failed; 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; /* * The size to be used for the index transaction cache */ size_t index_transaction_cache_size; }; struct ldb_kv_context { struct ldb_module *module; struct ldb_request *req; bool request_terminated; struct ldb_kv_req_spy *spy; /* search stuff */ const struct ldb_parse_tree *tree; struct ldb_dn *base; enum ldb_scope scope; const char * const *attrs; struct tevent_timer *timeout_event; /* error handling */ int error; }; struct ldb_kv_reindex_context { int error; uint32_t count; }; struct ldb_kv_repack_context { int error; uint32_t count; bool normal_record_seen; uint32_t old_version; }; /* special record types */ #define LDB_KV_INDEX "@INDEX" #define LDB_KV_INDEXLIST "@INDEXLIST" #define LDB_KV_IDX "@IDX" #define LDB_KV_IDXVERSION "@IDXVERSION" #define LDB_KV_IDXATTR "@IDXATTR" #define LDB_KV_IDXONE "@IDXONE" #define LDB_KV_IDXDN "@IDXDN" #define LDB_KV_IDXGUID "@IDXGUID" #define LDB_KV_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 LDB_KV_IDX_LMDB_SUBDB "@IDX_LMDB_SUBDB" #define LDB_KV_BASEINFO "@BASEINFO" #define LDB_KV_OPTIONS "@OPTIONS" #define LDB_KV_ATTRIBUTES "@ATTRIBUTES" /* special attribute types */ #define LDB_KV_SEQUENCE_NUMBER "sequenceNumber" #define LDB_KV_CHECK_BASE "checkBaseOnSearch" #define LDB_KV_DISALLOW_DN_FILTER "disallowDNFilter" #define LDB_KV_MOD_TIMESTAMP "whenChanged" #define LDB_KV_OBJECTCLASS "objectClass" /* DB keys */ #define LDB_KV_GUID_KEY_PREFIX "GUID=" #define LDB_KV_GUID_SIZE 16 #define LDB_KV_GUID_KEY_SIZE (LDB_KV_GUID_SIZE + sizeof(LDB_KV_GUID_KEY_PREFIX) - 1) /* LDB KV options */ /* * This allows pointers to be referenced after the callback to any variant of * iterate or fetch_and_parse -- as long as an overall read lock is held. */ #define LDB_KV_OPTION_STABLE_READ_LOCK 0x00000001 /* * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_cache.c */ int ldb_kv_cache_reload(struct ldb_module *module); int ldb_kv_cache_load(struct ldb_module *module); int ldb_kv_increase_sequence_number(struct ldb_module *module); int ldb_kv_check_at_attributes_values(const struct ldb_val *value); /* * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_index.c */ /* * The default size of the in memory TDB used to cache index records * The value chosen gives a prime modulo for the hash table and keeps the * tdb memory overhead under 4 kB */ #define DEFAULT_INDEX_CACHE_SIZE 491 struct ldb_parse_tree; int ldb_kv_search_indexed(struct ldb_kv_context *ctx, uint32_t *); int ldb_kv_index_add_new(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg); int ldb_kv_index_delete(struct ldb_module *module, const struct ldb_message *msg); int ldb_kv_index_del_element(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el); int ldb_kv_index_add_element(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el); int ldb_kv_index_del_value(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el, unsigned int v_idx); int ldb_kv_reindex(struct ldb_module *module); int ldb_kv_repack(struct ldb_module *module); int ldb_kv_index_transaction_start( struct ldb_module *module, size_t cache_size); int ldb_kv_index_transaction_commit(struct ldb_module *module); int ldb_kv_index_transaction_cancel(struct ldb_module *module); int ldb_kv_key_dn_from_idx(struct ldb_module *module, struct ldb_kv_private *ldb_kv, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct ldb_val *key); /* * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_search.c */ int ldb_kv_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg, unsigned int unpack_flags); int ldb_kv_search_base(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct ldb_dn **ret_dn); int ldb_kv_search_key(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_val ldb_key, struct ldb_message *msg, unsigned int unpack_flags); int ldb_kv_filter_attrs(struct ldb_context *ldb, const struct ldb_message *msg, const char *const *attrs, struct ldb_message *filtered_msg); int ldb_kv_search(struct ldb_kv_context *ctx); /* * The following definitions come from lib/ldb/ldb_key_value/ldb_kv.c */ /* * Determine if this key could hold a normal record. We allow the new * GUID index, the old DN index and a possible future ID= but not * DN=@. */ bool ldb_kv_key_is_normal_record(struct ldb_val key); struct ldb_val ldb_kv_key_dn(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); struct ldb_val ldb_kv_key_msg(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct ldb_message *msg); int ldb_kv_guid_to_key(const struct ldb_val *GUID_val, struct ldb_val *key); int ldb_kv_idx_to_key(struct ldb_module *module, struct ldb_kv_private *ldb_kv, TALLOC_CTX *mem_ctx, const struct ldb_val *idx_val, struct ldb_val *key); int ldb_kv_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); int ldb_kv_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req); int ldb_kv_delete_noindex(struct ldb_module *module, const struct ldb_message *msg); int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, const char *name, struct ldb_context *ldb, const char *options[], struct ldb_module **_module); int ldb_kv_index_sub_transaction_start(struct ldb_kv_private *ldb_kv); int ldb_kv_index_sub_transaction_cancel(struct ldb_kv_private *ldb_kv); int ldb_kv_index_sub_transaction_commit(struct ldb_kv_private *ldb_kv); #endif /* __LDB_KV_H__ */ ldb-2.0.8/ldb_key_value/ldb_kv_cache.c0000660000000000000000000004312513573675413017576 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldb key value cache functions * * Description: cache special records in a ldb/tdb * * Author: Andrew Tridgell */ #include "ldb_kv.h" #include "ldb_private.h" #define LDB_KV_FLAG_CASE_INSENSITIVE (1<<0) #define LDB_KV_FLAG_INTEGER (1<<1) #define LDB_KV_FLAG_UNIQUE_INDEX (1<<2) #define LDB_KV_FLAG_ORDERED_INTEGER (1<<3) /* valid attribute flags */ static const struct { const char *name; int value; } ldb_kv_valid_attr_flags[] = { { "CASE_INSENSITIVE", LDB_KV_FLAG_CASE_INSENSITIVE }, { "INTEGER", LDB_KV_FLAG_INTEGER }, { "ORDERED_INTEGER", LDB_KV_FLAG_ORDERED_INTEGER }, { "HIDDEN", 0 }, { "UNIQUE_INDEX", LDB_KV_FLAG_UNIQUE_INDEX}, { "NONE", 0 }, { NULL, 0 } }; /* de-register any special handlers for @ATTRIBUTES */ static void ldb_kv_attributes_unload(struct ldb_module *module) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_schema_attribute_remove_flagged(ldb, LDB_ATTR_FLAG_FROM_DB); } /* add up the attrib flags for a @ATTRIBUTES element */ static int ldb_kv_attributes_flags(struct ldb_message_element *el, unsigned *v) { unsigned int i; unsigned value = 0; for (i=0;inum_values;i++) { unsigned int j; for (j = 0; ldb_kv_valid_attr_flags[j].name; j++) { if (strcmp(ldb_kv_valid_attr_flags[j].name, (char *)el->values[i].data) == 0) { value |= ldb_kv_valid_attr_flags[j].value; break; } } if (ldb_kv_valid_attr_flags[j].name == NULL) { return -1; } } *v = value; return 0; } static int ldb_schema_attribute_compare(const void *p1, const void *p2) { const struct ldb_schema_attribute *sa1 = (const struct ldb_schema_attribute *)p1; const struct ldb_schema_attribute *sa2 = (const struct ldb_schema_attribute *)p2; return ldb_attr_cmp(sa1->name, sa2->name); } /* register any special handlers from @ATTRIBUTES */ static int ldb_kv_attributes_load(struct ldb_module *module) { struct ldb_schema_attribute *attrs; struct ldb_context *ldb; struct ldb_message *attrs_msg = NULL; struct ldb_dn *dn; unsigned int i; unsigned int num_loaded_attrs = 0; int r; ldb = ldb_module_get_ctx(module); if (ldb->schema.attribute_handler_override) { /* we skip loading the @ATTRIBUTES record when a module is supplying its own attribute handling */ return 0; } attrs_msg = ldb_msg_new(module); if (attrs_msg == NULL) { goto failed; } dn = ldb_dn_new(module, ldb, LDB_KV_ATTRIBUTES); if (dn == NULL) goto failed; r = ldb_kv_search_dn1(module, dn, attrs_msg, LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | LDB_UNPACK_DATA_FLAG_NO_DN); talloc_free(dn); if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { goto failed; } if (r == LDB_ERR_NO_SUCH_OBJECT || attrs_msg->num_elements == 0) { TALLOC_FREE(attrs_msg); return 0; } attrs = talloc_array(attrs_msg, struct ldb_schema_attribute, attrs_msg->num_elements + ldb->schema.num_attributes); if (attrs == NULL) { goto failed; } memcpy(attrs, ldb->schema.attributes, sizeof(ldb->schema.attributes[0]) * ldb->schema.num_attributes); /* mapping these flags onto ldap 'syntaxes' isn't strictly correct, but its close enough for now */ for (i=0;inum_elements;i++) { unsigned flags = 0, attr_flags = 0; const char *syntax; const struct ldb_schema_syntax *s; const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, attrs_msg->elements[i].name); if (a != NULL && a->flags & LDB_ATTR_FLAG_FIXED) { /* Must already be set in the array, and kept */ continue; } if (ldb_kv_attributes_flags(&attrs_msg->elements[i], &flags) != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'", attrs_msg->elements[i].name); goto failed; } if (flags & LDB_KV_FLAG_UNIQUE_INDEX) { attr_flags = LDB_ATTR_FLAG_UNIQUE_INDEX; } flags &= ~LDB_KV_FLAG_UNIQUE_INDEX; /* These are not currently flags, each is exclusive */ if (flags == LDB_KV_FLAG_CASE_INSENSITIVE) { syntax = LDB_SYNTAX_DIRECTORY_STRING; } else if (flags == LDB_KV_FLAG_INTEGER) { syntax = LDB_SYNTAX_INTEGER; } else if (flags == LDB_KV_FLAG_ORDERED_INTEGER) { syntax = LDB_SYNTAX_ORDERED_INTEGER; } else if (flags == 0) { syntax = LDB_SYNTAX_OCTET_STRING; } else { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid flag combination 0x%x for '%s' " "in @ATTRIBUTES", flags, attrs_msg->elements[i].name); goto failed; } s = ldb_standard_syntax_by_name(ldb, syntax); if (s == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid attribute syntax '%s' for '%s' " "in @ATTRIBUTES", syntax, attrs_msg->elements[i].name); goto failed; } attr_flags |= LDB_ATTR_FLAG_ALLOCATED | LDB_ATTR_FLAG_FROM_DB; r = ldb_schema_attribute_fill_with_syntax(ldb, attrs, attrs_msg->elements[i].name, attr_flags, s, &attrs[num_loaded_attrs + ldb->schema.num_attributes]); if (r != 0) { goto failed; } num_loaded_attrs++; } attrs = talloc_realloc(attrs_msg, attrs, struct ldb_schema_attribute, num_loaded_attrs + ldb->schema.num_attributes); if (attrs == NULL) { goto failed; } TYPESAFE_QSORT(attrs, num_loaded_attrs + ldb->schema.num_attributes, ldb_schema_attribute_compare); talloc_unlink(ldb, ldb->schema.attributes); ldb->schema.attributes = talloc_steal(ldb, attrs); ldb->schema.num_attributes = num_loaded_attrs + ldb->schema.num_attributes; TALLOC_FREE(attrs_msg); return 0; failed: TALLOC_FREE(attrs_msg); return -1; } /* register any index records we find for the DB */ static int ldb_kv_index_load(struct ldb_module *module, struct ldb_kv_private *ldb_kv) { struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_dn *indexlist_dn; int r, lmdb_subdb_version; if (ldb->schema.index_handler_override) { /* * we skip loading the @INDEXLIST record when a module is * supplying its own attribute handling */ ldb_kv->cache->attribute_indexes = true; ldb_kv->cache->one_level_indexes = ldb->schema.one_level_indexes; ldb_kv->cache->GUID_index_attribute = ldb->schema.GUID_index_attribute; ldb_kv->cache->GUID_index_dn_component = ldb->schema.GUID_index_dn_component; return 0; } talloc_free(ldb_kv->cache->indexlist); ldb_kv->cache->indexlist = ldb_msg_new(ldb_kv->cache); if (ldb_kv->cache->indexlist == NULL) { return -1; } ldb_kv->cache->one_level_indexes = false; ldb_kv->cache->attribute_indexes = false; indexlist_dn = ldb_dn_new(ldb_kv, ldb, LDB_KV_INDEXLIST); if (indexlist_dn == NULL) { return -1; } r = ldb_kv_search_dn1(module, indexlist_dn, ldb_kv->cache->indexlist, LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | LDB_UNPACK_DATA_FLAG_NO_DN); TALLOC_FREE(indexlist_dn); if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { return -1; } if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXONE) != NULL) { ldb_kv->cache->one_level_indexes = true; } if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR) != NULL) { ldb_kv->cache->attribute_indexes = true; } ldb_kv->cache->GUID_index_attribute = ldb_msg_find_attr_as_string( ldb_kv->cache->indexlist, LDB_KV_IDXGUID, NULL); ldb_kv->cache->GUID_index_dn_component = ldb_msg_find_attr_as_string( ldb_kv->cache->indexlist, LDB_KV_IDX_DN_GUID, NULL); lmdb_subdb_version = ldb_msg_find_attr_as_int( ldb_kv->cache->indexlist, LDB_KV_IDX_LMDB_SUBDB, 0); if (lmdb_subdb_version != 0) { ldb_set_errstring(ldb, "FATAL: This ldb_mdb database has " "been written in a new version of LDB " "using a sub-database index that " "is not understood by ldb " LDB_VERSION); return -1; } return 0; } /* initialise the baseinfo record */ static int ldb_kv_baseinfo_init(struct ldb_module *module) { struct ldb_context *ldb; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_message *msg; struct ldb_message_element el; struct ldb_val val; int ret; /* the initial sequence number must be different from the one set in ltdb_cache_free(). Thanks to Jon for pointing this out. */ const char *initial_sequence_number = "1"; ldb = ldb_module_get_ctx(module); ldb_kv->sequence_number = atof(initial_sequence_number); msg = ldb_msg_new(ldb_kv); if (msg == NULL) { goto failed; } msg->num_elements = 1; msg->elements = ⪙ msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO); if (!msg->dn) { goto failed; } el.name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER); if (!el.name) { goto failed; } el.values = &val; el.num_values = 1; el.flags = 0; val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number); if (!val.data) { goto failed; } val.length = 1; ret = ldb_kv_store(module, msg, TDB_INSERT); talloc_free(msg); return ret; failed: talloc_free(msg); errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } /* free any cache records */ static void ldb_kv_cache_free(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); ldb_kv->sequence_number = 0; talloc_free(ldb_kv->cache); ldb_kv->cache = NULL; } /* force a cache reload */ int ldb_kv_cache_reload(struct ldb_module *module) { ldb_kv_attributes_unload(module); ldb_kv_cache_free(module); return ldb_kv_cache_load(module); } static int get_pack_format_version(struct ldb_val key, struct ldb_val data, void *private_data) { uint32_t *v = (uint32_t *) private_data; return ldb_unpack_get_format(&data, v); } /* load the cache records */ int ldb_kv_cache_load(struct ldb_module *module) { struct ldb_context *ldb; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL; uint64_t seq; struct ldb_message *baseinfo = NULL, *options = NULL; const struct ldb_schema_attribute *a; bool have_write_txn = false; int r; struct ldb_val key; ldb = ldb_module_get_ctx(module); /* a very fast check to avoid extra database reads */ if (ldb_kv->cache != NULL && !ldb_kv->kv_ops->has_changed(ldb_kv)) { return 0; } if (ldb_kv->cache == NULL) { ldb_kv->cache = talloc_zero(ldb_kv, struct ldb_kv_cache); if (ldb_kv->cache == NULL) goto failed; } baseinfo = ldb_msg_new(ldb_kv->cache); if (baseinfo == NULL) goto failed; baseinfo_dn = ldb_dn_new(baseinfo, ldb, LDB_KV_BASEINFO); if (baseinfo_dn == NULL) goto failed; r = ldb_kv->kv_ops->lock_read(module); if (r != LDB_SUCCESS) { goto failed; } key = ldb_kv_key_dn(baseinfo, baseinfo_dn); if (!key.data) { goto failed_and_unlock; } /* Read packing format from first 4 bytes of @BASEINFO record */ r = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, get_pack_format_version, &ldb_kv->pack_format_version); /* possibly initialise the baseinfo */ if (r == LDB_ERR_NO_SUCH_OBJECT) { /* Give up the read lock, try again with a write lock */ r = ldb_kv->kv_ops->unlock_read(module); if (r != LDB_SUCCESS) { goto failed; } if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) { goto failed; } have_write_txn = true; /* * We need to write but haven't figured out packing format yet. * Just go with version 1 and we'll repack if we got it wrong. */ ldb_kv->pack_format_version = LDB_PACKING_FORMAT; ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT; /* error handling for ltdb_baseinfo_init() is by looking for the record again. */ ldb_kv_baseinfo_init(module); } else if (r != LDB_SUCCESS) { goto failed_and_unlock; } /* OK now we definitely have a @BASEINFO record so fetch it */ r = ldb_kv_search_dn1(module, baseinfo_dn, baseinfo, 0); if (r != LDB_SUCCESS) { goto failed_and_unlock; } /* Ignore the result, and update the sequence number */ ldb_kv->kv_ops->has_changed(ldb_kv); /* if the current internal sequence number is the same as the one in the database then assume the rest of the cache is OK */ seq = ldb_msg_find_attr_as_uint64(baseinfo, LDB_KV_SEQUENCE_NUMBER, 0); if (seq == ldb_kv->sequence_number) { goto done; } ldb_kv->sequence_number = seq; /* Read an interpret database options */ options = ldb_msg_new(ldb_kv->cache); if (options == NULL) goto failed_and_unlock; options_dn = ldb_dn_new(options, ldb, LDB_KV_OPTIONS); if (options_dn == NULL) goto failed_and_unlock; r = ldb_kv_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; } /* set flags if they do exist */ if (r == LDB_SUCCESS) { ldb_kv->check_base = ldb_msg_find_attr_as_bool(options, LDB_KV_CHECK_BASE, false); ldb_kv->disallow_dn_filter = ldb_msg_find_attr_as_bool( options, LDB_KV_DISALLOW_DN_FILTER, false); } else { ldb_kv->check_base = false; ldb_kv->disallow_dn_filter = false; } /* * ltdb_attributes_unload() calls internally talloc_free() on * any non-fixed elemnts in ldb->schema.attributes. * * NOTE WELL: This is per-ldb, not per module, so overwrites * the handlers across all databases when used under Samba's * partition module. */ ldb_kv_attributes_unload(module); if (ldb_kv_index_load(module, ldb_kv) == -1) { goto failed_and_unlock; } /* * NOTE WELL: This is per-ldb, not per module, so overwrites * the handlers across all databases when used under Samba's * partition module. */ if (ldb_kv_attributes_load(module) == -1) { goto failed_and_unlock; } /* * Initialise packing version and GUID index syntax, and force the * two to travel together, ie a GUID indexed database must use V2 * packing format and a DN indexed database must use V1. */ ldb_kv->GUID_index_syntax = NULL; if (ldb_kv->cache->GUID_index_attribute != NULL) { ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT_V2; /* * Now the attributes are loaded, set the guid_index_syntax. * This can't fail, it will return a default at worst */ a = ldb_schema_attribute_by_name( ldb, ldb_kv->cache->GUID_index_attribute); ldb_kv->GUID_index_syntax = a->syntax; } else { ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT; } done: if (have_write_txn) { if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) { goto failed; } } else { ldb_kv->kv_ops->unlock_read(module); } talloc_free(options); talloc_free(baseinfo); return 0; failed_and_unlock: if (have_write_txn) { ldb_kv->kv_ops->abort_write(ldb_kv); } else { ldb_kv->kv_ops->unlock_read(module); } failed: talloc_free(options); talloc_free(baseinfo); return -1; } /* increase the sequence number to indicate a database change */ int ldb_kv_increase_sequence_number(struct ldb_module *module) { struct ldb_context *ldb; void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct ldb_message *msg; struct ldb_message_element el[2]; struct ldb_val val; struct ldb_val val_time; time_t t = time(NULL); char *s = NULL; int ret; ldb = ldb_module_get_ctx(module); msg = ldb_msg_new(ldb_kv); if (msg == NULL) { errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } s = talloc_asprintf(msg, "%llu", ldb_kv->sequence_number + 1); if (!s) { talloc_free(msg); errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } msg->num_elements = ARRAY_SIZE(el); msg->elements = el; msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO); if (msg->dn == NULL) { talloc_free(msg); errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } el[0].name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER); if (el[0].name == NULL) { talloc_free(msg); errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } el[0].values = &val; el[0].num_values = 1; el[0].flags = LDB_FLAG_MOD_REPLACE; val.data = (uint8_t *)s; val.length = strlen(s); el[1].name = talloc_strdup(msg, LDB_KV_MOD_TIMESTAMP); if (el[1].name == NULL) { talloc_free(msg); errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } el[1].values = &val_time; el[1].num_values = 1; el[1].flags = LDB_FLAG_MOD_REPLACE; s = ldb_timestring(msg, t); if (s == NULL) { talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } val_time.data = (uint8_t *)s; val_time.length = strlen(s); ret = ldb_kv_modify_internal(module, msg, NULL); talloc_free(msg); if (ret == LDB_SUCCESS) { ldb_kv->sequence_number += 1; } /* updating the tdb_seqnum here avoids us reloading the cache records due to our own modification */ ldb_kv->kv_ops->has_changed(ldb_kv); return ret; } int ldb_kv_check_at_attributes_values(const struct ldb_val *value) { unsigned int i; for (i = 0; ldb_kv_valid_attr_flags[i].name != NULL; i++) { if ((strcmp(ldb_kv_valid_attr_flags[i].name, (char *)value->data) == 0)) { return 0; } } return -1; } ldb-2.0.8/ldb_key_value/ldb_kv_index.c0000660000000000000000000030363613573675413017650 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004-2009 ** 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 . */ /* * Name: ldb * * Component: ldb key value backend - indexing * * Description: indexing routines for ldb key value backend * * Author: Andrew Tridgell */ /* LDB Index design and choice of key: ======================================= LDB has index records held as LDB objects with a special record like: dn: @INDEX:attr:value value may be base64 encoded, if it is deemed not printable: dn: @INDEX:attr::base64-value In each record, there is two possible formats: The original format is: ----------------------- dn: @INDEX:NAME:DNSUPDATEPROXY @IDXVERSION: 2 @IDX: CN=DnsUpdateProxy,CN=Users,DC=addom,DC=samba,DC=example,DC=com In this format, @IDX is multi-valued, one entry for each match The corrosponding entry is stored in a TDB record with key: DN=CN=DNSUPDATEPROXY,CN=USERS,DC=ADDOM,DC=SAMBA,DC=EXAMPLE,DC=COM (This allows a scope BASE search to directly find the record via a simple casefold of the DN). The original mixed-case DN is stored in the entry iself. The new 'GUID index' format is: ------------------------------- dn: @INDEX:NAME:DNSUPDATEPROXY @IDXVERSION: 3 @IDX: [[...]] The binary guid is 16 bytes, as bytes and not expanded as hexidecimal or pretty-printed. The GUID is chosen from the message to be stored by the @IDXGUID attribute on @INDEXLIST. If there are multiple values the @IDX value simply becomes longer, in multiples of 16. The corrosponding entry is stored in a TDB record with key: GUID= This allows a very quick translation between the fixed-length index values and the TDB key, while seperating entries from other data in the TDB, should they be unlucky enough to start with the bytes of the 'DN=' prefix. Additionally, this allows a scope BASE search to directly find the record via a simple match on a GUID= extended DN, controlled via @IDX_DN_GUID on @INDEXLIST Exception for special @ DNs: @BASEINFO, @INDEXLIST and all other special DNs are stored as per the original format, as they are never referenced in an index and are used to bootstrap the database. Control points for choice of index mode --------------------------------------- The choice of index and TDB key mode is made based (for example, from Samba) on entries in the @INDEXLIST DN: dn: @INDEXLIST @IDXGUID: objectGUID @IDX_DN_GUID: GUID By default, the original DN format is used. Control points for choosing indexed attributes ---------------------------------------------- @IDXATTR controls if an attribute is indexed dn: @INDEXLIST @IDXATTR: samAccountName @IDXATTR: nETBIOSName C Override functions -------------------- void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, const char *GUID_index_attribute, const char *GUID_index_dn_component) This is used, particularly in combination with the below, instead of the @IDXGUID and @IDX_DN_GUID values in @INDEXLIST. void ldb_schema_set_override_indexlist(struct ldb_context *ldb, bool one_level_indexes); void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, ldb_attribute_handler_override_fn_t override, void *private_data); When the above two functions are called in combination, the @INDEXLIST values are not read from the DB, so ldb_schema_set_override_GUID_index() must be called. */ #include "ldb_kv.h" #include "../ldb_tdb/ldb_tdb.h" #include "ldb_private.h" #include "lib/util/binsearch.h" #include "lib/util/attr.h" struct dn_list { unsigned int count; struct ldb_val *dn; /* * Do not optimise the intersection of this list, * we must never return an entry not in this * list. This allows the index for * SCOPE_ONELEVEL to be trusted. */ bool strict; }; struct ldb_kv_idxptr { /* * In memory tdb to cache the index updates performed during a * transaction. This improves the performance of operations like * re-index and join */ struct tdb_context *itdb; int error; }; enum key_truncation { KEY_NOT_TRUNCATED, KEY_TRUNCATED, }; static int ldb_kv_write_index_dn_guid(struct ldb_module *module, const struct ldb_message *msg, int add); static int ldb_kv_index_dn_base_dn(struct ldb_module *module, struct ldb_kv_private *ldb_kv, struct ldb_dn *base_dn, struct dn_list *dn_list, enum key_truncation *truncation); static void ldb_kv_dn_list_sort(struct ldb_kv_private *ldb_kv, struct dn_list *list); /* we put a @IDXVERSION attribute on index entries. This allows us to tell if it was written by an older version */ #define LDB_KV_INDEXING_VERSION 2 #define LDB_KV_GUID_INDEXING_VERSION 3 static unsigned ldb_kv_max_key_length(struct ldb_kv_private *ldb_kv) { if (ldb_kv->max_key_length == 0) { return UINT_MAX; } return ldb_kv->max_key_length; } /* enable the idxptr mode when transactions start */ int ldb_kv_index_transaction_start( struct ldb_module *module, size_t cache_size) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); ldb_kv->idxptr = talloc_zero(ldb_kv, struct ldb_kv_idxptr); if (ldb_kv->idxptr == NULL) { return ldb_oom(ldb_module_get_ctx(module)); } ldb_kv->idxptr->itdb = tdb_open( NULL, cache_size, TDB_INTERNAL, O_RDWR, 0); if (ldb_kv->idxptr->itdb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } /* see if two ldb_val structures contain exactly the same data return -1 or 1 for a mismatch, 0 for match */ static int ldb_val_equal_exact_for_qsort(const struct ldb_val *v1, const struct ldb_val *v2) { if (v1->length > v2->length) { return -1; } if (v1->length < v2->length) { return 1; } return memcmp(v1->data, v2->data, v1->length); } /* see if two ldb_val structures contain exactly the same data return -1 or 1 for a mismatch, 0 for match */ static int ldb_val_equal_exact_ordered(const struct ldb_val v1, const struct ldb_val *v2) { if (v1.length > v2->length) { return -1; } if (v1.length < v2->length) { return 1; } return memcmp(v1.data, v2->data, v1.length); } /* find a entry in a dn_list, using a ldb_val. Uses a case sensitive binary-safe comparison for the 'dn' returns -1 if not found This is therefore safe when the value is a GUID in the future */ static int ldb_kv_dn_list_find_val(struct ldb_kv_private *ldb_kv, const struct dn_list *list, const struct ldb_val *v) { unsigned int i; struct ldb_val *exact = NULL, *next = NULL; if (ldb_kv->cache->GUID_index_attribute == NULL) { for (i=0; icount; i++) { if (ldb_val_equal_exact(&list->dn[i], v) == 1) { return i; } } return -1; } BINARY_ARRAY_SEARCH_GTE(list->dn, list->count, *v, ldb_val_equal_exact_ordered, exact, next); if (exact == NULL) { return -1; } /* Not required, but keeps the compiler quiet */ if (next != NULL) { return -1; } i = exact - list->dn; return i; } /* find a entry in a dn_list. Uses a case sensitive comparison with the dn returns -1 if not found */ static int ldb_kv_dn_list_find_msg(struct ldb_kv_private *ldb_kv, struct dn_list *list, const struct ldb_message *msg) { struct ldb_val v; const struct ldb_val *key_val; if (ldb_kv->cache->GUID_index_attribute == NULL) { const char *dn_str = ldb_dn_get_linearized(msg->dn); v.data = discard_const_p(unsigned char, dn_str); v.length = strlen(dn_str); } else { key_val = ldb_msg_find_ldb_val( msg, ldb_kv->cache->GUID_index_attribute); if (key_val == NULL) { return -1; } v = *key_val; } return ldb_kv_dn_list_find_val(ldb_kv, list, &v); } /* this is effectively a cast function, but with lots of paranoia checks and also copes with CPUs that are fussy about pointer alignment */ static struct dn_list *ldb_kv_index_idxptr(struct ldb_module *module, TDB_DATA rec) { struct dn_list *list; if (rec.dsize != sizeof(void *)) { ldb_asprintf_errstring(ldb_module_get_ctx(module), "Bad data size for idxptr %u", (unsigned)rec.dsize); return NULL; } /* note that we can't just use a cast here, as rec.dptr may not be aligned sufficiently for a pointer. A cast would cause platforms like some ARM CPUs to crash */ memcpy(&list, rec.dptr, sizeof(void *)); list = talloc_get_type(list, struct dn_list); if (list == NULL) { ldb_asprintf_errstring(ldb_module_get_ctx(module), "Bad type '%s' for idxptr", talloc_get_name(list)); return NULL; } return list; } enum dn_list_will_be_read_only { DN_LIST_MUTABLE = 0, DN_LIST_WILL_BE_READ_ONLY = 1, }; /* return the @IDX list in an index entry for a dn as a struct dn_list */ static int ldb_kv_dn_list_load(struct ldb_module *module, struct ldb_kv_private *ldb_kv, struct ldb_dn *dn, struct dn_list *list, enum dn_list_will_be_read_only read_only) { struct ldb_message *msg; int ret, version; struct ldb_message_element *el; TDB_DATA rec = {0}; struct dn_list *list2; bool from_primary_cache = false; TDB_DATA key = {0}; list->dn = NULL; list->count = 0; list->strict = false; /* * See if we have an in memory index cache */ if (ldb_kv->idxptr == NULL) { goto normal_index; } key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); key.dsize = strlen((char *)key.dptr); /* * Have we cached this index record? * If we have a nested transaction cache try that first. * then try the transaction cache. * if the record is not cached it will need to be read from disk. */ if (ldb_kv->nested_idx_ptr != NULL) { rec = tdb_fetch(ldb_kv->nested_idx_ptr->itdb, key); } if (rec.dptr == NULL) { from_primary_cache = true; rec = tdb_fetch(ldb_kv->idxptr->itdb, key); } if (rec.dptr == NULL) { goto normal_index; } /* we've found an in-memory index entry */ list2 = ldb_kv_index_idxptr(module, rec); if (list2 == NULL) { free(rec.dptr); return LDB_ERR_OPERATIONS_ERROR; } free(rec.dptr); /* * If this is a read only transaction the indexes will not be * changed so we don't need a copy in the event of a rollback * * In this case make an early return */ if (read_only == DN_LIST_WILL_BE_READ_ONLY) { *list = *list2; return LDB_SUCCESS; } /* * record was read from the sub transaction cache, so we have * already copied the primary cache record */ if (!from_primary_cache) { *list = *list2; return LDB_SUCCESS; } /* * No index sub transaction active, so no need to cache a copy */ if (ldb_kv->nested_idx_ptr == NULL) { *list = *list2; return LDB_SUCCESS; } /* * There is an active index sub transaction, and the record was * found in the primary index transaction cache. A copy of the * record needs be taken to prevent the original entry being * altered, until the index sub transaction is committed. */ { struct ldb_val *dns = NULL; size_t x = 0; dns = talloc_array( list, struct ldb_val, list2->count); if (dns == NULL) { return LDB_ERR_OPERATIONS_ERROR; } for (x = 0; x < list2->count; x++) { dns[x].length = list2->dn[x].length; dns[x].data = talloc_memdup( dns, list2->dn[x].data, list2->dn[x].length); if (dns[x].data == NULL) { TALLOC_FREE(dns); return LDB_ERR_OPERATIONS_ERROR; } } list->dn = dns; list->count = list2->count; } return LDB_SUCCESS; /* * Index record not found in the caches, read it from the * database. */ normal_index: msg = ldb_msg_new(list); if (msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_search_dn1(module, dn, msg, LDB_UNPACK_DATA_FLAG_NO_DN | /* * The entry point ldb_kv_search_indexed is * only called from the read-locked * ldb_kv_search. */ LDB_UNPACK_DATA_FLAG_READ_LOCKED); if (ret != LDB_SUCCESS) { talloc_free(msg); return ret; } el = ldb_msg_find_element(msg, LDB_KV_IDX); if (!el) { talloc_free(msg); return LDB_SUCCESS; } version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0); /* * we avoid copying the strings by stealing the list. We have * to steal msg onto el->values (which looks odd) because * the memory is allocated on msg, not on each value. */ if (ldb_kv->cache->GUID_index_attribute == NULL) { /* check indexing version number */ if (version != LDB_KV_INDEXING_VERSION) { ldb_debug_set(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, "Wrong DN index version %d " "expected %d for %s", version, LDB_KV_INDEXING_VERSION, ldb_dn_get_linearized(dn)); talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } talloc_steal(el->values, msg); list->dn = talloc_steal(list, el->values); list->count = el->num_values; } else { unsigned int i; if (version != LDB_KV_GUID_INDEXING_VERSION) { /* This is quite likely during the DB startup on first upgrade to using a GUID index */ ldb_debug_set(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, "Wrong GUID index version %d " "expected %d for %s", version, LDB_KV_GUID_INDEXING_VERSION, ldb_dn_get_linearized(dn)); talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } if (el->num_values == 0) { talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0) { talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } list->count = el->values[0].length / LDB_KV_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. */ talloc_steal(list->dn, msg); for (i = 0; i < list->count; i++) { list->dn[i].data = &el->values[0].data[i * LDB_KV_GUID_SIZE]; list->dn[i].length = LDB_KV_GUID_SIZE; } } /* We don't need msg->elements any more */ talloc_free(msg->elements); return LDB_SUCCESS; } int ldb_kv_key_dn_from_idx(struct ldb_module *module, struct ldb_kv_private *ldb_kv, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct ldb_val *ldb_key) { 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 = ldb_kv_index_dn_base_dn(module, ldb_kv, dn, list, &truncation); if (ret != LDB_SUCCESS) { TALLOC_FREE(list); return ret; } if (list->count == 0) { TALLOC_FREE(list); return LDB_ERR_NO_SUCH_OBJECT; } if (list->count > 1 && truncation == KEY_NOT_TRUNCATED) { const char *dn_str = ldb_dn_get_linearized(dn); ldb_asprintf_errstring(ldb_module_get_ctx(module), __location__ ": Failed to read DN index " "against %s for %s: too many " "values (%u > 1)", ldb_kv->cache->GUID_index_attribute, dn_str, list->count); TALLOC_FREE(list); 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 */ unsigned int i; index = -1; for (i=0; i < list->count; i++) { uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; struct ldb_val key = { .data = guid_key, .length = sizeof(guid_key) }; const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS; struct ldb_message *rec = ldb_msg_new(ldb); if (rec == NULL) { TALLOC_FREE(list); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_idx_to_key( module, ldb_kv, ldb, &list->dn[i], &key); if (ret != LDB_SUCCESS) { TALLOC_FREE(list); TALLOC_FREE(rec); return ret; } ret = ldb_kv_search_key(module, ldb_kv, key, rec, flags); if (key.data != guid_key) { TALLOC_FREE(key.data); } 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 ldb_key memory is allocated by the caller */ ret = ldb_kv_guid_to_key(&list->dn[index], ldb_key); TALLOC_FREE(list); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } /* save a dn_list into a full @IDX style record */ static int ldb_kv_dn_list_store_full(struct ldb_module *module, struct ldb_kv_private *ldb_kv, struct ldb_dn *dn, struct dn_list *list) { struct ldb_message *msg; int ret; msg = ldb_msg_new(module); if (!msg) { return ldb_module_oom(module); } msg->dn = dn; if (list->count == 0) { ret = ldb_kv_delete_noindex(module, msg); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ret = LDB_SUCCESS; } TALLOC_FREE(msg); return ret; } if (ldb_kv->cache->GUID_index_attribute == NULL) { ret = ldb_msg_add_fmt(msg, LDB_KV_IDXVERSION, "%u", LDB_KV_INDEXING_VERSION); if (ret != LDB_SUCCESS) { TALLOC_FREE(msg); return ldb_module_oom(module); } } else { ret = ldb_msg_add_fmt(msg, LDB_KV_IDXVERSION, "%u", LDB_KV_GUID_INDEXING_VERSION); if (ret != LDB_SUCCESS) { TALLOC_FREE(msg); return ldb_module_oom(module); } } if (list->count > 0) { struct ldb_message_element *el; ret = ldb_msg_add_empty(msg, LDB_KV_IDX, LDB_FLAG_MOD_ADD, &el); if (ret != LDB_SUCCESS) { TALLOC_FREE(msg); return ldb_module_oom(module); } if (ldb_kv->cache->GUID_index_attribute == NULL) { el->values = list->dn; el->num_values = list->count; } else { struct ldb_val v; unsigned int i; el->values = talloc_array(msg, struct ldb_val, 1); if (el->values == NULL) { TALLOC_FREE(msg); return ldb_module_oom(module); } v.data = talloc_array_size(el->values, list->count, LDB_KV_GUID_SIZE); if (v.data == NULL) { TALLOC_FREE(msg); return ldb_module_oom(module); } v.length = talloc_get_size(v.data); for (i = 0; i < list->count; i++) { if (list->dn[i].length != LDB_KV_GUID_SIZE) { TALLOC_FREE(msg); return ldb_module_operr(module); } memcpy(&v.data[LDB_KV_GUID_SIZE*i], list->dn[i].data, LDB_KV_GUID_SIZE); } el->values[0] = v; el->num_values = 1; } } ret = ldb_kv_store(module, msg, TDB_REPLACE); TALLOC_FREE(msg); return ret; } /* save a dn_list into the database, in either @IDX or internal format */ static int ldb_kv_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, struct dn_list *list) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); TDB_DATA rec = {0}; TDB_DATA key = {0}; int ret = LDB_SUCCESS; struct dn_list *list2 = NULL; struct ldb_kv_idxptr *idxptr = NULL; 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); /* * If there is an index sub transaction active, update the * sub transaction index cache. Otherwise update the * primary index cache */ if (ldb_kv->nested_idx_ptr != NULL) { idxptr = ldb_kv->nested_idx_ptr; } else { idxptr = ldb_kv->idxptr; } /* * Get the cache entry for the index * * As the value in the cache is a pointer to a dn_list we update * the dn_list directly. * */ rec = tdb_fetch(idxptr->itdb, key); if (rec.dptr != NULL) { list2 = ldb_kv_index_idxptr(module, rec); if (list2 == NULL) { free(rec.dptr); return LDB_ERR_OPERATIONS_ERROR; } free(rec.dptr); /* Now put the updated pointer back in the cache */ if (list->dn == NULL) { list2->dn = NULL; list2->count = 0; } else { list2->dn = talloc_steal(list2, list->dn); list2->count = list->count; } return LDB_SUCCESS; } list2 = talloc(idxptr, struct dn_list); if (list2 == NULL) { return LDB_ERR_OPERATIONS_ERROR; } list2->dn = talloc_steal(list2, list->dn); list2->count = list->count; rec.dptr = (uint8_t *)&list2; rec.dsize = sizeof(void *); /* * This is not a store into the main DB, but into an in-memory * TDB, so we don't need a guard on ltdb->read_only * * Also as we directly update the in memory dn_list for existing * cache entries we must be adding a new entry to the cache. */ ret = tdb_store(idxptr->itdb, key, rec, TDB_INSERT); if (ret != 0) { return ltdb_err_map( tdb_error(idxptr->itdb)); } return LDB_SUCCESS; } /* traverse function for storing the in-memory index entries on disk */ static int ldb_kv_index_traverse_store(_UNUSED_ struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { struct ldb_module *module = state; struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); struct ldb_dn *dn; struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_val v; struct dn_list *list; list = ldb_kv_index_idxptr(module, data); if (list == NULL) { ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; return -1; } v.data = key.dptr; v.length = strnlen((char *)key.dptr, key.dsize); dn = ldb_dn_from_ldb_val(module, ldb, &v); if (dn == NULL) { ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data); ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; return -1; } ldb_kv->idxptr->error = ldb_kv_dn_list_store_full(module, ldb_kv, dn, list); talloc_free(dn); if (ldb_kv->idxptr->error != 0) { return -1; } return 0; } /* cleanup the idxptr mode when transaction commits */ int ldb_kv_index_transaction_commit(struct ldb_module *module) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); int ret; struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_reset_err_string(ldb); if (ldb_kv->idxptr->itdb) { tdb_traverse( ldb_kv->idxptr->itdb, ldb_kv_index_traverse_store, module); tdb_close(ldb_kv->idxptr->itdb); } ret = ldb_kv->idxptr->error; if (ret != LDB_SUCCESS) { if (!ldb_errstring(ldb)) { ldb_set_errstring(ldb, ldb_strerror(ret)); } ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb)); } talloc_free(ldb_kv->idxptr); ldb_kv->idxptr = NULL; return ret; } /* cleanup the idxptr mode when transaction cancels */ int ldb_kv_index_transaction_cancel(struct ldb_module *module) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); if (ldb_kv->idxptr && ldb_kv->idxptr->itdb) { tdb_close(ldb_kv->idxptr->itdb); } TALLOC_FREE(ldb_kv->idxptr); if (ldb_kv->nested_idx_ptr && ldb_kv->nested_idx_ptr->itdb) { tdb_close(ldb_kv->nested_idx_ptr->itdb); } TALLOC_FREE(ldb_kv->nested_idx_ptr); return LDB_SUCCESS; } /* return the dn key to be used for an index the caller is responsible for freeing */ static struct ldb_dn *ldb_kv_index_key(struct ldb_context *ldb, struct ldb_kv_private *ldb_kv, const char *attr, const struct ldb_val *value, const struct ldb_schema_attribute **ap, enum key_truncation *truncation) { struct ldb_dn *ret; struct ldb_val v; const struct ldb_schema_attribute *a = NULL; char *attr_folded = NULL; const char *attr_for_dn = NULL; int r; bool should_b64_encode; unsigned int max_key_length = ldb_kv_max_key_length(ldb_kv); size_t key_len = 0; size_t attr_len = 0; const size_t indx_len = sizeof(LDB_KV_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; struct ldb_val empty; /* * Accept a NULL value as a request for a key with no value. This is * different from passing an empty value, which might be given * significance by some canonicalise functions. */ bool empty_val = value == NULL; if (empty_val) { empty.length = 0; empty.data = discard_const_p(unsigned char, ""); value = ∅ } if (attr[0] == '@') { attr_for_dn = attr; v = *value; if (ap != NULL) { *ap = NULL; } } else { attr_folded = ldb_attr_casefold(ldb, attr); if (!attr_folded) { return NULL; } attr_for_dn = attr_folded; a = ldb_schema_attribute_by_name(ldb, attr); if (ap) { *ap = a; } if (empty_val) { v = *value; } else { ldb_attr_handler_t fn; if (a->syntax->index_format_fn && ldb_kv->cache->GUID_index_attribute != NULL) { fn = a->syntax->index_format_fn; } else { fn = a->syntax->canonicalise_fn; } r = fn(ldb, ldb, value, &v); if (r != LDB_SUCCESS) { const char *errstr = ldb_errstring(ldb); /* canonicalisation can be refused. For example, a attribute that takes wildcards will refuse to canonicalise if the value contains a wildcard */ ldb_asprintf_errstring(ldb, "Failed to create " "index key for " "attribute '%s':%s%s%s", attr, ldb_strerror(r), (errstr?":":""), (errstr?errstr:"")); talloc_free(attr_folded); 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 * casefold and lineraized, that is good enough. That already * avoids embedded NUL etc. */ if (ldb_kv->cache->GUID_index_attribute != NULL) { if (strcmp(attr, LDB_KV_IDXDN) == 0) { should_b64_encode = false; } else if (strcmp(attr, LDB_KV_IDXONE) == 0) { /* * We can only change the behaviour for IDXONE * when the GUID index is enabled */ should_b64_encode = false; } else { should_b64_encode = ldb_should_b64_encode(ldb, &v); } } else { should_b64_encode = ldb_should_b64_encode(ldb, &v); } 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", LDB_KV_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", LDB_KV_INDEX, attr_for_dn, frmt_len, 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", LDB_KV_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", LDB_KV_INDEX, attr_for_dn, frmt_len, (char *)v.data); } } if (v.data != value->data && !empty_val) { talloc_free(v.data); } talloc_free(attr_folded); return ret; } /* see if a attribute value is in the list of indexed attributes */ static bool ldb_kv_is_indexed(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const char *attr) { struct ldb_context *ldb = ldb_module_get_ctx(module); unsigned int i; struct ldb_message_element *el; if ((ldb_kv->cache->GUID_index_attribute != NULL) && (ldb_attr_cmp(attr, ldb_kv->cache->GUID_index_attribute) == 0)) { /* Implicity covered, this is the index key */ return false; } if (ldb->schema.index_handler_override) { const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, attr); if (a == NULL) { return false; } if (a->flags & LDB_ATTR_FLAG_INDEXED) { return true; } else { return false; } } if (!ldb_kv->cache->attribute_indexes) { return false; } el = ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR); if (el == NULL) { return false; } /* TODO: this is too expensive! At least use a binary search */ for (i=0; inum_values; i++) { if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) { return true; } } return false; } /* in the following logic functions, the return value is treated as follows: LDB_SUCCESS: we found some matching index values LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call, we'll need a full search */ /* return a list of dn's that might match a simple indexed search (an equality search only) */ static int ldb_kv_index_dn_simple(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list) { struct ldb_context *ldb; struct ldb_dn *dn; int ret; enum key_truncation truncation = KEY_NOT_TRUNCATED; ldb = ldb_module_get_ctx(module); list->count = 0; list->dn = NULL; /* if the attribute isn't in the list of indexed attributes then this node needs a full search */ if (!ldb_kv_is_indexed(module, ldb_kv, tree->u.equality.attr)) { return LDB_ERR_OPERATIONS_ERROR; } /* the attribute is indexed. Pull the list of DNs that match the search criterion */ dn = ldb_kv_index_key(ldb, ldb_kv, 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(). */ if (!dn) return LDB_ERR_OPERATIONS_ERROR; ret = ldb_kv_dn_list_load(module, ldb_kv, dn, list, DN_LIST_WILL_BE_READ_ONLY); talloc_free(dn); return ret; } static bool list_union(struct ldb_context *ldb, struct ldb_kv_private *ldb_kv, struct dn_list *list, struct dn_list *list2); /* return a list of dn's that might match a leaf indexed search */ static int ldb_kv_index_dn_leaf(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list) { if (ldb_kv->disallow_dn_filter && (ldb_attr_cmp(tree->u.equality.attr, "dn") == 0)) { /* in AD mode we do not support "(dn=...)" search filters */ list->dn = NULL; list->count = 0; return LDB_SUCCESS; } if (tree->u.equality.attr[0] == '@') { /* Do not allow a indexed search against an @ */ list->dn = NULL; list->count = 0; 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), &tree->u.equality.value); if (dn == NULL) { /* If we can't parse it, no match */ list->dn = NULL; list->count = 0; 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 * * We can't call TALLOC_FREE(dn) as this must belong * to list for the memory to remain valid. */ return ldb_kv_index_dn_base_dn( module, ldb_kv, 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(). */ } else if ((ldb_kv->cache->GUID_index_attribute != NULL) && (ldb_attr_cmp(tree->u.equality.attr, ldb_kv->cache->GUID_index_attribute) == 0)) { int ret; struct ldb_context *ldb = ldb_module_get_ctx(module); list->dn = talloc_array(list, struct ldb_val, 1); if (list->dn == NULL) { ldb_module_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* * We need to go via the canonicalise_fn() to * ensure we get the index in binary, rather * than a string */ ret = ldb_kv->GUID_index_syntax->canonicalise_fn( ldb, list->dn, &tree->u.equality.value, &list->dn[0]); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } list->count = 1; return LDB_SUCCESS; } return ldb_kv_index_dn_simple(module, ldb_kv, tree, list); } /* list intersection list = list & list2 */ static bool list_intersect(struct ldb_kv_private *ldb_kv, struct dn_list *list, const struct dn_list *list2) { const struct dn_list *short_list, *long_list; struct dn_list *list3; unsigned int i; if (list->count == 0) { /* 0 & X == 0 */ return true; } if (list2->count == 0) { /* X & 0 == 0 */ list->count = 0; list->dn = NULL; return true; } /* * In both of the below we check for strict and in that * case do not optimise the intersection of this list, * we must never return an entry not in this * list. This allows the index for * SCOPE_ONELEVEL to be trusted. */ /* the indexing code is allowed to return a longer list than what really matches, as all results are filtered by the full expression at the end - this shortcut avoids a lot of work in some cases */ if (list->count < 2 && list2->count > 10 && list2->strict == false) { return true; } if (list2->count < 2 && list->count > 10 && list->strict == false) { list->count = list2->count; list->dn = list2->dn; /* note that list2 may not be the parent of list2->dn, as list2->dn may be owned by ltdb->idxptr. In that case we expect this reparent call to fail, which is OK */ talloc_reparent(list2, list, list2->dn); return true; } if (list->count > list2->count) { short_list = list2; long_list = list; } else { short_list = list; long_list = list2; } list3 = talloc_zero(list, struct dn_list); if (list3 == NULL) { return false; } list3->dn = talloc_array(list3, struct ldb_val, MIN(list->count, list2->count)); if (!list3->dn) { talloc_free(list3); return false; } list3->count = 0; for (i=0;icount;i++) { /* For the GUID index case, this is a binary search */ if (ldb_kv_dn_list_find_val( ldb_kv, long_list, &short_list->dn[i]) != -1) { list3->dn[list3->count] = short_list->dn[i]; list3->count++; } } list->strict |= list2->strict; list->dn = talloc_steal(list, list3->dn); list->count = list3->count; talloc_free(list3); return true; } /* list union list = list | list2 */ static bool list_union(struct ldb_context *ldb, struct ldb_kv_private *ldb_kv, struct dn_list *list, struct dn_list *list2) { struct ldb_val *dn3; unsigned int i = 0, j = 0, k = 0; if (list2->count == 0) { /* X | 0 == X */ return true; } if (list->count == 0) { /* 0 | X == X */ list->count = list2->count; list->dn = list2->dn; /* note that list2 may not be the parent of list2->dn, as list2->dn may be owned by ltdb->idxptr. In that case we expect this reparent call to fail, which is OK */ talloc_reparent(list2, list, list2->dn); return true; } /* * Sort the lists (if not in GUID DN mode) so we can do * the de-duplication during the merge * * NOTE: This can sort the in-memory index values, as list or * list2 might not be a copy! */ ldb_kv_dn_list_sort(ldb_kv, list); ldb_kv_dn_list_sort(ldb_kv, list2); dn3 = talloc_array(list, struct ldb_val, list->count + list2->count); if (!dn3) { ldb_oom(ldb); return false; } while (i < list->count || j < list2->count) { int cmp; if (i >= list->count) { cmp = 1; } else if (j >= list2->count) { cmp = -1; } else { cmp = ldb_val_equal_exact_ordered(list->dn[i], &list2->dn[j]); } if (cmp < 0) { /* Take list */ dn3[k] = list->dn[i]; i++; k++; } else if (cmp > 0) { /* Take list2 */ dn3[k] = list2->dn[j]; j++; k++; } else { /* Equal, take list */ dn3[k] = list->dn[i]; i++; j++; k++; } } list->dn = dn3; list->count = k; return true; } static int ldb_kv_index_dn(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list); /* process an OR list (a union) */ static int ldb_kv_index_dn_or(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list) { struct ldb_context *ldb; unsigned int i; ldb = ldb_module_get_ctx(module); list->dn = NULL; list->count = 0; for (i=0; iu.list.num_elements; i++) { struct dn_list *list2; int ret; list2 = talloc_zero(list, struct dn_list); if (list2 == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_index_dn( module, ldb_kv, tree->u.list.elements[i], list2); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* X || 0 == X */ talloc_free(list2); continue; } if (ret != LDB_SUCCESS) { /* X || * == * */ talloc_free(list2); return ret; } if (!list_union(ldb, ldb_kv, list, list2)) { talloc_free(list2); return LDB_ERR_OPERATIONS_ERROR; } } if (list->count == 0) { return LDB_ERR_NO_SUCH_OBJECT; } return LDB_SUCCESS; } /* NOT an index results */ static int ldb_kv_index_dn_not(_UNUSED_ struct ldb_module *module, _UNUSED_ struct ldb_kv_private *ldb_kv, _UNUSED_ const struct ldb_parse_tree *tree, _UNUSED_ struct dn_list *list) { /* the only way to do an indexed not would be if we could negate the not via another not or if we knew the total number of database elements so we could know that the existing expression covered the whole database. instead, we just give up, and rely on a full index scan (unless an outer & manages to reduce the list) */ return LDB_ERR_OPERATIONS_ERROR; } /* * These things are unique, so avoid a full scan if this is a search * by GUID, DN or a unique attribute */ static bool ldb_kv_index_unique(struct ldb_context *ldb, struct ldb_kv_private *ldb_kv, const char *attr) { const struct ldb_schema_attribute *a; if (ldb_kv->cache->GUID_index_attribute != NULL) { if (ldb_attr_cmp(attr, ldb_kv->cache->GUID_index_attribute) == 0) { return true; } } if (ldb_attr_dn(attr) == 0) { return true; } a = ldb_schema_attribute_by_name(ldb, attr); if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { return true; } return false; } /* process an AND expression (intersection) */ static int ldb_kv_index_dn_and(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list) { struct ldb_context *ldb; unsigned int i; bool found; ldb = ldb_module_get_ctx(module); list->dn = NULL; list->count = 0; /* in the first pass we only look for unique simple equality tests, in the hope of avoiding having to look at any others */ for (i=0; iu.list.num_elements; i++) { const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; int ret; if (subtree->operation != LDB_OP_EQUALITY || !ldb_kv_index_unique( ldb, ldb_kv, subtree->u.equality.attr)) { continue; } ret = ldb_kv_index_dn(module, ldb_kv, subtree, list); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* 0 && X == 0 */ return LDB_ERR_NO_SUCH_OBJECT; } if (ret == LDB_SUCCESS) { /* a unique index match means we can * stop. Note that we don't care if we return * a few too many objects, due to later * filtering */ return LDB_SUCCESS; } } /* now do a full intersection */ found = false; for (i=0; iu.list.num_elements; i++) { const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; struct dn_list *list2; int ret; list2 = talloc_zero(list, struct dn_list); if (list2 == NULL) { return ldb_module_oom(module); } ret = ldb_kv_index_dn(module, ldb_kv, subtree, list2); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* X && 0 == 0 */ list->dn = NULL; list->count = 0; talloc_free(list2); return LDB_ERR_NO_SUCH_OBJECT; } if (ret != LDB_SUCCESS) { /* this didn't adding anything */ talloc_free(list2); continue; } if (!found) { talloc_reparent(list2, list, list->dn); list->dn = list2->dn; list->count = list2->count; found = true; } else if (!list_intersect(ldb_kv, list, list2)) { talloc_free(list2); return LDB_ERR_OPERATIONS_ERROR; } if (list->count == 0) { list->dn = NULL; return LDB_ERR_NO_SUCH_OBJECT; } if (list->count < 2) { /* it isn't worth loading the next part of the tree */ return LDB_SUCCESS; } } if (!found) { /* none of the attributes were indexed */ return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } struct ldb_kv_ordered_index_context { struct ldb_module *module; int error; struct dn_list *dn_list; }; static int traverse_range_index(_UNUSED_ struct ldb_kv_private *ldb_kv, _UNUSED_ struct ldb_val key, struct ldb_val data, void *state) { struct ldb_context *ldb; struct ldb_kv_ordered_index_context *ctx = (struct ldb_kv_ordered_index_context *)state; struct ldb_module *module = ctx->module; struct ldb_message_element *el = NULL; struct ldb_message *msg = NULL; int version; size_t dn_array_size, additional_length; unsigned int i; ldb = ldb_module_get_ctx(module); msg = ldb_msg_new(module); ctx->error = ldb_unpack_data_flags(ldb, &data, msg, LDB_UNPACK_DATA_FLAG_NO_DN); if (ctx->error != LDB_SUCCESS) { talloc_free(msg); return ctx->error; } el = ldb_msg_find_element(msg, LDB_KV_IDX); if (!el) { talloc_free(msg); return LDB_SUCCESS; } version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0); /* * we avoid copying the strings by stealing the list. We have * to steal msg onto el->values (which looks odd) because * the memory is allocated on msg, not on each value. */ if (version != LDB_KV_GUID_INDEXING_VERSION) { /* This is quite likely during the DB startup on first upgrade to using a GUID index */ ldb_debug_set(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, __location__ ": Wrong GUID index version %d expected %d", version, LDB_KV_GUID_INDEXING_VERSION); talloc_free(msg); ctx->error = LDB_ERR_OPERATIONS_ERROR; return ctx->error; } if (el->num_values == 0) { talloc_free(msg); ctx->error = LDB_ERR_OPERATIONS_ERROR; return ctx->error; } if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0 || el->values[0].length == 0) { talloc_free(msg); ctx->error = LDB_ERR_OPERATIONS_ERROR; return ctx->error; } dn_array_size = talloc_array_length(ctx->dn_list->dn); additional_length = el->values[0].length / LDB_KV_GUID_SIZE; if (ctx->dn_list->count + additional_length < ctx->dn_list->count) { talloc_free(msg); ctx->error = LDB_ERR_OPERATIONS_ERROR; return ctx->error; } if ((ctx->dn_list->count + additional_length) >= dn_array_size) { size_t new_array_length; if (dn_array_size * 2 < dn_array_size) { talloc_free(msg); ctx->error = LDB_ERR_OPERATIONS_ERROR; return ctx->error; } new_array_length = MAX(ctx->dn_list->count + additional_length, dn_array_size * 2); ctx->dn_list->dn = talloc_realloc(ctx->dn_list, ctx->dn_list->dn, struct ldb_val, new_array_length); } if (ctx->dn_list->dn == NULL) { talloc_free(msg); ctx->error = LDB_ERR_OPERATIONS_ERROR; return ctx->error; } /* * The actual data is on msg. */ talloc_steal(ctx->dn_list->dn, msg); for (i = 0; i < additional_length; i++) { ctx->dn_list->dn[i + ctx->dn_list->count].data = &el->values[0].data[i * LDB_KV_GUID_SIZE]; ctx->dn_list->dn[i + ctx->dn_list->count].length = LDB_KV_GUID_SIZE; } ctx->dn_list->count += additional_length; talloc_free(msg->elements); return LDB_SUCCESS; } /* * >= and <= indexing implemented using lexicographically sorted keys * * We only run this in GUID indexing mode and when there is no write * transaction (only implicit read locks are being held). Otherwise, we would * have to deal with the in-memory index cache. * * We rely on the implementation of index_format_fn on a schema syntax which * will can help us to construct keys which can be ordered correctly, and we * terminate using schema agnostic start and end keys. * * index_format_fn must output values which can be memcmp-able to produce the * correct ordering as defined by the schema syntax class. */ static int ldb_kv_index_dn_ordered(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list, bool ascending) { enum key_truncation truncation = KEY_NOT_TRUNCATED; struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_val ldb_key = { 0 }, ldb_key2 = { 0 }; struct ldb_val start_key, end_key; struct ldb_dn *key_dn = NULL; const struct ldb_schema_attribute *a = NULL; struct ldb_kv_ordered_index_context ctx; int ret; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (!ldb_kv_is_indexed(module, ldb_kv, tree->u.comparison.attr)) { return LDB_ERR_OPERATIONS_ERROR; } if (ldb_kv->cache->GUID_index_attribute == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* bail out if we're in a transaction, full search instead. */ if (ldb_kv->kv_ops->transaction_active(ldb_kv)) { return LDB_ERR_OPERATIONS_ERROR; } if (ldb_kv->disallow_dn_filter && (ldb_attr_cmp(tree->u.comparison.attr, "dn") == 0)) { /* in AD mode we do not support "(dn=...)" search filters */ list->dn = NULL; list->count = 0; return LDB_SUCCESS; } if (tree->u.comparison.attr[0] == '@') { /* Do not allow a indexed search against an @ */ list->dn = NULL; list->count = 0; return LDB_SUCCESS; } a = ldb_schema_attribute_by_name(ldb, tree->u.comparison.attr); /* * If there's no index format function defined for this attr, then * the lexicographic order in the database doesn't correspond to the * attr's ordering, so we can't use the iterate_range op. */ if (a->syntax->index_format_fn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } key_dn = ldb_kv_index_key(ldb, ldb_kv, tree->u.comparison.attr, &tree->u.comparison.value, NULL, &truncation); if (!key_dn) { return LDB_ERR_OPERATIONS_ERROR; } else if (truncation == KEY_TRUNCATED) { ldb_debug(ldb, LDB_DEBUG_WARNING, __location__ ": ordered index violation: key dn truncated: %s\n", ldb_dn_get_linearized(key_dn)); return LDB_ERR_OPERATIONS_ERROR; } ldb_key = ldb_kv_key_dn(tmp_ctx, key_dn); talloc_free(key_dn); if (ldb_key.data == NULL) { return LDB_ERR_OPERATIONS_ERROR; } key_dn = ldb_kv_index_key(ldb, ldb_kv, tree->u.comparison.attr, NULL, NULL, &truncation); if (!key_dn) { return LDB_ERR_OPERATIONS_ERROR; } else if (truncation == KEY_TRUNCATED) { ldb_debug(ldb, LDB_DEBUG_WARNING, __location__ ": ordered index violation: key dn truncated: %s\n", ldb_dn_get_linearized(key_dn)); return LDB_ERR_OPERATIONS_ERROR; } ldb_key2 = ldb_kv_key_dn(tmp_ctx, key_dn); talloc_free(key_dn); if (ldb_key2.data == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* * In order to avoid defining a start and end key for the search, we * notice that each index key is of the form: * * DN=@INDEX::\0. * * We can simply make our start key DN=@INDEX:: and our end * key DN=@INDEX:; to return all index entries for a * particular attribute. * * Our LMDB backend uses the default memcmp for key comparison. */ /* Eliminate NUL byte at the end of the empty key */ ldb_key2.length--; if (ascending) { /* : becomes ; for pseudo end-key */ ldb_key2.data[ldb_key2.length-1]++; start_key = ldb_key; end_key = ldb_key2; } else { start_key = ldb_key2; end_key = ldb_key; } ctx.module = module; ctx.error = 0; ctx.dn_list = list; ctx.dn_list->count = 0; ctx.dn_list->dn = talloc_zero_array(ctx.dn_list, struct ldb_val, 2); ret = ldb_kv->kv_ops->iterate_range(ldb_kv, start_key, end_key, traverse_range_index, &ctx); if (ret != LDB_SUCCESS || ctx.error != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } TYPESAFE_QSORT(ctx.dn_list->dn, ctx.dn_list->count, ldb_val_equal_exact_for_qsort); talloc_free(tmp_ctx); return LDB_SUCCESS; } static int ldb_kv_index_dn_greater(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list) { return ldb_kv_index_dn_ordered(module, ldb_kv, tree, list, true); } static int ldb_kv_index_dn_less(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list) { return ldb_kv_index_dn_ordered(module, ldb_kv, tree, list, false); } /* return a list of matching objects using a one-level index */ static int ldb_kv_index_dn_attr(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const char *attr, struct ldb_dn *dn, struct dn_list *list, enum key_truncation *truncation) { struct ldb_context *ldb; struct ldb_dn *key; struct ldb_val val; int ret; ldb = ldb_module_get_ctx(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 = ldb_kv_index_key(ldb, ldb_kv, attr, &val, NULL, truncation); if (!key) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_dn_list_load(module, ldb_kv, key, list, DN_LIST_WILL_BE_READ_ONLY); talloc_free(key); if (ret != LDB_SUCCESS) { return ret; } if (list->count == 0) { return LDB_ERR_NO_SUCH_OBJECT; } return LDB_SUCCESS; } /* return a list of matching objects using a one-level index */ static int ldb_kv_index_dn_one(struct ldb_module *module, struct ldb_kv_private *ldb_kv, struct ldb_dn *parent_dn, struct dn_list *list, enum key_truncation *truncation) { /* * Ensure we do not shortcut on intersection for this list. * We must never be lazy and return an entry not in this * list. This allows the index for * SCOPE_ONELEVEL to be trusted. */ list->strict = true; return ldb_kv_index_dn_attr( module, ldb_kv, LDB_KV_IDXONE, parent_dn, list, truncation); } /* return a list of matching objects using the DN index */ static int ldb_kv_index_dn_base_dn(struct ldb_module *module, struct ldb_kv_private *ldb_kv, struct ldb_dn *base_dn, struct dn_list *dn_list, enum key_truncation *truncation) { const struct ldb_val *guid_val = NULL; if (ldb_kv->cache->GUID_index_attribute == NULL) { dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); if (dn_list->dn == NULL) { return ldb_module_oom(module); } dn_list->dn[0].data = discard_const_p(unsigned char, ldb_dn_get_linearized(base_dn)); if (dn_list->dn[0].data == NULL) { talloc_free(dn_list->dn); return ldb_module_oom(module); } dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data); dn_list->count = 1; return LDB_SUCCESS; } if (ldb_kv->cache->GUID_index_dn_component != NULL) { guid_val = ldb_dn_get_extended_component( base_dn, ldb_kv->cache->GUID_index_dn_component); } if (guid_val != NULL) { dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); if (dn_list->dn == NULL) { return ldb_module_oom(module); } dn_list->dn[0].data = guid_val->data; dn_list->dn[0].length = guid_val->length; dn_list->count = 1; return LDB_SUCCESS; } return ldb_kv_index_dn_attr( module, ldb_kv, LDB_KV_IDXDN, base_dn, dn_list, truncation); } /* return a list of dn's that might match a indexed search or an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches */ static int ldb_kv_index_dn(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_parse_tree *tree, struct dn_list *list) { int ret = LDB_ERR_OPERATIONS_ERROR; switch (tree->operation) { case LDB_OP_AND: ret = ldb_kv_index_dn_and(module, ldb_kv, tree, list); break; case LDB_OP_OR: ret = ldb_kv_index_dn_or(module, ldb_kv, tree, list); break; case LDB_OP_NOT: ret = ldb_kv_index_dn_not(module, ldb_kv, tree, list); break; case LDB_OP_EQUALITY: ret = ldb_kv_index_dn_leaf(module, ldb_kv, tree, list); break; case LDB_OP_GREATER: ret = ldb_kv_index_dn_greater(module, ldb_kv, tree, list); break; case LDB_OP_LESS: ret = ldb_kv_index_dn_less(module, ldb_kv, tree, list); break; case LDB_OP_SUBSTRING: case LDB_OP_PRESENT: case LDB_OP_APPROX: case LDB_OP_EXTENDED: /* we can't index with fancy bitops yet */ ret = LDB_ERR_OPERATIONS_ERROR; break; } return ret; } /* filter a candidate dn_list from an indexed search into a set of results extracting just the given attributes */ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, const struct dn_list *dn_list, struct ldb_kv_context *ac, uint32_t *match_count, enum key_truncation scope_one_truncation) { struct ldb_context *ldb = ldb_module_get_ctx(ac->module); struct ldb_message *msg; struct ldb_message *filtered_msg; unsigned int i; unsigned int num_keys = 0; uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {}; struct ldb_val *keys = NULL; /* * We have to allocate the key list (rather than just walk the * caller supplied list) as the callback could change the list * (by modifying an indexed attribute hosted in the in-memory * index cache!) */ keys = talloc_array(ac, struct ldb_val, dn_list->count); if (keys == NULL) { return ldb_module_oom(ac->module); } if (ldb_kv->cache->GUID_index_attribute != NULL) { /* * We speculate that the keys will be GUID based and so * pre-fill in enough space for a GUID (avoiding a pile of * small allocations) */ struct guid_tdb_key { uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; } *key_values = NULL; key_values = talloc_array(keys, 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].data = key_values[i].guid_key; keys[i].length = sizeof(key_values[i].guid_key); } } else { for (i = 0; i < dn_list->count; i++) { keys[i].data = NULL; keys[i].length = 0; } } for (i = 0; i < dn_list->count; i++) { int ret; ret = ldb_kv_idx_to_key( ac->module, ldb_kv, keys, &dn_list->dn[i], &keys[num_keys]); if (ret != LDB_SUCCESS) { talloc_free(keys); return ret; } if (ldb_kv->cache->GUID_index_attribute != NULL) { /* * If we are in GUID index mode, then the dn_list is * sorted. If we got a duplicate, forget about it, as * otherwise we would send the same entry back more * than once. * * This is needed in the truncated DN case, or if a * duplicate was forced in via * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK */ if (memcmp(previous_guid_key, keys[num_keys].data, sizeof(previous_guid_key)) == 0) { continue; } memcpy(previous_guid_key, keys[num_keys].data, sizeof(previous_guid_key)); } num_keys++; } /* * Now that the list is a safe copy, send the callbacks */ for (i = 0; i < num_keys; i++) { int ret; bool matched; msg = ldb_msg_new(ac); if (!msg) { talloc_free(keys); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_search_key(ac->module, ldb_kv, keys[i], msg, LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | /* * The entry point ldb_kv_search_indexed is * only called from the read-locked * ldb_kv_search. */ LDB_UNPACK_DATA_FLAG_READ_LOCKED); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* * the record has disappeared? yes, this can * happen if the entry is deleted by something * operating in the callback (not another * process, as we have a read lock) */ talloc_free(msg); continue; } 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 && ldb_kv->cache->one_level_indexes && scope_one_truncation == KEY_NOT_TRUNCATED) { ret = ldb_match_message(ldb, msg, ac->tree, ac->scope, &matched); } else { ret = ldb_match_msg_error(ldb, msg, ac->tree, ac->base, ac->scope, &matched); } if (ret != LDB_SUCCESS) { talloc_free(keys); talloc_free(msg); return ret; } if (!matched) { talloc_free(msg); continue; } filtered_msg = ldb_msg_new(ac); if (filtered_msg == NULL) { TALLOC_FREE(keys); TALLOC_FREE(msg); return LDB_ERR_OPERATIONS_ERROR; } filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); /* filter the attributes that the user wants */ ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); talloc_free(msg); if (ret == -1) { TALLOC_FREE(filtered_msg); talloc_free(keys); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); if (ret != LDB_SUCCESS) { /* Regardless of success or failure, the msg * is the callbacks responsiblity, and should * not be talloc_free()'ed */ ac->request_terminated = true; talloc_free(keys); return ret; } (*match_count)++; } TALLOC_FREE(keys); return LDB_SUCCESS; } /* sort a DN list */ static void ldb_kv_dn_list_sort(struct ldb_kv_private *ltdb, struct dn_list *list) { if (list->count < 2) { return; } /* We know the list is sorted when using the GUID index */ if (ltdb->cache->GUID_index_attribute != NULL) { return; } TYPESAFE_QSORT(list->dn, list->count, ldb_val_equal_exact_for_qsort); } /* search the database with a LDAP-like expression using indexes returns -1 if an indexed search is not possible, in which case the caller should call ltdb_search_full() */ int ldb_kv_search_indexed(struct ldb_kv_context *ac, uint32_t *match_count) { struct ldb_context *ldb = ldb_module_get_ctx(ac->module); struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(ac->module), struct ldb_kv_private); 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 (!ldb_kv->cache->attribute_indexes && !ldb_kv->cache->one_level_indexes && ac->scope != LDB_SCOPE_BASE) { /* fallback to a full search */ return LDB_ERR_OPERATIONS_ERROR; } dn_list = talloc_zero(ac, struct dn_list); if (dn_list == NULL) { return ldb_module_oom(ac->module); } /* * For the purposes of selecting the switch arm below, if we * don't have a one-level index then treat it like a subtree * search */ if (ac->scope == LDB_SCOPE_ONELEVEL && !ldb_kv->cache->one_level_indexes) { index_scope = LDB_SCOPE_SUBTREE; } else { index_scope = ac->scope; } switch (index_scope) { case LDB_SCOPE_BASE: /* * The only caller will have filtered the operation out * so we should never get here */ return ldb_operr(ldb); case LDB_SCOPE_ONELEVEL: /* * First, load all the one-level child objects (regardless of * whether they match the search filter or not). The database * maintains a one-level index, so retrieving this is quick. */ ret = ldb_kv_index_dn_one(ac->module, ldb_kv, ac->base, dn_list, &scope_one_truncation); if (ret != LDB_SUCCESS) { talloc_free(dn_list); return ret; } /* * If we have too many children, running ldb_kv_index_filter() * over all the child objects can be quite expensive. So next * we do a separate indexed query using the search filter. * * This should be quick, but it may return objects that are not * the direct one-level child objects we're interested in. * * We only do this in the GUID index mode, which is * O(n*log(m)) otherwise the intersection below will * be too costly at O(n*m). * * We don't set a heuristic for 'too many' but instead * do it always and rely on the index lookup being * fast enough in the small case. */ if (ldb_kv->cache->GUID_index_attribute != NULL) { struct dn_list *indexed_search_result = talloc_zero(ac, struct dn_list); if (indexed_search_result == NULL) { talloc_free(dn_list); return ldb_module_oom(ac->module); } if (!ldb_kv->cache->attribute_indexes) { talloc_free(indexed_search_result); talloc_free(dn_list); return LDB_ERR_OPERATIONS_ERROR; } /* * Try to do an indexed database search */ ret = ldb_kv_index_dn( ac->module, ldb_kv, ac->tree, indexed_search_result); /* * We can stop if we're sure the object doesn't exist */ if (ret == LDB_ERR_NO_SUCH_OBJECT) { talloc_free(indexed_search_result); talloc_free(dn_list); return LDB_ERR_NO_SUCH_OBJECT; } /* * Once we have a successful search result, we * intersect it with the one-level children (dn_list). * This should give us exactly the result we're after * (we still need to run ldb_kv_index_filter() to * handle potential index truncation cases). * * The indexed search may fail because we don't support * indexing on that type of search operation, e.g. * matching against '*'. In which case we fall through * and run ldb_kv_index_filter() over all the one-level * children (which is still better than bailing out here * and falling back to a full DB scan). */ if (ret == LDB_SUCCESS) { if (!list_intersect(ldb_kv, dn_list, indexed_search_result)) { talloc_free(indexed_search_result); talloc_free(dn_list); return LDB_ERR_OPERATIONS_ERROR; } } } break; case LDB_SCOPE_SUBTREE: case LDB_SCOPE_DEFAULT: if (!ldb_kv->cache->attribute_indexes) { talloc_free(dn_list); return LDB_ERR_OPERATIONS_ERROR; } /* * Here we load the index for the tree. We have no * index for the subtree. */ ret = ldb_kv_index_dn(ac->module, ldb_kv, ac->tree, dn_list); if (ret != LDB_SUCCESS) { talloc_free(dn_list); return ret; } 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 = ldb_kv_index_filter( ldb_kv, dn_list, ac, match_count, scope_one_truncation); talloc_free(dn_list); return ret; } /** * @brief Add a DN in the index list of a given attribute name/value pair * * This function will add the DN in the index list for the index for * the given attribute name and value. * * @param[in] module A ldb_module structure * * @param[in] dn The string representation of the DN as it * will be stored in the index entry * * @param[in] el A ldb_message_element array, one of the entry * referred by the v_idx is the attribute name and * value pair which will be used to construct the * index name * * @param[in] v_idx The index of element in the el array to use * * @return An ldb error code */ static int ldb_kv_index_add1(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el, int v_idx) { struct ldb_context *ldb; struct ldb_dn *dn_key; int ret; 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); list = talloc_zero(module, struct dn_list); if (list == NULL) { return LDB_ERR_OPERATIONS_ERROR; } dn_key = ldb_kv_index_key( ldb, ldb_kv, el->name, &el->values[v_idx], &a, &truncation); 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), ldb_kv->max_key_length); talloc_free(list); return LDB_ERR_CONSTRAINT_VIOLATION; } talloc_steal(list, dn_key); ret = ldb_kv_dn_list_load(module, ldb_kv, dn_key, list, DN_LIST_MUTABLE); if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { talloc_free(list); return ret; } /* * Check for duplicates in the @IDXDN DN -> GUID record * * This is very normal, it just means a duplicate DN creation * was attempted, so don't set the error string or print scary * messages. */ if (list->count > 0 && ldb_attr_cmp(el->name, LDB_KV_IDXDN) == 0 && truncation == KEY_NOT_TRUNCATED) { talloc_free(list); return LDB_ERR_CONSTRAINT_VIOLATION; } else if (list->count > 0 && ldb_attr_cmp(el->name, LDB_KV_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 */ unsigned int i; for (i=0; i < list->count; i++) { uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; struct ldb_val key = { .data = guid_key, .length = 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 = ldb_kv_idx_to_key( module, ldb_kv, ldb, &list->dn[i], &key); if (ret != LDB_SUCCESS) { TALLOC_FREE(list); TALLOC_FREE(rec); return ret; } ret = ldb_kv_search_key(module, ldb_kv, key, rec, flags); if (key.data != guid_key) { TALLOC_FREE(key.data); } 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 && (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX || (el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX))))) { /* * We do not want to print info about a possibly * confidential DN that the conflict was with in the * user-visible error string */ if (ldb_kv->cache->GUID_index_attribute == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, __location__ ": unique index violation on %s in %s, " "conflicts with %*.*s in %s", el->name, ldb_dn_get_linearized(msg->dn), (int)list->dn[0].length, (int)list->dn[0].length, list->dn[0].data, ldb_dn_get_linearized(dn_key)); } else { /* This can't fail, gives a default at worst */ const struct ldb_schema_attribute *attr = ldb_schema_attribute_by_name( ldb, ldb_kv->cache->GUID_index_attribute); struct ldb_val v; ret = attr->syntax->ldif_write_fn(ldb, list, &list->dn[0], &v); if (ret == LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_WARNING, __location__ ": unique index violation on %s in " "%s, conflicts with %s %*.*s in %s", el->name, ldb_dn_get_linearized(msg->dn), ldb_kv->cache->GUID_index_attribute, (int)v.length, (int)v.length, v.data, ldb_dn_get_linearized(dn_key)); } } ldb_asprintf_errstring(ldb, __location__ ": unique index violation " "on %s in %s", el->name, ldb_dn_get_linearized(msg->dn)); talloc_free(list); return LDB_ERR_CONSTRAINT_VIOLATION; } /* overallocate the list a bit, to reduce the number of * realloc trigered copies */ alloc_len = ((list->count+1)+7) & ~7; list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len); if (list->dn == NULL) { talloc_free(list); return LDB_ERR_OPERATIONS_ERROR; } if (ldb_kv->cache->GUID_index_attribute == NULL) { const char *dn_str = ldb_dn_get_linearized(msg->dn); list->dn[list->count].data = (uint8_t *)talloc_strdup(list->dn, dn_str); if (list->dn[list->count].data == NULL) { talloc_free(list); return LDB_ERR_OPERATIONS_ERROR; } list->dn[list->count].length = strlen(dn_str); } else { const struct ldb_val *key_val; struct ldb_val *exact = NULL, *next = NULL; key_val = ldb_msg_find_ldb_val( msg, ldb_kv->cache->GUID_index_attribute); if (key_val == NULL) { talloc_free(list); return ldb_module_operr(module); } if (key_val->length != LDB_KV_GUID_SIZE) { talloc_free(list); return ldb_module_operr(module); } BINARY_ARRAY_SEARCH_GTE(list->dn, list->count, *key_val, ldb_val_equal_exact_ordered, exact, next); /* * Give a warning rather than fail, this could be a * duplicate value in the record allowed by a caller * forcing in the value with * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK */ if (exact != NULL && truncation == KEY_NOT_TRUNCATED) { /* This can't fail, gives a default at worst */ const struct ldb_schema_attribute *attr = ldb_schema_attribute_by_name( ldb, ldb_kv->cache->GUID_index_attribute); struct ldb_val v; ret = attr->syntax->ldif_write_fn(ldb, list, exact, &v); if (ret == LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_WARNING, __location__ ": duplicate attribute value in %s " "for index on %s, " "duplicate of %s %*.*s in %s", ldb_dn_get_linearized(msg->dn), el->name, ldb_kv->cache->GUID_index_attribute, (int)v.length, (int)v.length, v.data, ldb_dn_get_linearized(dn_key)); } } if (next == NULL) { next = &list->dn[list->count]; } else { memmove(&next[1], next, sizeof(*next) * (list->count - (next - list->dn))); } *next = ldb_val_dup(list->dn, key_val); if (next->data == NULL) { talloc_free(list); return ldb_module_operr(module); } } list->count++; ret = ldb_kv_dn_list_store(module, dn_key, list); talloc_free(list); return ret; } /* add index entries for one elements in a message */ static int ldb_kv_index_add_el(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el) { unsigned int i; for (i = 0; i < el->num_values; i++) { int ret = ldb_kv_index_add1(module, ldb_kv, msg, el, i); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } /* add index entries for all elements in a message */ static int ldb_kv_index_add_all(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg) { struct ldb_message_element *elements = msg->elements; unsigned int i; const char *dn_str; int ret; if (ldb_dn_is_special(msg->dn)) { return LDB_SUCCESS; } dn_str = ldb_dn_get_linearized(msg->dn); if (dn_str == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_write_index_dn_guid(module, msg, 1); if (ret != LDB_SUCCESS) { return ret; } if (!ldb_kv->cache->attribute_indexes) { /* no indexed fields */ return LDB_SUCCESS; } for (i = 0; i < msg->num_elements; i++) { if (!ldb_kv_is_indexed(module, ldb_kv, elements[i].name)) { continue; } ret = ldb_kv_index_add_el(module, ldb_kv, msg, &elements[i]); if (ret != LDB_SUCCESS) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, __location__ ": Failed to re-index %s in %s - %s", elements[i].name, dn_str, ldb_errstring(ldb)); return ret; } } return LDB_SUCCESS; } /* insert a DN index for a message */ static int ldb_kv_modify_index_dn(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_dn *dn, const char *index, int add) { struct ldb_message_element el; struct ldb_val val; int ret; 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 modify %s " "against %s in %s: failed " "to get casefold DN", index, ldb_kv->cache->GUID_index_attribute, dn_str); return LDB_ERR_OPERATIONS_ERROR; } val.length = strlen((char *)val.data); el.name = index; el.values = &val; el.num_values = 1; if (add) { ret = ldb_kv_index_add1(module, ldb_kv, msg, &el, 0); } else { /* delete */ ret = ldb_kv_index_del_value(module, ldb_kv, msg, &el, 0); } if (ret != LDB_SUCCESS) { struct ldb_context *ldb = ldb_module_get_ctx(module); const char *dn_str = ldb_dn_get_linearized(dn); ldb_asprintf_errstring(ldb, __location__ ": Failed to modify %s " "against %s in %s - %s", index, ldb_kv->cache->GUID_index_attribute, dn_str, ldb_errstring(ldb)); return ret; } return ret; } /* insert a one level index for a message */ static int ldb_kv_index_onelevel(struct ldb_module *module, const struct ldb_message *msg, int add) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); struct ldb_dn *pdn; int ret; /* We index for ONE Level only if requested */ if (!ldb_kv->cache->one_level_indexes) { return LDB_SUCCESS; } pdn = ldb_dn_get_parent(module, msg->dn); if (pdn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_modify_index_dn(module, ldb_kv, msg, pdn, LDB_KV_IDXONE, add); talloc_free(pdn); return ret; } /* insert a one level index for a message */ static int ldb_kv_write_index_dn_guid(struct ldb_module *module, const struct ldb_message *msg, int add) { int ret; struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); /* We index for DN only if using a GUID index */ if (ldb_kv->cache->GUID_index_attribute == NULL) { return LDB_SUCCESS; } ret = ldb_kv_modify_index_dn( module, ldb_kv, msg, msg->dn, LDB_KV_IDXDN, add); if (ret == LDB_ERR_CONSTRAINT_VIOLATION) { ldb_asprintf_errstring(ldb_module_get_ctx(module), "Entry %s already exists", ldb_dn_get_linearized(msg->dn)); ret = LDB_ERR_ENTRY_ALREADY_EXISTS; } return ret; } /* add the index entries for a new element in a record The caller guarantees that these element values are not yet indexed */ int ldb_kv_index_add_element(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el) { if (ldb_dn_is_special(msg->dn)) { return LDB_SUCCESS; } if (!ldb_kv_is_indexed(module, ldb_kv, el->name)) { return LDB_SUCCESS; } return ldb_kv_index_add_el(module, ldb_kv, msg, el); } /* add the index entries for a new record */ int ldb_kv_index_add_new(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg) { int ret; if (ldb_dn_is_special(msg->dn)) { return LDB_SUCCESS; } ret = ldb_kv_index_add_all(module, ldb_kv, msg); if (ret != LDB_SUCCESS) { /* * Because we can't trust the caller to be doing * transactions properly, clean up any index for this * entry rather than relying on a transaction * cleanup */ ldb_kv_index_delete(module, msg); return ret; } ret = ldb_kv_index_onelevel(module, msg, 1); if (ret != LDB_SUCCESS) { /* * Because we can't trust the caller to be doing * transactions properly, clean up any index for this * entry rather than relying on a transaction * cleanup */ ldb_kv_index_delete(module, msg); return ret; } return ret; } /* delete an index entry for one message element */ int ldb_kv_index_del_value(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el, unsigned int v_idx) { struct ldb_context *ldb; struct ldb_dn *dn_key; const char *dn_str; int ret, i; 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); dn_str = ldb_dn_get_linearized(dn); if (dn_str == NULL) { return LDB_ERR_OPERATIONS_ERROR; } if (dn_str[0] == '@') { return LDB_SUCCESS; } dn_key = ldb_kv_index_key( ldb, ldb_kv, 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 */ if (!dn_key) { return LDB_ERR_OPERATIONS_ERROR; } list = talloc_zero(dn_key, struct dn_list); if (list == NULL) { talloc_free(dn_key); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_dn_list_load(module, ldb_kv, dn_key, list, DN_LIST_MUTABLE); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* it wasn't indexed. Did we have an earlier error? If we did then its gone now */ talloc_free(dn_key); return LDB_SUCCESS; } if (ret != LDB_SUCCESS) { talloc_free(dn_key); return ret; } /* * Find one of the values matching this message to remove */ i = ldb_kv_dn_list_find_msg(ldb_kv, list, msg); if (i == -1) { /* nothing to delete */ talloc_free(dn_key); return LDB_SUCCESS; } j = (unsigned int) i; if (j != list->count - 1) { memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1))); } list->count--; if (list->count == 0) { talloc_free(list->dn); list->dn = NULL; } else { list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count); } ret = ldb_kv_dn_list_store(module, dn_key, list); talloc_free(dn_key); return ret; } /* delete the index entries for a element return -1 on failure */ int ldb_kv_index_del_element(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_message *msg, struct ldb_message_element *el) { const char *dn_str; int ret; unsigned int i; if (!ldb_kv->cache->attribute_indexes) { /* no indexed fields */ return LDB_SUCCESS; } dn_str = ldb_dn_get_linearized(msg->dn); if (dn_str == NULL) { return LDB_ERR_OPERATIONS_ERROR; } if (dn_str[0] == '@') { return LDB_SUCCESS; } if (!ldb_kv_is_indexed(module, ldb_kv, el->name)) { return LDB_SUCCESS; } for (i = 0; i < el->num_values; i++) { ret = ldb_kv_index_del_value(module, ldb_kv, msg, el, i); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } /* delete the index entries for a record return -1 on failure */ int ldb_kv_index_delete(struct ldb_module *module, const struct ldb_message *msg) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); int ret; unsigned int i; if (ldb_dn_is_special(msg->dn)) { return LDB_SUCCESS; } ret = ldb_kv_index_onelevel(module, msg, 0); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_kv_write_index_dn_guid(module, msg, 0); if (ret != LDB_SUCCESS) { return ret; } if (!ldb_kv->cache->attribute_indexes) { /* no indexed fields */ return LDB_SUCCESS; } for (i = 0; i < msg->num_elements; i++) { ret = ldb_kv_index_del_element( module, ldb_kv, msg, &msg->elements[i]); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } /* traversal function that deletes all @INDEX records in the in-memory TDB. This does not touch the actual DB, that is done at transaction 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 ldb_kv_private *ldb_kv, struct ldb_val key, _UNUSED_ struct ldb_val data, void *state) { struct ldb_module *module = state; const char *dnstr = "DN=" LDB_KV_INDEX ":"; struct dn_list list; struct ldb_dn *dn; struct ldb_val v; int ret; if (strncmp((char *)key.data, dnstr, strlen(dnstr)) != 0) { return 0; } /* we need to put a empty list in the internal tdb for this * index entry */ list.dn = NULL; 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; dn = ldb_dn_from_ldb_val(ldb_kv, ldb_module_get_ctx(module), &v); /* * This does not actually touch the DB quite yet, just * the in-memory index cache */ ret = ldb_kv_dn_list_store(module, dn, &list); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb_module_get_ctx(module), "Unable to store null index for %s\n", ldb_dn_get_linearized(dn)); talloc_free(dn); return -1; } talloc_free(dn); return 0; } /* traversal function that adds @INDEX records during a re index TODO wrong comment */ static int re_key(struct ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val val, void *state) { struct ldb_context *ldb; struct ldb_kv_reindex_context *ctx = (struct ldb_kv_reindex_context *)state; struct ldb_module *module = ldb_kv->module; struct ldb_message *msg; int ret; struct ldb_val key2; bool is_record; ldb = ldb_module_get_ctx(module); is_record = ldb_kv_key_is_normal_record(key); if (is_record == false) { return 0; } msg = ldb_msg_new(module); if (msg == NULL) { return -1; } ret = ldb_unpack_data(ldb, &val, msg); if (ret != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", ldb_dn_get_linearized(msg->dn)); ctx->error = ret; talloc_free(msg); return -1; } if (msg->dn == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Refusing to re-index as GUID " "key %*.*s with no DN\n", (int)key.length, (int)key.length, (char *)key.data); talloc_free(msg); return -1; } /* check if the DN key has changed, perhaps due to the case insensitivity of an element changing, or a change from DN to GUID keys */ key2 = ldb_kv_key_msg(module, msg, msg); if (key2.data == NULL) { /* probably a corrupt record ... darn */ ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s", ldb_dn_get_linearized(msg->dn)); talloc_free(msg); return 0; } if (key.length != key2.length || (memcmp(key.data, key2.data, key.length) != 0)) { ldb_kv->kv_ops->update_in_iterate( ldb_kv, key, key2, val, ctx); } talloc_free(key2.data); talloc_free(msg); ctx->count++; if (ctx->count % 10000 == 0) { ldb_debug(ldb, LDB_DEBUG_WARNING, "Reindexing: re-keyed %u records so far", ctx->count); } return 0; } /* traversal function that adds @INDEX records during a re index */ static int re_index(struct ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val val, void *state) { struct ldb_context *ldb; struct ldb_kv_reindex_context *ctx = (struct ldb_kv_reindex_context *)state; struct ldb_module *module = ldb_kv->module; struct ldb_message *msg; int ret; bool is_record; ldb = ldb_module_get_ctx(module); is_record = ldb_kv_key_is_normal_record(key); if (is_record == false) { return 0; } msg = ldb_msg_new(module); if (msg == NULL) { return -1; } ret = ldb_unpack_data(ldb, &val, msg); if (ret != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", ldb_dn_get_linearized(msg->dn)); ctx->error = ret; talloc_free(msg); return -1; } if (msg->dn == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Refusing to re-index as GUID " "key %*.*s with no DN\n", (int)key.length, (int)key.length, (char *)key.data); talloc_free(msg); return -1; } ret = ldb_kv_index_onelevel(module, msg, 1); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Adding special ONE LEVEL index failed (%s)!", ldb_dn_get_linearized(msg->dn)); talloc_free(msg); return -1; } ret = ldb_kv_index_add_all(module, ldb_kv, msg); if (ret != LDB_SUCCESS) { ctx->error = ret; talloc_free(msg); return -1; } talloc_free(msg); ctx->count++; if (ctx->count % 10000 == 0) { ldb_debug(ldb, LDB_DEBUG_WARNING, "Reindexing: re-indexed %u records so far", ctx->count); } return 0; } /* * Convert the 4-byte pack format version to a number that's slightly * more intelligible to a user e.g. version 0, 1, 2, etc. */ static uint32_t displayable_pack_version(uint32_t version) { if (version < LDB_PACKING_FORMAT_NODN) { return version; /* unknown - can't convert */ } return (version - LDB_PACKING_FORMAT_NODN); } static int re_pack(struct ldb_kv_private *ldb_kv, _UNUSED_ struct ldb_val key, struct ldb_val val, void *state) { struct ldb_context *ldb; struct ldb_message *msg; struct ldb_module *module = ldb_kv->module; struct ldb_kv_repack_context *ctx = (struct ldb_kv_repack_context *)state; int ret; ldb = ldb_module_get_ctx(module); msg = ldb_msg_new(module); if (msg == NULL) { return -1; } ret = ldb_unpack_data(ldb, &val, msg); if (ret != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack: unpack failed: %s\n", ldb_dn_get_linearized(msg->dn)); ctx->error = ret; talloc_free(msg); return -1; } ret = ldb_kv_store(module, msg, TDB_MODIFY); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack: store failed: %s\n", ldb_dn_get_linearized(msg->dn)); ctx->error = ret; talloc_free(msg); return -1; } /* * Warn the user that we're repacking the first time we see a normal * record. This means we never warn if we're repacking a database with * only @ records. This is because during database initialisation, * we might repack as initial settings are written out, and we don't * want to spam the log. */ if ((!ctx->normal_record_seen) && (!ldb_dn_is_special(msg->dn))) { ldb_debug(ldb, LDB_DEBUG_ALWAYS_LOG, "Repacking database from v%u to v%u format " "(first record %s)", displayable_pack_version(ctx->old_version), displayable_pack_version(ldb_kv->pack_format_version), ldb_dn_get_linearized(msg->dn)); ctx->normal_record_seen = true; } ctx->count++; if (ctx->count % 10000 == 0) { ldb_debug(ldb, LDB_DEBUG_WARNING, "Repack: re-packed %u records so far", ctx->count); } talloc_free(msg); return 0; } int ldb_kv_repack(struct ldb_module *module) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_kv_repack_context ctx; int ret; ctx.old_version = ldb_kv->pack_format_version; ctx.count = 0; ctx.error = LDB_SUCCESS; ctx.normal_record_seen = false; ldb_kv->pack_format_version = ldb_kv->target_pack_format_version; /* Iterate all database records and repack them in the new format */ ret = ldb_kv->kv_ops->iterate(ldb_kv, re_pack, &ctx); if (ret < 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack traverse failed: %s", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } if (ctx.error != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack failed: %s", ldb_errstring(ldb)); return ctx.error; } return LDB_SUCCESS; } /* force a complete reindex of the database */ int ldb_kv_reindex(struct ldb_module *module) { struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); int ret; struct ldb_kv_reindex_context ctx; size_t index_cache_size = 0; /* * Only triggered after a modification, but make clear we do * not re-index a read-only DB */ if (ldb_kv->read_only) { return LDB_ERR_UNWILLING_TO_PERFORM; } if (ldb_kv_cache_reload(module) != 0) { return LDB_ERR_OPERATIONS_ERROR; } /* * Ensure we read (and so remove) the entries from the real * DB, no values stored so far are any use as we want to do a * re-index */ ldb_kv_index_transaction_cancel(module); if (ldb_kv->nested_idx_ptr != NULL) { ldb_kv_index_sub_transaction_cancel(ldb_kv); } /* * Calculate the size of the index cache needed for * the re-index. If specified always use the * ldb_kv->index_transaction_cache_size otherwise use the maximum * of the size estimate or the DEFAULT_INDEX_CACHE_SIZE */ if (ldb_kv->index_transaction_cache_size > 0) { index_cache_size = ldb_kv->index_transaction_cache_size; } else { index_cache_size = ldb_kv->kv_ops->get_size(ldb_kv); if (index_cache_size < DEFAULT_INDEX_CACHE_SIZE) { index_cache_size = DEFAULT_INDEX_CACHE_SIZE; } } /* * Note that we don't start an index sub transaction for re-indexing */ ret = ldb_kv_index_transaction_start(module, index_cache_size); if (ret != LDB_SUCCESS) { return ret; } /* first traverse the database deleting any @INDEX records by * putting NULL entries in the in-memory tdb */ ret = ldb_kv->kv_ops->iterate(ldb_kv, delete_index, module); if (ret < 0) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, "index deletion traverse failed: %s", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } ctx.error = 0; ctx.count = 0; ret = ldb_kv->kv_ops->iterate(ldb_kv, re_key, &ctx); if (ret < 0) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, "key correction traverse failed: %s", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } if (ctx.error != LDB_SUCCESS) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); return ctx.error; } ctx.error = 0; ctx.count = 0; /* now traverse adding any indexes for normal LDB records */ ret = ldb_kv->kv_ops->iterate(ldb_kv, re_index, &ctx); if (ret < 0) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } if (ctx.error != LDB_SUCCESS) { struct ldb_context *ldb = ldb_module_get_ctx(module); ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); return ctx.error; } if (ctx.count > 10000) { 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", ldb_kv->kv_ops->name(ldb_kv)); } return LDB_SUCCESS; } /* * Copy the contents of the nested transaction index cache record to the * transaction index cache. * * During this 'commit' of the subtransaction to the main transaction * (cache), care must be taken to free any existing index at the top * level because otherwise we would leak memory. */ static int ldb_kv_sub_transaction_traverse( struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { struct ldb_module *module = state; struct ldb_kv_private *ldb_kv = talloc_get_type( ldb_module_get_private(module), struct ldb_kv_private); TDB_DATA rec = {0}; struct dn_list *index_in_subtransaction = NULL; struct dn_list *index_in_top_level = NULL; int ret = 0; /* * This unwraps the pointer in the DB into a pointer in * memory, we are abusing TDB as a hash map, not a linearised * database store */ index_in_subtransaction = ldb_kv_index_idxptr(module, data); if (index_in_subtransaction == NULL) { ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; return -1; } /* * Do we already have an entry in the primary transaction cache * If so free it's dn_list and replace it with the dn_list from * the secondary cache * * The TDB and so the fetched rec contains NO DATA, just a * pointer to data held in memory. */ rec = tdb_fetch(ldb_kv->idxptr->itdb, key); if (rec.dptr != NULL) { index_in_top_level = ldb_kv_index_idxptr(module, rec); free(rec.dptr); if (index_in_top_level == NULL) { abort(); } /* * We had this key at the top level. However we made a copy * at the sub-transaction level so that we could possibly * roll back. We have to free the top level index memory * otherwise we would leak */ if (index_in_top_level->count > 0) { TALLOC_FREE(index_in_top_level->dn); } index_in_top_level->dn = talloc_steal(index_in_top_level, index_in_subtransaction->dn); index_in_top_level->count = index_in_subtransaction->count; return 0; } index_in_top_level = talloc(ldb_kv->idxptr, struct dn_list); if (index_in_top_level == NULL) { ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; return -1; } index_in_top_level->dn = talloc_steal(index_in_top_level, index_in_subtransaction->dn); index_in_top_level->count = index_in_subtransaction->count; rec.dptr = (uint8_t *)&index_in_top_level; rec.dsize = sizeof(void *); /* * This is not a store into the main DB, but into an in-memory * TDB, so we don't need a guard on ltdb->read_only */ ret = tdb_store(ldb_kv->idxptr->itdb, key, rec, TDB_INSERT); if (ret != 0) { ldb_kv->idxptr->error = ltdb_err_map( tdb_error(ldb_kv->idxptr->itdb)); return -1; } return 0; } /* * Initialise the index cache for a sub transaction. */ int ldb_kv_index_sub_transaction_start(struct ldb_kv_private *ldb_kv) { ldb_kv->nested_idx_ptr = talloc_zero(ldb_kv, struct ldb_kv_idxptr); if (ldb_kv->nested_idx_ptr == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* * We use a tiny hash size for the sub-database (11). * * The sub-transaction is only for one record at a time, we * would use a linked list but that would make the code even * more complex when manipulating the index, as it would have * to know if we were in a nested transaction (normal * operations) or the top one (a reindex). */ ldb_kv->nested_idx_ptr->itdb = tdb_open(NULL, 11, TDB_INTERNAL, O_RDWR, 0); if (ldb_kv->nested_idx_ptr->itdb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } /* * Clear the contents of the nested transaction index cache when the nested * transaction is cancelled. */ int ldb_kv_index_sub_transaction_cancel(struct ldb_kv_private *ldb_kv) { if (ldb_kv->nested_idx_ptr != NULL) { tdb_close(ldb_kv->nested_idx_ptr->itdb); TALLOC_FREE(ldb_kv->nested_idx_ptr); } return LDB_SUCCESS; } /* * Commit a nested transaction, * Copy the contents of the nested transaction index cache to the * transaction index cache. */ int ldb_kv_index_sub_transaction_commit(struct ldb_kv_private *ldb_kv) { int ret = 0; if (ldb_kv->nested_idx_ptr == NULL) { return LDB_SUCCESS; } if (ldb_kv->nested_idx_ptr->itdb == NULL) { return LDB_SUCCESS; } tdb_traverse( ldb_kv->nested_idx_ptr->itdb, ldb_kv_sub_transaction_traverse, ldb_kv->module); tdb_close(ldb_kv->nested_idx_ptr->itdb); ldb_kv->nested_idx_ptr->itdb = NULL; ret = ldb_kv->nested_idx_ptr->error; if (ret != LDB_SUCCESS) { struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); if (!ldb_errstring(ldb)) { ldb_set_errstring(ldb, ldb_strerror(ret)); } ldb_asprintf_errstring( ldb, __location__": Failed to update index records in " "sub transaction commit: %s", ldb_errstring(ldb)); } TALLOC_FREE(ldb_kv->nested_idx_ptr); return ret; } ldb-2.0.8/ldb_key_value/ldb_kv_search.c0000660000000000000000000004316713573675413020006 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldb search functions * * Description: functions to search ldb+tdb databases * * Author: Andrew Tridgell */ #include "ldb_kv.h" #include "ldb_private.h" #include "lib/util/attr.h" /* search the database for a single simple dn. return LDB_ERR_NO_SUCH_OBJECT on record-not-found and LDB_SUCCESS on success */ int ldb_kv_search_base(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct ldb_dn **ret_dn) { int exists; int ret; struct ldb_message *msg = NULL; if (ldb_dn_is_null(dn)) { return LDB_ERR_NO_SUCH_OBJECT; } /* * We can't use tdb_exists() directly on a key when the TDB * key is the GUID one, not the DN based one. So we just do a * normal search and avoid most of the allocation with the * LDB_UNPACK_DATA_FLAG_NO_ATTRS flag */ msg = ldb_msg_new(module); if (msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_search_dn1(module, dn, msg, LDB_UNPACK_DATA_FLAG_NO_ATTRS); if (ret == LDB_SUCCESS) { const char *dn_linearized = ldb_dn_get_linearized(dn); const char *msg_dn_linearized = ldb_dn_get_linearized(msg->dn); if (strcmp(dn_linearized, msg_dn_linearized) == 0) { /* * Re-use the full incoming DN for * subtree checks */ *ret_dn = dn; } else { /* * Use the string DN from the unpack, so that * we have a case-exact match of the base */ *ret_dn = talloc_steal(mem_ctx, msg->dn); } exists = true; } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { exists = false; } else { talloc_free(msg); return ret; } talloc_free(msg); if (exists) { return LDB_SUCCESS; } return LDB_ERR_NO_SUCH_OBJECT; } struct ldb_kv_parse_data_unpack_ctx { struct ldb_message *msg; struct ldb_module *module; struct ldb_kv_private *ldb_kv; unsigned int unpack_flags; }; static int ldb_kv_parse_data_unpack(struct ldb_val key, struct ldb_val data, void *private_data) { struct ldb_kv_parse_data_unpack_ctx *ctx = private_data; int ret; struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); struct ldb_val data_parse = data; struct ldb_kv_private *ldb_kv = ctx->ldb_kv; if ((ldb_kv->kv_ops->options & LDB_KV_OPTION_STABLE_READ_LOCK) && (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_READ_LOCKED) && !ldb_kv->kv_ops->transaction_active(ldb_kv)) { /* * In the case where no transactions are active and * we're in a read-lock, we can point directly into * database memory. * * The database can't be changed underneath us and we * will duplicate this data in the call to filter. * * This is seen in: * - ldb_kv_index_filter * - ldb_kv_search_and_return_base */ } else { /* * In every other case, since unpack doesn't memdup, we need * to at least do a memdup on the whole data buffer as that * may change later and the caller needs a stable result. * * During transactions, pointers could change and in * TDB, there just aren't the same guarantees. */ data_parse.data = talloc_memdup(ctx->msg, data.data, data.length); 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); return LDB_ERR_OPERATIONS_ERROR; } } ret = ldb_unpack_data_flags(ldb, &data_parse, ctx->msg, ctx->unpack_flags); if (ret == -1) { if (data_parse.data != data.data) { 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; } return ret; } /* search the database for a single simple dn, returning all attributes in a single message return LDB_ERR_NO_SUCH_OBJECT on record-not-found and LDB_SUCCESS on success */ int ldb_kv_search_key(struct ldb_module *module, struct ldb_kv_private *ldb_kv, const struct ldb_val ldb_key, struct ldb_message *msg, unsigned int unpack_flags) { int ret; struct ldb_kv_parse_data_unpack_ctx ctx = { .msg = msg, .module = module, .unpack_flags = unpack_flags, .ldb_kv = ldb_kv }; memset(msg, 0, sizeof(*msg)); msg->num_elements = 0; msg->elements = NULL; ret = ldb_kv->kv_ops->fetch_and_parse( ldb_kv, ldb_key, ldb_kv_parse_data_unpack, &ctx); if (ret == -1) { ret = ldb_kv->kv_ops->error(ldb_kv); if (ret == LDB_SUCCESS) { /* * Just to be sure we don't turn errors * into success */ return LDB_ERR_OPERATIONS_ERROR; } return ret; } else if (ret != LDB_SUCCESS) { return ret; } return LDB_SUCCESS; } /* search the database for a single simple dn, returning all attributes in a single message return LDB_ERR_NO_SUCH_OBJECT on record-not-found and LDB_SUCCESS on success */ int ldb_kv_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg, unsigned int unpack_flags) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int ret; uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; struct ldb_val key = { .data = guid_key, .length = sizeof(guid_key) }; TALLOC_CTX *tdb_key_ctx = NULL; 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 (ldb_kv->cache->GUID_index_attribute == NULL || ldb_dn_is_special(dn)) { tdb_key_ctx = talloc_new(msg); if (!tdb_key_ctx) { return ldb_module_oom(module); } /* form the key */ key = ldb_kv_key_dn(tdb_key_ctx, dn); if (!key.data) { TALLOC_FREE(tdb_key_ctx); return LDB_ERR_OPERATIONS_ERROR; } } else { /* * Look in the index to find the key for this DN. * * the tdb_key memory is allocated above, msg is just * used for internal memory. * */ ret = ldb_kv_key_dn_from_idx(module, ldb_kv, msg, dn, &key); if (ret != LDB_SUCCESS) { return ret; } } ret = ldb_kv_search_key(module, ldb_kv, key, msg, unpack_flags); TALLOC_FREE(tdb_key_ctx); if (ret != LDB_SUCCESS) { return ret; } if ((unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DN) == 0) { if (!msg->dn) { msg->dn = ldb_dn_copy(msg, dn); } if (!msg->dn) { return LDB_ERR_OPERATIONS_ERROR; } } return LDB_SUCCESS; } /* * filter the specified list of attributes from msg, * adding requested attributes, and perhaps all for *, * but not the DN to filtered_msg. */ int ldb_kv_filter_attrs(struct ldb_context *ldb, const struct ldb_message *msg, const char *const *attrs, struct ldb_message *filtered_msg) { return ldb_filter_attrs(ldb, msg, attrs, filtered_msg); } /* search function for a non-indexed search */ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val val, void *state) { struct ldb_context *ldb; struct ldb_kv_context *ac; struct ldb_message *msg, *filtered_msg; int ret; bool matched; ac = talloc_get_type(state, struct ldb_kv_context); ldb = ldb_module_get_ctx(ac->module); /* * We want to skip @ records early in a search full scan * * @ records like @IDXLIST are only available via a base * search on the specific name but the method by which they * were excluded was expensive, after the unpack the DN is * exploded and ldb_match_msg_error() would reject it for * failing to match the scope. * * ldb_kv_key_is_normal_record() uses the fact that @ records * have the DN=@ prefix on their TDB/LMDB key to quickly * exclude them from consideration. * * (any other non-records are also excluded by the same key * match) */ if (ldb_kv_key_is_normal_record(key) == false) { return 0; } msg = ldb_msg_new(ac); if (!msg) { ac->error = LDB_ERR_OPERATIONS_ERROR; return -1; } /* unpack the record */ ret = ldb_unpack_data_flags(ldb, &val, msg, LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC); if (ret == -1) { talloc_free(msg); ac->error = LDB_ERR_OPERATIONS_ERROR; return -1; } if (!msg->dn) { msg->dn = ldb_dn_new(msg, ldb, (char *)key.data + 3); if (msg->dn == NULL) { talloc_free(msg); ac->error = LDB_ERR_OPERATIONS_ERROR; return -1; } } /* see if it matches the given expression */ ret = ldb_match_msg_error(ldb, msg, ac->tree, ac->base, ac->scope, &matched); if (ret != LDB_SUCCESS) { talloc_free(msg); ac->error = LDB_ERR_OPERATIONS_ERROR; return -1; } if (!matched) { talloc_free(msg); return 0; } filtered_msg = ldb_msg_new(ac); if (filtered_msg == NULL) { TALLOC_FREE(msg); return LDB_ERR_OPERATIONS_ERROR; } filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); /* filter the attributes that the user wants */ ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); talloc_free(msg); if (ret == -1) { TALLOC_FREE(filtered_msg); ac->error = LDB_ERR_OPERATIONS_ERROR; return -1; } ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); if (ret != LDB_SUCCESS) { ac->request_terminated = true; /* the callback failed, abort the operation */ ac->error = LDB_ERR_OPERATIONS_ERROR; return -1; } return 0; } /* search the database with a LDAP-like expression. this is the "full search" non-indexed variant */ static int ldb_kv_search_full(struct ldb_kv_context *ctx) { void *data = ldb_module_get_private(ctx->module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int ret; ctx->error = LDB_SUCCESS; ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx); if (ret < 0) { return LDB_ERR_OPERATIONS_ERROR; } return ctx->error; } static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, struct ldb_kv_context *ctx) { struct ldb_message *msg, *filtered_msg; struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); const char *dn_linearized; const char *msg_dn_linearized; int ret; bool matched; msg = ldb_msg_new(ctx); if (!msg) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_kv_search_dn1(ctx->module, ctx->base, msg, LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | LDB_UNPACK_DATA_FLAG_READ_LOCKED); if (ret == LDB_ERR_NO_SUCH_OBJECT) { if (ldb_kv->check_base == false) { /* * In this case, we are done, as no base * checking is allowed in this DB */ talloc_free(msg); return LDB_SUCCESS; } ldb_asprintf_errstring(ldb, "No such Base DN: %s", ldb_dn_get_linearized(ctx->base)); } if (ret != LDB_SUCCESS) { talloc_free(msg); return ret; } /* * We use this, not ldb_match_msg_error() as we know * we matched on the scope BASE, as we just fetched * the base DN */ ret = ldb_match_message(ldb, msg, ctx->tree, ctx->scope, &matched); if (ret != LDB_SUCCESS) { talloc_free(msg); return ret; } if (!matched) { talloc_free(msg); return LDB_SUCCESS; } dn_linearized = ldb_dn_get_linearized(ctx->base); msg_dn_linearized = ldb_dn_get_linearized(msg->dn); filtered_msg = ldb_msg_new(ctx); if (filtered_msg == NULL) { talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } if (strcmp(dn_linearized, msg_dn_linearized) == 0) { /* * If the DN is exactly the same string, then * re-use the full incoming DN for the * returned result, as it has already been * casefolded */ filtered_msg->dn = ldb_dn_copy(filtered_msg, ctx->base); } /* * If the ldb_dn_copy() failed, or if we did not choose that * optimisation (filtered_msg is zeroed at allocation), * steal the one from the unpack */ if (filtered_msg->dn == NULL) { filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); } /* * filter the attributes that the user wants. */ ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg); if (ret == -1) { talloc_free(msg); filtered_msg = NULL; return LDB_ERR_OPERATIONS_ERROR; } /* * Remove any extended components possibly copied in from * msg->dn, we just want the casefold components */ ldb_dn_remove_extended_components(filtered_msg->dn); talloc_free(msg); ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL); if (ret != LDB_SUCCESS) { /* Regardless of success or failure, the msg * is the callbacks responsiblity, and should * not be talloc_free()'ed */ ctx->request_terminated = true; return ret; } return LDB_SUCCESS; } /* search the database with a LDAP-like expression. choses a search method */ int ldb_kv_search(struct ldb_kv_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 ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int ret; ldb = ldb_module_get_ctx(module); ldb_request_set_state(req, LDB_ASYNC_PENDING); if (ldb_kv->kv_ops->lock_read(module) != 0) { return LDB_ERR_OPERATIONS_ERROR; } if (ldb_kv_cache_load(module) != 0) { ldb_kv->kv_ops->unlock_read(module); return LDB_ERR_OPERATIONS_ERROR; } if (req->op.search.tree == NULL) { ldb_kv->kv_ops->unlock_read(module); return LDB_ERR_OPERATIONS_ERROR; } ctx->tree = req->op.search.tree; ctx->scope = req->op.search.scope; ctx->base = req->op.search.base; ctx->attrs = req->op.search.attrs; if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) { /* Check what we should do with a NULL dn */ switch (req->op.search.scope) { case LDB_SCOPE_BASE: ldb_asprintf_errstring(ldb, "NULL Base DN invalid for a base search"); ret = LDB_ERR_INVALID_DN_SYNTAX; break; case LDB_SCOPE_ONELEVEL: ldb_asprintf_errstring(ldb, "NULL Base DN invalid for a one-level search"); ret = LDB_ERR_INVALID_DN_SYNTAX; break; case LDB_SCOPE_SUBTREE: default: /* We accept subtree searches from a NULL base DN, ie over the whole DB */ ret = LDB_SUCCESS; } } else if (req->op.search.scope == LDB_SCOPE_BASE) { /* * If we are LDB_SCOPE_BASE, do just one search and * return early. This is critical to ensure we do not * go into the index code for special DNs, as that * will try to look up an index record for a special * record (which doesn't exist). */ ret = ldb_kv_search_and_return_base(ldb_kv, ctx); ldb_kv->kv_ops->unlock_read(module); return ret; } else if (ldb_kv->check_base) { /* * This database has been marked as * 'checkBaseOnSearch', so do a spot check of the base * dn. Also optimise the subsequent filter by filling * in the ctx->base to be exactly case correct */ ret = ldb_kv_search_base( module, ctx, req->op.search.base, &ctx->base); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_asprintf_errstring(ldb, "No such Base DN: %s", 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; } if (ret == LDB_SUCCESS) { uint32_t match_count = 0; ret = ldb_kv_search_indexed(ctx, &match_count); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* Not in the index, therefore OK! */ ret = LDB_SUCCESS; } /* Check if we got just a normal error. * In that case proceed to a full search unless we got a * callback error */ if (!ctx->request_terminated && ret != LDB_SUCCESS) { /* Not indexed, so we need to do a full scan */ if (ldb_kv->warn_unindexed || ldb_kv->disable_full_db_scan) { /* useful for debugging when slow performance * is caused by unindexed searches */ char *expression = ldb_filter_from_tree(ctx, ctx->tree); ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb FULL SEARCH: %s SCOPE: %s DN: %s", expression, req->op.search.scope==LDB_SCOPE_BASE?"base": req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN", ldb_dn_get_linearized(req->op.search.base)); talloc_free(expression); } if (match_count != 0) { /* the indexing code gave an error * after having returned at least one * entry. This means the indexes are * corrupt or a database record is * corrupt. We cannot continue with a * full search or we may return * duplicate entries */ ldb_kv->kv_ops->unlock_read(module); return LDB_ERR_OPERATIONS_ERROR; } if (ldb_kv->disable_full_db_scan) { ldb_set_errstring(ldb, "ldb FULL SEARCH disabled"); ldb_kv->kv_ops->unlock_read(module); return LDB_ERR_INAPPROPRIATE_MATCHING; } ret = ldb_kv_search_full(ctx); if (ret != LDB_SUCCESS) { ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); } } } ldb_kv->kv_ops->unlock_read(module); return ret; } ldb-2.0.8/ldb_ldap/ldb_ldap.c0000660000000000000000000005306713573675413015715 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 Copyright (C) Simo Sorce 2006 ** 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 . */ /* * Name: ldb_ldap * * Component: ldb ldap backend * * Description: core files for LDAP backend * * Author: Andrew Tridgell * * Modifications: * * - description: make the module use asynchronous calls * date: Feb 2006 * author: Simo Sorce */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_module.h" #include "ldb_private.h" #define LDAP_DEPRECATED 1 #include struct lldb_private { LDAP *ldap; }; struct lldb_context { struct ldb_module *module; struct ldb_request *req; struct lldb_private *lldb; struct ldb_control **controls; int msgid; }; static int lldb_ldap_to_ldb(int err) { /* Ldap errors and ldb errors are defined to the same values */ return err; } /* convert a ldb_message structure to a list of LDAPMod structures ready for ldap_add() or ldap_modify() */ static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags) { LDAPMod **mods; unsigned int i, j; int num_mods = 0; /* allocate maximum number of elements needed */ mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1); if (!mods) { errno = ENOMEM; return NULL; } mods[0] = NULL; for (i=0;inum_elements;i++) { const struct ldb_message_element *el = &msg->elements[i]; mods[num_mods] = talloc(mods, LDAPMod); if (!mods[num_mods]) { goto failed; } mods[num_mods+1] = NULL; mods[num_mods]->mod_op = LDAP_MOD_BVALUES; if (use_flags) { switch (el->flags & LDB_FLAG_MOD_MASK) { case LDB_FLAG_MOD_ADD: mods[num_mods]->mod_op |= LDAP_MOD_ADD; break; case LDB_FLAG_MOD_DELETE: mods[num_mods]->mod_op |= LDAP_MOD_DELETE; break; case LDB_FLAG_MOD_REPLACE: mods[num_mods]->mod_op |= LDAP_MOD_REPLACE; break; } } mods[num_mods]->mod_type = discard_const_p(char, el->name); mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], struct berval *, 1+el->num_values); if (!mods[num_mods]->mod_vals.modv_bvals) { goto failed; } for (j=0;jnum_values;j++) { mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals, struct berval); if (!mods[num_mods]->mod_vals.modv_bvals[j]) { goto failed; } mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = (char *)el->values[j].data; mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length; } mods[num_mods]->mod_vals.modv_bvals[j] = NULL; num_mods++; } return mods; failed: talloc_free(mods); return NULL; } /* add a single set of ldap message values to a ldb_message */ static int lldb_add_msg_attr(struct ldb_context *ldb, struct ldb_message *msg, const char *attr, struct berval **bval) { int count, i, ret; struct ldb_message_element *el; count = ldap_count_values_len(bval); if (count <= 0) { return -1; } ret = ldb_msg_add_empty(msg, attr, 0, &el); if (ret != LDB_SUCCESS) { errno = ENOMEM; return -1; } el->values = talloc_array(msg->elements, struct ldb_val, count); if (!el->values) { errno = ENOMEM; return -1; } for (i=0;ivalues[i].data = talloc_size(el->values, bval[i]->bv_len+1); if (!el->values[i].data) { errno = ENOMEM; return -1; } memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len); el->values[i].data[bval[i]->bv_len] = 0; el->values[i].length = bval[i]->bv_len; el->num_values++; } msg->num_elements++; return 0; } /* search for matching records */ static int lldb_search(struct lldb_context *lldb_ac) { struct ldb_context *ldb; struct lldb_private *lldb = lldb_ac->lldb; struct ldb_module *module = lldb_ac->module; struct ldb_request *req = lldb_ac->req; struct timeval tv; int ldap_scope; char *search_base; char *expression; int ret; ldb = ldb_module_get_ctx(module); if (!req->callback || !req->context) { ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); return LDB_ERR_OPERATIONS_ERROR; } if (req->op.search.tree == NULL) { ldb_set_errstring(ldb, "Invalid expression parse tree"); return LDB_ERR_OPERATIONS_ERROR; } if (req->controls != NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!"); } ldb_request_set_state(req, LDB_ASYNC_PENDING); search_base = ldb_dn_alloc_linearized(lldb_ac, req->op.search.base); if (req->op.search.base == NULL) { search_base = talloc_strdup(lldb_ac, ""); } if (search_base == NULL) { return LDB_ERR_OPERATIONS_ERROR; } expression = ldb_filter_from_tree(lldb_ac, req->op.search.tree); if (expression == NULL) { return LDB_ERR_OPERATIONS_ERROR; } switch (req->op.search.scope) { case LDB_SCOPE_BASE: ldap_scope = LDAP_SCOPE_BASE; break; case LDB_SCOPE_ONELEVEL: ldap_scope = LDAP_SCOPE_ONELEVEL; break; default: ldap_scope = LDAP_SCOPE_SUBTREE; break; } tv.tv_sec = 0; tv.tv_usec = 0; if (req->timeout > 0) { tv.tv_sec = req->timeout; } ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, expression, discard_const_p(char *, req->op.search.attrs), 0, NULL, NULL, &tv, LDAP_NO_LIMIT, &lldb_ac->msgid); if (ret != LDAP_SUCCESS) { ldb_set_errstring(ldb, ldap_err2string(ret)); } return lldb_ldap_to_ldb(ret); } /* add a record */ static int lldb_add(struct lldb_context *lldb_ac) { struct ldb_context *ldb; struct lldb_private *lldb = lldb_ac->lldb; struct ldb_module *module = lldb_ac->module; struct ldb_request *req = lldb_ac->req; LDAPMod **mods; char *dn; int ret; ldb = ldb_module_get_ctx(module); ldb_request_set_state(req, LDB_ASYNC_PENDING); mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0); if (mods == NULL) { return LDB_ERR_OPERATIONS_ERROR; } dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn); if (dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldap_add_ext(lldb->ldap, dn, mods, NULL, NULL, &lldb_ac->msgid); if (ret != LDAP_SUCCESS) { ldb_set_errstring(ldb, ldap_err2string(ret)); } return lldb_ldap_to_ldb(ret); } /* modify a record */ static int lldb_modify(struct lldb_context *lldb_ac) { struct ldb_context *ldb; struct lldb_private *lldb = lldb_ac->lldb; struct ldb_module *module = lldb_ac->module; struct ldb_request *req = lldb_ac->req; LDAPMod **mods; char *dn; int ret; ldb = ldb_module_get_ctx(module); ldb_request_set_state(req, LDB_ASYNC_PENDING); mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1); if (mods == NULL) { return LDB_ERR_OPERATIONS_ERROR; } dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn); if (dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldap_modify_ext(lldb->ldap, dn, mods, NULL, NULL, &lldb_ac->msgid); if (ret != LDAP_SUCCESS) { ldb_set_errstring(ldb, ldap_err2string(ret)); } return lldb_ldap_to_ldb(ret); } /* delete a record */ static int lldb_delete(struct lldb_context *lldb_ac) { struct ldb_context *ldb; struct lldb_private *lldb = lldb_ac->lldb; struct ldb_module *module = lldb_ac->module; struct ldb_request *req = lldb_ac->req; char *dnstr; int ret; ldb = ldb_module_get_ctx(module); ldb_request_set_state(req, LDB_ASYNC_PENDING); dnstr = ldb_dn_alloc_linearized(lldb_ac, req->op.del.dn); ret = ldap_delete_ext(lldb->ldap, dnstr, NULL, NULL, &lldb_ac->msgid); if (ret != LDAP_SUCCESS) { ldb_set_errstring(ldb, ldap_err2string(ret)); } return lldb_ldap_to_ldb(ret); } /* rename a record */ static int lldb_rename(struct lldb_context *lldb_ac) { struct ldb_context *ldb; struct lldb_private *lldb = lldb_ac->lldb; struct ldb_module *module = lldb_ac->module; struct ldb_request *req = lldb_ac->req; const char *rdn_name; const struct ldb_val *rdn_val; char *old_dn; char *newrdn; char *parentdn; int ret; ldb = ldb_module_get_ctx(module); ldb_request_set_state(req, LDB_ASYNC_PENDING); old_dn = ldb_dn_alloc_linearized(lldb_ac, req->op.rename.olddn); if (old_dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); if ((rdn_name != NULL) && (rdn_val != NULL)) { newrdn = talloc_asprintf(lldb_ac, "%s=%s", rdn_name, rdn_val->length > 0 ? ldb_dn_escape_value(lldb, *rdn_val) : ""); } else { newrdn = talloc_strdup(lldb_ac, ""); } if (!newrdn) { return LDB_ERR_OPERATIONS_ERROR; } parentdn = ldb_dn_alloc_linearized(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn)); if (!parentdn) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn, 1, NULL, NULL, &lldb_ac->msgid); if (ret != LDAP_SUCCESS) { ldb_set_errstring(ldb, ldap_err2string(ret)); } return lldb_ldap_to_ldb(ret); } static int lldb_start_trans(struct ldb_module *module) { /* TODO implement a local transaction mechanism here */ return LDB_SUCCESS; } static int lldb_end_trans(struct ldb_module *module) { /* TODO implement a local transaction mechanism here */ return LDB_SUCCESS; } static int lldb_del_trans(struct ldb_module *module) { /* TODO implement a local transaction mechanism here */ return LDB_SUCCESS; } static void lldb_request_done(struct lldb_context *ac, struct ldb_control **ctrls, int error) { struct ldb_request *req; struct ldb_reply *ares; req = ac->req; ares = talloc_zero(req, struct ldb_reply); if (!ares) { ldb_oom(ldb_module_get_ctx(ac->module)); req->callback(req, NULL); return; } ares->type = LDB_REPLY_DONE; ares->controls = talloc_steal(ares, ctrls); ares->error = error; req->callback(req, ares); } /* return false if the request is still in progress * return true if the request is completed */ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result) { struct ldb_context *ldb; struct lldb_private *lldb = ac->lldb; LDAPControl **serverctrlsp = NULL; char **referralsp = NULL; char *matcheddnp = NULL; char *errmsgp = NULL; LDAPMessage *msg; int type; struct ldb_message *ldbmsg = NULL; char *referral; bool callback_failed; bool request_done; bool lret; unsigned int i; int ret; ldb = ldb_module_get_ctx(ac->module); type = ldap_msgtype(result); callback_failed = false; request_done = false; switch (type) { case LDAP_RES_SEARCH_ENTRY: msg = ldap_first_entry(lldb->ldap, result); if (msg != NULL) { BerElement *berptr = NULL; char *attr, *dn; ldbmsg = ldb_msg_new(ac); if (!ldbmsg) { ldb_oom(ldb); ret = LDB_ERR_OPERATIONS_ERROR; break; } dn = ldap_get_dn(lldb->ldap, msg); if (!dn) { ldb_oom(ldb); talloc_free(ldbmsg); ret = LDB_ERR_OPERATIONS_ERROR; break; } ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn); if ( ! ldb_dn_validate(ldbmsg->dn)) { ldb_asprintf_errstring(ldb, "Invalid DN '%s' in reply", dn); talloc_free(ldbmsg); ret = LDB_ERR_OPERATIONS_ERROR; ldap_memfree(dn); break; } ldap_memfree(dn); /* loop over all attributes */ for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); attr; attr=ldap_next_attribute(lldb->ldap, msg, berptr)) { struct berval **bval; bval = ldap_get_values_len(lldb->ldap, msg, attr); if (bval) { lldb_add_msg_attr(ldb, ldbmsg, attr, bval); ldap_value_free_len(bval); } } if (berptr) ber_free(berptr, 0); ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "entry send failed: %s", ldb_errstring(ldb)); callback_failed = true; } } else { ret = LDB_ERR_OPERATIONS_ERROR; } break; case LDAP_RES_SEARCH_REFERENCE: ret = ldap_parse_reference(lldb->ldap, result, &referralsp, &serverctrlsp, 0); if (ret != LDAP_SUCCESS) { ldb_asprintf_errstring(ldb, "ldap reference parse error: %s : %s", ldap_err2string(ret), errmsgp); ret = LDB_ERR_OPERATIONS_ERROR; break; } if (referralsp == NULL) { ldb_asprintf_errstring(ldb, "empty ldap referrals list"); ret = LDB_ERR_PROTOCOL_ERROR; break; } for (i = 0; referralsp[i]; i++) { referral = talloc_strdup(ac, referralsp[i]); ret = ldb_module_send_referral(ac->req, referral); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "referral send failed: %s", ldb_errstring(ldb)); callback_failed = true; break; } } break; case LDAP_RES_SEARCH_RESULT: case LDAP_RES_MODIFY: case LDAP_RES_ADD: case LDAP_RES_DELETE: case LDAP_RES_MODDN: if (ldap_parse_result(lldb->ldap, result, &ret, &matcheddnp, &errmsgp, &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { ret = LDB_ERR_OPERATIONS_ERROR; } if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "ldap parse error for type %d: %s : %s", type, ldap_err2string(ret), errmsgp); break; } if (serverctrlsp != NULL) { /* FIXME: transform the LDAPControl list into an ldb_control one */ ac->controls = NULL; } request_done = true; break; default: ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type); ret = LDB_ERR_PROTOCOL_ERROR; break; } if (ret != LDB_SUCCESS) { /* if the callback failed the caller will have freed the * request. Just return and don't try to use it */ if (callback_failed) { /* tell lldb_wait to remove the request from the * queue */ lret = true; goto free_and_return; } request_done = true; } if (request_done) { lldb_request_done(ac, ac->controls, ret); lret = true; goto free_and_return; } lret = false; free_and_return: if (matcheddnp) ldap_memfree(matcheddnp); if (errmsgp && *errmsgp) { ldb_set_errstring(ldb, errmsgp); } if (errmsgp) { ldap_memfree(errmsgp); } if (referralsp) ldap_value_free(referralsp); if (serverctrlsp) ldap_controls_free(serverctrlsp); ldap_msgfree(result); return lret; } static void lldb_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct lldb_context *ac; ac = talloc_get_type(private_data, struct lldb_context); lldb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); } static void lldb_callback(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct lldb_context *ac; struct tevent_timer *lte; struct timeval tv; LDAPMessage *result; int lret; ac = talloc_get_type(private_data, struct lldb_context); if (!ac->msgid) { lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); return; } tv.tv_sec = 0; tv.tv_usec = 0; lret = ldap_result(ac->lldb->ldap, ac->msgid, 0, &tv, &result); if (lret == 0) { goto respin; } if (lret == -1) { lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); return; } if ( ! lldb_parse_result(ac, result)) { goto respin; } return; respin: tv.tv_sec = 0; tv.tv_usec = 100; lte = tevent_add_timer(ev, ac, tv, lldb_callback, ac); if (NULL == lte) { lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); } } static bool lldb_dn_is_special(struct ldb_request *req) { struct ldb_dn *dn = NULL; switch (req->operation) { case LDB_ADD: dn = req->op.add.message->dn; break; case LDB_MODIFY: dn = req->op.mod.message->dn; break; case LDB_DELETE: dn = req->op.del.dn; break; case LDB_RENAME: dn = req->op.rename.olddn; break; default: break; } if (dn && ldb_dn_is_special(dn)) { return true; } return false; } static void lldb_auto_done_callback(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct lldb_context *ac; ac = talloc_get_type(private_data, struct lldb_context); lldb_request_done(ac, NULL, LDB_SUCCESS); } static int lldb_handle_request(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct lldb_private *lldb; struct lldb_context *ac; struct tevent_context *ev; struct tevent_timer *te; struct timeval tv; int ret; lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); ldb = ldb_module_get_ctx(module); if (req->starttime == 0 || req->timeout == 0) { ldb_set_errstring(ldb, "Invalid timeout settings"); return LDB_ERR_TIME_LIMIT_EXCEEDED; } ev = ldb_get_event_context(ldb); if (NULL == ev) { return LDB_ERR_OPERATIONS_ERROR; } ac = talloc_zero(ldb, struct lldb_context); if (ac == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } ac->module = module; ac->req = req; ac->lldb = lldb; ac->msgid = 0; if (lldb_dn_is_special(req)) { tv.tv_sec = 0; tv.tv_usec = 0; te = tevent_add_timer(ev, ac, tv, lldb_auto_done_callback, ac); if (NULL == te) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } switch (ac->req->operation) { case LDB_SEARCH: ret = lldb_search(ac); break; case LDB_ADD: ret = lldb_add(ac); break; case LDB_MODIFY: ret = lldb_modify(ac); break; case LDB_DELETE: ret = lldb_delete(ac); break; case LDB_RENAME: ret = lldb_rename(ac); break; default: /* no other op supported */ ret = LDB_ERR_PROTOCOL_ERROR; break; } if (ret != LDB_SUCCESS) { lldb_request_done(ac, NULL, ret); return ret; } tv.tv_sec = 0; tv.tv_usec = 0; te = tevent_add_timer(ev, ac, tv, lldb_callback, ac); if (NULL == te) { return LDB_ERR_OPERATIONS_ERROR; } if (req->timeout > 0) { tv.tv_sec = req->starttime + req->timeout; tv.tv_usec = 0; te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac); if (NULL == te) { return LDB_ERR_OPERATIONS_ERROR; } } return LDB_SUCCESS; } static const struct ldb_module_ops lldb_ops = { .name = "ldap", .search = lldb_handle_request, .add = lldb_handle_request, .modify = lldb_handle_request, .del = lldb_handle_request, .rename = lldb_handle_request, .request = lldb_handle_request, .start_transaction = lldb_start_trans, .end_transaction = lldb_end_trans, .del_transaction = lldb_del_trans, }; static int lldb_destructor(struct lldb_private *lldb) { ldap_unbind(lldb->ldap); return 0; } /* optionally perform a bind */ static int lldb_bind(struct ldb_module *module, const char *options[]) { const char *bind_mechanism; struct lldb_private *lldb; struct ldb_context *ldb = ldb_module_get_ctx(module); int ret; bind_mechanism = ldb_options_find(ldb, options, "bindMech"); if (bind_mechanism == NULL) { /* no bind wanted */ return LDB_SUCCESS; } lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); if (strcmp(bind_mechanism, "simple") == 0) { const char *bind_id, *bind_secret; bind_id = ldb_options_find(ldb, options, "bindID"); bind_secret = ldb_options_find(ldb, options, "bindSecret"); if (bind_id == NULL || bind_secret == NULL) { ldb_asprintf_errstring(ldb, "simple bind requires bindID and bindSecret"); return LDB_ERR_OPERATIONS_ERROR; } ret = ldap_simple_bind_s(lldb->ldap, bind_id, bind_secret); if (ret != LDAP_SUCCESS) { ldb_asprintf_errstring(ldb, "bind failed: %s", ldap_err2string(ret)); return ret; } return LDB_SUCCESS; } ldb_asprintf_errstring(ldb, "bind failed: unknown mechanism %s", bind_mechanism); return LDB_ERR_INAPPROPRIATE_AUTHENTICATION; } /* 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) { struct ldb_module *module; struct lldb_private *lldb; int version = 3; int ret; module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops); if (!module) return LDB_ERR_OPERATIONS_ERROR; lldb = talloc_zero(module, struct lldb_private); if (!lldb) { ldb_oom(ldb); goto failed; } ldb_module_set_private(module, lldb); ret = ldap_initialize(&lldb->ldap, url); if (ret != LDAP_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s", url, ldap_err2string(ret)); goto failed; } talloc_set_destructor(lldb, lldb_destructor); ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); if (ret != LDAP_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s", ldap_err2string(ret)); goto failed; } *_module = module; ret = lldb_bind(module, options); if (ret != LDB_SUCCESS) { goto failed; } return LDB_SUCCESS; failed: talloc_free(module); return LDB_ERR_OPERATIONS_ERROR; } /* initialise the module */ int ldb_ldap_init(const char *version) { int ret, i; const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; LDB_MODULE_CHECK_VERSION(version); for (i=0; names[i]; i++) { ret = ldb_register_backend(names[i], lldb_connect, false); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } ldb-2.0.8/ldb_ldb/ldb_ldb.c0000660000000000000000000000363613444661620015344 0ustar rootroot00000000000000/* * ldb connection and module initialisation * * Copyright (C) Andrew Bartlett 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 . * */ #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); } ldb-2.0.8/ldb_map/ldb_map.c0000660000000000000000000007254513444661620015401 0ustar rootroot00000000000000/* ldb database mapping module Copyright (C) Jelmer Vernooij 2005 Copyright (C) Martin Kuehl 2006 Copyright (C) Simo Sorce 2008 ** 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 . */ /* * Name: ldb * * Component: ldb ldb_map module * * Description: Map portions of data into a different format on a * remote partition. * * Author: Jelmer Vernooij, Martin Kuehl */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_map.h" #include "ldb_map_private.h" #ifndef _PUBLIC_ #define _PUBLIC_ #endif /* Description of the provided ldb requests: - special attribute 'isMapped' - search: - if parse tree can be split - search remote records w/ remote attrs and parse tree - otherwise - enumerate all remote records - for each remote result - map remote result to local message - search local result - is present - merge local into remote result - run callback on merged result - otherwise - run callback on remote result - add: - split message into local and remote part - if local message is not empty - add isMapped to local message - add local message - add remote message - modify: - split message into local and remote part - if local message is not empty - add isMapped to local message - search for local record - if present - modify local record - otherwise - add local message - modify remote record - delete: - search for local record - if present - delete local record - delete remote record - rename: - search for local record - if present - rename local record - modify local isMapped - rename remote record */ /* Private data structures * ======================= */ /* Global private data */ /* Extract mappings from private data. */ const struct ldb_map_context *map_get_context(struct ldb_module *module) { const struct map_private *data = talloc_get_type(ldb_module_get_private(module), struct map_private); return data->context; } /* Create a generic request context. */ struct map_context *map_init_context(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct map_context *ac; ldb = ldb_module_get_ctx(module); ac = talloc_zero(req, struct map_context); if (ac == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return NULL; } ac->module = module; ac->req = req; return ac; } /* Dealing with DNs for different partitions * ========================================= */ /* Check whether any data should be stored in the local partition. */ bool map_check_local_db(struct ldb_module *module) { const struct ldb_map_context *data = map_get_context(module); if (!data->remote_base_dn || !data->local_base_dn) { return false; } return true; } /* Copy a DN with the base DN of the local partition. */ static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) { struct ldb_dn *new_dn; new_dn = ldb_dn_copy(mem_ctx, dn); if ( ! ldb_dn_validate(new_dn)) { talloc_free(new_dn); return NULL; } /* may be we don't need to rebase at all */ if ( ! data->remote_base_dn || ! data->local_base_dn) { return new_dn; } if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->remote_base_dn))) { talloc_free(new_dn); return NULL; } if ( ! ldb_dn_add_base(new_dn, data->local_base_dn)) { talloc_free(new_dn); return NULL; } return new_dn; } /* Copy a DN with the base DN of the remote partition. */ static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) { struct ldb_dn *new_dn; new_dn = ldb_dn_copy(mem_ctx, dn); if ( ! ldb_dn_validate(new_dn)) { talloc_free(new_dn); return NULL; } /* may be we don't need to rebase at all */ if ( ! data->remote_base_dn || ! data->local_base_dn) { return new_dn; } if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->local_base_dn))) { talloc_free(new_dn); return NULL; } if ( ! ldb_dn_add_base(new_dn, data->remote_base_dn)) { talloc_free(new_dn); return NULL; } return new_dn; } /* Run a request and make sure it targets the remote partition. */ /* TODO: free old DNs and messages? */ int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request) { const struct ldb_map_context *data = map_get_context(module); struct ldb_context *ldb; struct ldb_message *msg; ldb = ldb_module_get_ctx(module); switch (request->operation) { case LDB_SEARCH: if (request->op.search.base) { request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base); } else { request->op.search.base = data->remote_base_dn; /* TODO: adjust scope? */ } break; case LDB_ADD: msg = ldb_msg_copy_shallow(request, request->op.add.message); if (msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); request->op.add.message = msg; break; case LDB_MODIFY: msg = ldb_msg_copy_shallow(request, request->op.mod.message); if (msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); request->op.mod.message = msg; break; case LDB_DELETE: request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn); break; case LDB_RENAME: request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn); request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn); break; default: ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "Invalid remote request!"); return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(module, request); } /* Finding mappings for attributes and objectClasses * ================================================= */ /* Find an objectClass mapping by the local name. */ static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name) { unsigned int i; for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) { if (ldb_attr_cmp(data->objectclass_maps[i].local_name, name) == 0) { return &data->objectclass_maps[i]; } } return NULL; } /* Find an objectClass mapping by the remote name. */ static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name) { unsigned int i; for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) { if (ldb_attr_cmp(data->objectclass_maps[i].remote_name, name) == 0) { return &data->objectclass_maps[i]; } } return NULL; } /* Find an attribute mapping by the local name. */ const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name) { unsigned int i; for (i = 0; data->attribute_maps[i].local_name; i++) { if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) { return &data->attribute_maps[i]; } } for (i = 0; data->attribute_maps[i].local_name; i++) { if (ldb_attr_cmp(data->attribute_maps[i].local_name, "*") == 0) { return &data->attribute_maps[i]; } } return NULL; } /* Find an attribute mapping by the remote name. */ const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name) { const struct ldb_map_attribute *map; const struct ldb_map_attribute *wildcard = NULL; unsigned int i, j; for (i = 0; data->attribute_maps[i].local_name; i++) { map = &data->attribute_maps[i]; if (ldb_attr_cmp(map->local_name, "*") == 0) { wildcard = &data->attribute_maps[i]; } switch (map->type) { case LDB_MAP_IGNORE: break; case LDB_MAP_KEEP: if (ldb_attr_cmp(map->local_name, name) == 0) { return map; } break; case LDB_MAP_RENAME: case LDB_MAP_RENDROP: case LDB_MAP_CONVERT: if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) { return map; } break; case LDB_MAP_GENERATE: for (j = 0; map->u.generate.remote_names[j]; j++) { if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) { return map; } } break; } } /* We didn't find it, so return the wildcard record if one was configured */ return wildcard; } /* Mapping attributes * ================== */ /* Check whether an attribute will be mapped into the remote partition. */ bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr) { const struct ldb_map_attribute *map = map_attr_find_local(data, attr); if (map == NULL) { return false; } if (map->type == LDB_MAP_IGNORE) { return false; } return true; } /* Map an attribute name into the remote partition. */ const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) { if (map == NULL) { return talloc_strdup(mem_ctx, attr); } switch (map->type) { case LDB_MAP_KEEP: return talloc_strdup(mem_ctx, attr); case LDB_MAP_RENAME: case LDB_MAP_RENDROP: case LDB_MAP_CONVERT: return talloc_strdup(mem_ctx, map->u.rename.remote_name); default: return NULL; } } /* Map an attribute name back into the local partition. */ const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) { if (map == NULL) { return talloc_strdup(mem_ctx, attr); } if (map->type == LDB_MAP_KEEP) { return talloc_strdup(mem_ctx, attr); } return talloc_strdup(mem_ctx, map->local_name); } /* Merge two lists of attributes into a single one. */ int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs) { unsigned int i, j, k; for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ; for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ; *attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1); if (*attrs == NULL) { map_oom(module); return -1; } for (k = 0; k < j; k++) { (*attrs)[i + k] = more_attrs[k]; } (*attrs)[i+k] = NULL; return 0; } /* Mapping ldb values * ================== */ /* Map an ldb value into the remote partition. */ struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val) { if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) { return map->u.convert.convert_local(module, mem_ctx, val); } return ldb_val_dup(mem_ctx, val); } /* Map an ldb value back into the local partition. */ struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val) { if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) { return map->u.convert.convert_remote(module, mem_ctx, val); } return ldb_val_dup(mem_ctx, val); } /* Mapping DNs * =========== */ /* Check whether a DN is below the local baseDN. */ bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn) { const struct ldb_map_context *data = map_get_context(module); if (!data->local_base_dn) { return true; } return ldb_dn_compare_base(data->local_base_dn, dn) == 0; } /* Map a DN into the remote partition. */ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) { const struct ldb_map_context *data = map_get_context(module); struct ldb_context *ldb; struct ldb_dn *newdn; const struct ldb_map_attribute *map; enum ldb_map_attr_type map_type; const char *name; struct ldb_val value; int i, ret; if (dn == NULL) { return NULL; } ldb = ldb_module_get_ctx(module); newdn = ldb_dn_copy(mem_ctx, dn); if (newdn == NULL) { map_oom(module); return NULL; } /* For each RDN, map the component name and possibly the value */ for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i)); /* Unknown attribute - leave this RDN as is and hope the best... */ if (map == NULL) { map_type = LDB_MAP_KEEP; } else { map_type = map->type; } switch (map_type) { case LDB_MAP_IGNORE: case LDB_MAP_GENERATE: ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; case LDB_MAP_CONVERT: if (map->u.convert.convert_local == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "'convert_local' not set for attribute '%s' " "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; } FALL_THROUGH; case LDB_MAP_KEEP: case LDB_MAP_RENAME: case LDB_MAP_RENDROP: name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); if (name == NULL) goto failed; value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i)); if (value.data == NULL) goto failed; ret = ldb_dn_set_component(newdn, i, name, value); if (ret != LDB_SUCCESS) { goto failed; } break; } } return newdn; failed: talloc_free(newdn); return NULL; } /* Map a DN into the local partition. */ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) { const struct ldb_map_context *data = map_get_context(module); struct ldb_context *ldb; struct ldb_dn *newdn; const struct ldb_map_attribute *map; enum ldb_map_attr_type map_type; const char *name; struct ldb_val value; int i, ret; if (dn == NULL) { return NULL; } ldb = ldb_module_get_ctx(module); newdn = ldb_dn_copy(mem_ctx, dn); if (newdn == NULL) { map_oom(module); return NULL; } /* For each RDN, map the component name and possibly the value */ for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i)); /* Unknown attribute - leave this RDN as is and hope the best... */ if (map == NULL) { map_type = LDB_MAP_KEEP; } else { map_type = map->type; } switch (map_type) { case LDB_MAP_IGNORE: case LDB_MAP_GENERATE: ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; case LDB_MAP_CONVERT: if (map->u.convert.convert_remote == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "'convert_remote' not set for attribute '%s' " "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; } FALL_THROUGH; case LDB_MAP_KEEP: case LDB_MAP_RENAME: case LDB_MAP_RENDROP: name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); if (name == NULL) goto failed; value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i)); if (value.data == NULL) goto failed; ret = ldb_dn_set_component(newdn, i, name, value); if (ret != LDB_SUCCESS) { goto failed; } break; } } return newdn; failed: talloc_free(newdn); return NULL; } /* Map a DN and its base into the local partition. */ /* TODO: This should not be required with GUIDs. */ struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) { const struct ldb_map_context *data = map_get_context(module); struct ldb_dn *dn1, *dn2; dn1 = ldb_dn_rebase_local(mem_ctx, data, dn); dn2 = ldb_dn_map_remote(module, mem_ctx, dn1); talloc_free(dn1); return dn2; } /* Converting DNs and objectClasses (as ldb values) * ================================================ */ /* Map a DN contained in an ldb value into the remote partition. */ static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) { struct ldb_context *ldb; struct ldb_dn *dn, *newdn; struct ldb_val newval; ldb = ldb_module_get_ctx(module); dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); if (! ldb_dn_validate(dn)) { newval.length = 0; newval.data = NULL; talloc_free(dn); return newval; } newdn = ldb_dn_map_local(module, mem_ctx, dn); talloc_free(dn); newval.length = 0; newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); if (newval.data) { newval.length = strlen((char *)newval.data); } talloc_free(newdn); return newval; } /* Map a DN contained in an ldb value into the local partition. */ static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) { struct ldb_context *ldb; struct ldb_dn *dn, *newdn; struct ldb_val newval; ldb = ldb_module_get_ctx(module); dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); if (! ldb_dn_validate(dn)) { newval.length = 0; newval.data = NULL; talloc_free(dn); return newval; } newdn = ldb_dn_map_remote(module, mem_ctx, dn); talloc_free(dn); newval.length = 0; newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); if (newval.data) { newval.length = strlen((char *)newval.data); } talloc_free(newdn); return newval; } /* Map an objectClass into the remote partition. */ static struct ldb_val map_objectclass_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) { const struct ldb_map_context *data = map_get_context(module); const char *name = (char *)val->data; const struct ldb_map_objectclass *map = map_objectclass_find_local(data, name); struct ldb_val newval; if (map) { newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->remote_name); newval.length = strlen((char *)newval.data); return newval; } return ldb_val_dup(mem_ctx, val); } /* Generate a remote message with a mapped objectClass. */ static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local) { const struct ldb_map_context *data = map_get_context(module); struct ldb_context *ldb; struct ldb_message_element *el, *oc; struct ldb_val val; bool found_extensibleObject = false; unsigned int i; int ret; ldb = ldb_module_get_ctx(module); /* Find old local objectClass */ oc = ldb_msg_find_element(old, "objectClass"); if (oc == NULL) { return; } /* Prepare new element */ el = talloc_zero(remote, struct ldb_message_element); if (el == NULL) { ldb_oom(ldb); return; /* TODO: fail? */ } /* Copy local objectClass element, reverse space for an extra value */ el->num_values = oc->num_values + 1; el->values = talloc_array(el, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(el); ldb_oom(ldb); return; /* TODO: fail? */ } /* Copy local element name "objectClass" */ el->name = talloc_strdup(el, local_attr); /* Convert all local objectClasses */ for (i = 0; i < el->num_values - 1; i++) { el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]); if (ldb_attr_cmp((char *)el->values[i].data, data->add_objectclass) == 0) { found_extensibleObject = true; } } if (!found_extensibleObject) { val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); val.length = strlen((char *)val.data); /* Append additional objectClass data->add_objectclass */ el->values[i] = val; } else { el->num_values--; } /* Add new objectClass to remote message */ ret = ldb_msg_add(remote, el, 0); if (ret != LDB_SUCCESS) { ldb_oom(ldb); return; } } /* Map an objectClass into the local partition. */ static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) { const struct ldb_map_context *data = map_get_context(module); const char *name = (char *)val->data; const struct ldb_map_objectclass *map = map_objectclass_find_remote(data, name); struct ldb_val newval; if (map) { newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->local_name); newval.length = strlen((char *)newval.data); return newval; } return ldb_val_dup(mem_ctx, val); } /* Generate a local message with a mapped objectClass. */ static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote) { const struct ldb_map_context *data = map_get_context(module); struct ldb_context *ldb; struct ldb_message_element *el, *oc; struct ldb_val val; unsigned int i; ldb = ldb_module_get_ctx(module); /* Find old remote objectClass */ oc = ldb_msg_find_element(remote, "objectClass"); if (oc == NULL) { return NULL; } /* Prepare new element */ el = talloc_zero(mem_ctx, struct ldb_message_element); if (el == NULL) { ldb_oom(ldb); return NULL; } /* Copy remote objectClass element */ el->num_values = oc->num_values; el->values = talloc_array(el, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(el); ldb_oom(ldb); return NULL; } /* Copy remote element name "objectClass" */ el->name = talloc_strdup(el, local_attr); /* Convert all remote objectClasses */ for (i = 0; i < el->num_values; i++) { el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]); } val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); val.length = strlen((char *)val.data); /* Remove last value if it was the string in data->add_objectclass (eg samba4top, extensibleObject) */ if (ldb_val_equal_exact(&val, &el->values[i-1])) { el->num_values--; el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(el); ldb_oom(ldb); return NULL; } } return el; } static const struct ldb_map_attribute objectclass_convert_map = { .local_name = "objectClass", .type = LDB_MAP_CONVERT, .u = { .convert = { .remote_name = "objectClass", .convert_local = map_objectclass_convert_local, .convert_remote = map_objectclass_convert_remote, }, }, }; /* Mappings for searches on objectClass= assuming a one-to-one * mapping. Needed because this is a generate operator for the * add/modify code */ static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_convert_map); } /* Auxiliary request construction * ============================== */ /* Build a request to search a record by its DN. */ struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback) { struct ldb_parse_tree *search_tree; struct ldb_context *ldb; struct ldb_request *req; int ret; ldb = ldb_module_get_ctx(ac->module); if (tree) { search_tree = tree; } else { search_tree = ldb_parse_tree(ac, NULL); if (search_tree == NULL) { return NULL; } } ret = ldb_build_search_req_ex(&req, ldb, ac, dn, LDB_SCOPE_BASE, search_tree, attrs, NULL, context, callback, ac->req); LDB_REQ_SET_LOCATION(req); if (ret != LDB_SUCCESS) { return NULL; } return req; } /* Build a request to update the 'IS_MAPPED' attribute */ struct ldb_request *map_build_fixup_req(struct map_context *ac, struct ldb_dn *olddn, struct ldb_dn *newdn, void *context, ldb_map_callback_t callback) { struct ldb_context *ldb; struct ldb_request *req; struct ldb_message *msg; const char *dn; int ret; ldb = ldb_module_get_ctx(ac->module); /* Prepare message */ msg = ldb_msg_new(ac); if (msg == NULL) { map_oom(ac->module); return NULL; } /* Update local 'IS_MAPPED' to the new remote DN */ msg->dn = ldb_dn_copy(msg, olddn); dn = ldb_dn_alloc_linearized(msg, newdn); if ( ! dn || ! ldb_dn_validate(msg->dn)) { goto failed; } if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { goto failed; } if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { goto failed; } /* Prepare request */ ret = ldb_build_mod_req(&req, ldb, ac, msg, NULL, context, callback, ac->req); LDB_REQ_SET_LOCATION(req); if (ret != LDB_SUCCESS) { goto failed; } talloc_steal(req, msg); return req; failed: talloc_free(msg); return NULL; } /* Module initialization * ===================== */ /* Builtin mappings for DNs and objectClasses */ static const struct ldb_map_attribute builtin_attribute_maps[] = { { .local_name = "dn", .type = LDB_MAP_CONVERT, .u = { .convert = { .remote_name = "dn", .convert_local = ldb_dn_convert_local, .convert_remote = ldb_dn_convert_remote, }, }, }, { .local_name = NULL, } }; static const struct ldb_map_attribute objectclass_attribute_map = { .local_name = "objectClass", .type = LDB_MAP_GENERATE, .convert_operator = map_objectclass_convert_operator, .u = { .generate = { .remote_names = { "objectClass", NULL }, .generate_local = map_objectclass_generate_local, .generate_remote = map_objectclass_generate_remote, }, }, }; /* Find the special 'MAP_DN_NAME' record and store local and remote * base DNs in private data. */ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, const char *name) { static const char * const attrs[] = { MAP_DN_FROM, MAP_DN_TO, NULL }; struct ldb_context *ldb; struct ldb_dn *dn; struct ldb_message *msg; struct ldb_result *res; int ret; if (!name) { data->local_base_dn = NULL; data->remote_base_dn = NULL; return LDB_SUCCESS; } ldb = ldb_module_get_ctx(module); dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name); if ( ! ldb_dn_validate(dn)) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "Failed to construct '%s' DN!", MAP_DN_NAME); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_search(ldb, data, &res, dn, LDB_SCOPE_BASE, attrs, NULL); talloc_free(dn); if (ret != LDB_SUCCESS) { return ret; } if (res->count == 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "No results for '%s=%s'!", MAP_DN_NAME, name); talloc_free(res); return LDB_ERR_CONSTRAINT_VIOLATION; } if (res->count > 1) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "Too many results for '%s=%s'!", MAP_DN_NAME, name); talloc_free(res); return LDB_ERR_CONSTRAINT_VIOLATION; } msg = res->msgs[0]; data->local_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_FROM); data->remote_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_TO); talloc_free(res); return LDB_SUCCESS; } /* Store attribute maps and objectClass maps in private data. */ static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, const struct ldb_map_attribute *attrs, const struct ldb_map_objectclass *ocls, const char * const *wildcard_attributes) { unsigned int i, j, last; last = 0; /* Count specified attribute maps */ for (i = 0; attrs[i].local_name; i++) /* noop */ ; /* Count built-in attribute maps */ for (j = 0; builtin_attribute_maps[j].local_name; j++) /* noop */ ; /* Store list of attribute maps */ data->attribute_maps = talloc_array(data, struct ldb_map_attribute, i+j+2); if (data->attribute_maps == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* Specified ones go first */ for (i = 0; attrs[i].local_name; i++) { data->attribute_maps[last] = attrs[i]; last++; } /* Built-in ones go last */ for (i = 0; builtin_attribute_maps[i].local_name; i++) { data->attribute_maps[last] = builtin_attribute_maps[i]; last++; } if (data->add_objectclass) { /* ObjectClass one is very last, if required */ data->attribute_maps[last] = objectclass_attribute_map; last++; } else if (ocls) { data->attribute_maps[last] = objectclass_convert_map; last++; } /* Ensure 'local_name == NULL' for the last entry */ memset(&data->attribute_maps[last], 0, sizeof(struct ldb_map_attribute)); /* Store list of objectClass maps */ data->objectclass_maps = ocls; data->wildcard_attributes = wildcard_attributes; return LDB_SUCCESS; } /* Initialize global private data. */ _PUBLIC_ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, const struct ldb_map_objectclass *ocls, const char * const *wildcard_attributes, const char *add_objectclass, const char *name) { struct map_private *data; int ret; /* Prepare private data */ data = talloc_zero(module, struct map_private); if (data == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } ldb_module_set_private(module, data); data->context = talloc_zero(data, struct ldb_map_context); if (!data->context) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* Store local and remote baseDNs */ ret = map_init_dns(module, data->context, name); if (ret != LDB_SUCCESS) { talloc_free(data); return ret; } data->context->add_objectclass = add_objectclass; /* Store list of attribute and objectClass maps */ ret = map_init_maps(module, data->context, attrs, ocls, wildcard_attributes); if (ret != LDB_SUCCESS) { talloc_free(data); return ret; } return LDB_SUCCESS; } ldb-2.0.8/ldb_map/ldb_map.h0000660000000000000000000001355012406075657015403 0ustar rootroot00000000000000/* ldb database mapping module Copyright (C) Jelmer Vernooij 2005 Copyright (C) Martin Kuehl 2006 ** 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 . */ #ifndef __LDB_MAP_H__ #define __LDB_MAP_H__ #include "ldb_module.h" /* ldb_map is a skeleton LDB module that can be used for any other modules * that need to map attributes. * * The term 'remote' in this header refers to the connection where the * original schema is used on while 'local' means the local connection * that any upper layers will use. * * All local attributes will have to have a definition. Not all remote * attributes need a definition as LDB is a lot less strict than LDAP * (in other words, sending unknown attributes to an LDAP server hurts us, * while returning too many attributes in ldb_search() doesn't) */ /* Name of the internal attribute pointing from the local to the * remote part of a record */ #define IS_MAPPED "isMapped" struct ldb_map_context; /* convert a local ldb_val to a remote ldb_val */ typedef struct ldb_val (*ldb_map_convert_func) (struct ldb_module *module, void *mem_ctx, const struct ldb_val *val); #define LDB_MAP_MAX_REMOTE_NAMES 10 /* map from local to remote attribute */ struct ldb_map_attribute { const char *local_name; /* local name */ enum ldb_map_attr_type { LDB_MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */ LDB_MAP_KEEP, /* Keep as is. Same name locally and remotely. */ LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */ LDB_MAP_CONVERT, /* Rename + convert data */ LDB_MAP_GENERATE, /* Use generate function for generating new name/data. Used for generating attributes based on multiple remote attributes. */ LDB_MAP_RENDROP /* Rename the attribute. Strip from Add requests. */ } type; /* if set, will be called for search expressions that contain this attribute */ int (*convert_operator)(struct ldb_module *, TALLOC_CTX *ctx, struct ldb_parse_tree **ntree, const struct ldb_parse_tree *otree); union { struct { const char *remote_name; } rename; struct { const char *remote_name; /* Convert local to remote data */ ldb_map_convert_func convert_local; /* Convert remote to local data */ /* an entry can have convert_remote set to NULL, as long as there as an entry with the same local_name * that is non-NULL before it. */ ldb_map_convert_func convert_remote; } convert; struct { /* Generate the local attribute from remote message */ struct ldb_message_element *(*generate_local)(struct ldb_module *, TALLOC_CTX *mem_ctx, const char *remote_attr, const struct ldb_message *remote); /* Update remote message with information from local message */ void (*generate_remote)(struct ldb_module *, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local); /* Name(s) for this attribute on the remote server. This is an array since * one local attribute's data can be split up into several attributes * remotely */ const char *remote_names[LDB_MAP_MAX_REMOTE_NAMES]; /* Names of additional remote attributes * required for the generation. NULL * indicates that `local_attr' suffices. */ /* #define LDB_MAP_MAX_SELF_ATTRIBUTES 10 const char *self_attrs[LDB_MAP_MAX_SELF_ATTRIBUTES]; */ } generate; } u; }; #define LDB_MAP_MAX_SUBCLASSES 10 #define LDB_MAP_MAX_MUSTS 10 #define LDB_MAP_MAX_MAYS 50 /* map from local to remote objectClass */ struct ldb_map_objectclass { const char *local_name; const char *remote_name; const char *base_classes[LDB_MAP_MAX_SUBCLASSES]; const char *musts[LDB_MAP_MAX_MUSTS]; const char *mays[LDB_MAP_MAX_MAYS]; }; /* private context data */ struct ldb_map_context { struct ldb_map_attribute *attribute_maps; /* NOTE: Always declare base classes first here */ const struct ldb_map_objectclass *objectclass_maps; /* Remote (often operational) attributes that should be added * to any wildcard search */ const char * const *wildcard_attributes; /* ObjectClass (if any) to be added to remote attributes on add */ const char *add_objectclass; /* struct ldb_context *mapped_ldb; */ struct ldb_dn *local_base_dn; struct ldb_dn *remote_base_dn; }; /* Global private data */ struct map_private { void *caller_private; struct ldb_map_context *context; }; /* Initialize global private data. */ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, const struct ldb_map_objectclass *ocls, const char * const *wildcard_attributes, const char *add_objectclass, const char *name); int ldb_map_add(struct ldb_module *module, struct ldb_request *req); int ldb_map_search(struct ldb_module *module, struct ldb_request *req); int ldb_map_rename(struct ldb_module *module, struct ldb_request *req); int ldb_map_delete(struct ldb_module *module, struct ldb_request *req); int ldb_map_modify(struct ldb_module *module, struct ldb_request *req); #define LDB_MAP_OPS \ .add = ldb_map_add, \ .modify = ldb_map_modify, \ .del = ldb_map_delete, \ .rename = ldb_map_rename, \ .search = ldb_map_search, #endif /* __LDB_MAP_H__ */ ldb-2.0.8/ldb_map/ldb_map_inbound.c0000660000000000000000000005435513444661620017116 0ustar rootroot00000000000000/* ldb database mapping module Copyright (C) Jelmer Vernooij 2005 Copyright (C) Martin Kuehl 2006 Copyright (C) Simo Sorce 2008 ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_map.h" #include "ldb_map_private.h" /* Mapping message elements * ======================== */ /* Map a message element into the remote partition. */ static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_message_element *old) { struct ldb_message_element *el; unsigned int i; el = talloc_zero(mem_ctx, struct ldb_message_element); if (el == NULL) { map_oom(module); return NULL; } el->num_values = old->num_values; el->values = talloc_array(el, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(el); map_oom(module); return NULL; } el->name = map_attr_map_local(el, map, old->name); for (i = 0; i < el->num_values; i++) { el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]); } return el; } /* Add a message element either to a local or to a remote message, * depending on whether it goes into the local or remote partition. */ static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old) { const struct ldb_map_context *data = map_get_context(module); const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name); struct ldb_message_element *el=NULL; struct ldb_context *ldb = ldb_module_get_ctx(module); /* Unknown attribute: ignore */ if (map == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Not mapping attribute '%s': no mapping found", old->name); goto local; } switch (map->type) { case LDB_MAP_RENDROP: if (optype != LDB_ADD) { /* do the same as LDB_MAP_RENAME */ el = ldb_msg_el_map_local(module, remote, map, old); break; } FALL_THROUGH; case LDB_MAP_IGNORE: goto local; case LDB_MAP_CONVERT: if (map->u.convert.convert_local == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Not mapping attribute '%s': " "'convert_local' not set", map->local_name); goto local; } FALL_THROUGH; case LDB_MAP_KEEP: case LDB_MAP_RENAME: el = ldb_msg_el_map_local(module, remote, map, old); break; case LDB_MAP_GENERATE: if (map->u.generate.generate_remote == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Not mapping attribute '%s': " "'generate_remote' not set", map->local_name); goto local; } /* TODO: if this attr requires context: * make sure all context attrs are mappable (in 'names') * make sure all context attrs have already been mapped? * maybe postpone generation until they have been mapped? */ map->u.generate.generate_remote(module, map->local_name, msg, remote, local); return 0; } if (el == NULL) { return -1; } return ldb_msg_add(remote, el, old->flags); local: el = talloc(local, struct ldb_message_element); if (el == NULL) { map_oom(module); return -1; } *el = *old; /* copy the old element */ return ldb_msg_add(local, el, old->flags); } /* Mapping messages * ================ */ /* Check whether a message will be (partially) mapped into the remote partition. */ static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_message *msg) { const struct ldb_map_context *data = map_get_context(module); bool ret; unsigned int i; for (i = 0; i < msg->num_elements; i++) { ret = map_attr_check_remote(data, msg->elements[i].name); if (ret) { return ret; } } return false; } /* Split message elements that stay in the local partition from those * that are mapped into the remote partition. */ static int ldb_msg_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg) { /* const char * const names[]; */ struct ldb_context *ldb; unsigned int i; int ret; ldb = ldb_module_get_ctx(module); for (i = 0; i < msg->num_elements; i++) { /* Skip 'IS_MAPPED' */ if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Skipping attribute '%s'", msg->elements[i].name); continue; } ret = ldb_msg_el_partition(module, optype, local, remote, msg, msg->elements[i].name, &msg->elements[i]); if (ret) { return ret; } } return 0; } static int map_add_do_local(struct map_context *ac); static int map_modify_do_local(struct map_context *ac); static int map_delete_do_local(struct map_context *ac); static int map_rename_do_local(struct map_context *ac); static int map_rename_do_fixup(struct map_context *ac); static int map_rename_local_callback(struct ldb_request *req, struct ldb_reply *ares); /***************************************************************************** * COMMON INBOUND functions *****************************************************************************/ /* Store the DN of a single search result in context. */ static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct map_context *ac; int ret; ac = talloc_get_type(req->context, struct map_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } /* We are interested only in the single reply */ switch(ares->type) { case LDB_REPLY_ENTRY: /* We have already found a remote DN */ if (ac->local_dn) { ldb_set_errstring(ldb, "Too many results!"); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* Store local DN */ ac->local_dn = talloc_steal(ac, ares->message->dn); break; case LDB_REPLY_DONE: switch (ac->req->operation) { case LDB_MODIFY: ret = map_modify_do_local(ac); break; case LDB_DELETE: ret = map_delete_do_local(ac); break; case LDB_RENAME: ret = map_rename_do_local(ac); break; default: /* if we get here we have definitely a problem */ ret = LDB_ERR_OPERATIONS_ERROR; } if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } default: /* ignore referrals */ break; } talloc_free(ares); return LDB_SUCCESS; } /* Build a request to search the local record by its DN. */ static int map_search_self_req(struct ldb_request **req, struct map_context *ac, struct ldb_dn *dn) { /* attrs[] is returned from this function in * ac->search_req->op.search.attrs, so it must be static, as * otherwise the compiler can put it on the stack */ static const char * const attrs[] = { IS_MAPPED, NULL }; struct ldb_parse_tree *tree; /* Limit search to records with 'IS_MAPPED' present */ tree = ldb_parse_tree(ac, "(" IS_MAPPED "=*)"); if (tree == NULL) { map_oom(ac->module); return LDB_ERR_OPERATIONS_ERROR; } *req = map_search_base_req(ac, dn, attrs, tree, ac, map_search_self_callback); if (*req == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } static int map_op_local_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct map_context *ac; int ret; ac = talloc_get_type(req->context, struct map_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* Do the remote request. */ ret = ldb_next_remote_request(ac->module, ac->remote_req); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } return LDB_SUCCESS; } static int map_op_remote_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct map_context *ac; ac = talloc_get_type(req->context, struct map_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } /***************************************************************************** * ADD operations *****************************************************************************/ /* Add a record. */ int ldb_map_add(struct ldb_module *module, struct ldb_request *req) { const struct ldb_message *msg = req->op.add.message; struct ldb_context *ldb; struct map_context *ac; struct ldb_message *remote_msg; int ret; ldb = ldb_module_get_ctx(module); /* Do not manipulate our control entries */ if (ldb_dn_is_special(msg->dn)) { return ldb_next_request(module, req); } /* No mapping requested (perhaps no DN mapping specified), skip to next module */ if (!ldb_dn_check_local(module, msg->dn)) { return ldb_next_request(module, req); } /* No mapping needed, fail */ if (!ldb_msg_check_remote(module, msg)) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare context and handle */ ac = map_init_context(module, req); if (ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare the local message */ ac->local_msg = ldb_msg_new(ac); if (ac->local_msg == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } ac->local_msg->dn = msg->dn; /* Prepare the remote message */ remote_msg = ldb_msg_new(ac); if (remote_msg == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); /* Split local from remote message */ ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg); /* Prepare the remote operation */ ret = ldb_build_add_req(&ac->remote_req, ldb, ac, remote_msg, req->controls, ac, map_op_remote_callback, req); LDB_REQ_SET_LOCATION(ac->remote_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } if ((ac->local_msg->num_elements == 0) || ( ! map_check_local_db(ac->module))) { /* No local data or db, just run the remote request */ return ldb_next_remote_request(ac->module, ac->remote_req); } /* Store remote DN in 'IS_MAPPED' */ /* TODO: use GUIDs here instead */ ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, remote_msg->dn); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return map_add_do_local(ac); } /* Add the local record. */ static int map_add_do_local(struct map_context *ac) { struct ldb_request *local_req; struct ldb_context *ldb; int ret; ldb = ldb_module_get_ctx(ac->module); /* Prepare the local operation */ ret = ldb_build_add_req(&local_req, ldb, ac, ac->local_msg, ac->req->controls, ac, map_op_local_callback, ac->req); LDB_REQ_SET_LOCATION(local_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(ac->module, local_req); } /***************************************************************************** * MODIFY operations *****************************************************************************/ /* Modify a record. */ int ldb_map_modify(struct ldb_module *module, struct ldb_request *req) { const struct ldb_message *msg = req->op.mod.message; struct ldb_request *search_req = NULL; struct ldb_message *remote_msg; struct ldb_context *ldb; struct map_context *ac; int ret; ldb = ldb_module_get_ctx(module); /* Do not manipulate our control entries */ if (ldb_dn_is_special(msg->dn)) { return ldb_next_request(module, req); } /* No mapping requested (perhaps no DN mapping specified), skip to next module */ if (!ldb_dn_check_local(module, msg->dn)) { return ldb_next_request(module, req); } /* No mapping needed, skip to next module */ /* TODO: What if the remote part exists, the local doesn't, * and this request wants to modify local data and thus * add the local record? */ if (!ldb_msg_check_remote(module, msg)) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare context and handle */ ac = map_init_context(module, req); if (ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare the local message */ ac->local_msg = ldb_msg_new(ac); if (ac->local_msg == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } ac->local_msg->dn = msg->dn; /* Prepare the remote message */ remote_msg = ldb_msg_new(ac->remote_req); if (remote_msg == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); /* Split local from remote message */ ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg); /* Prepare the remote operation */ ret = ldb_build_mod_req(&ac->remote_req, ldb, ac, remote_msg, req->controls, ac, map_op_remote_callback, req); LDB_REQ_SET_LOCATION(ac->remote_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } if ((ac->local_msg->num_elements == 0) || ( ! map_check_local_db(ac->module))) { /* No local data or db, just run the remote request */ return ldb_next_remote_request(ac->module, ac->remote_req); } /* prepare the search operation */ ret = map_search_self_req(&search_req, ac, msg->dn); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(module, search_req); } /* Modify the local record. */ static int map_modify_do_local(struct map_context *ac) { struct ldb_request *local_req; struct ldb_context *ldb; int ret; ldb = ldb_module_get_ctx(ac->module); if (ac->local_dn == NULL) { /* No local record present, add it instead */ /* Add local 'IS_MAPPED' */ /* TODO: use GUIDs here instead */ if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, LDB_FLAG_MOD_ADD, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, ac->remote_req->op.mod.message->dn); if (ret != 0) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare the local operation */ ret = ldb_build_add_req(&local_req, ldb, ac, ac->local_msg, ac->req->controls, ac, map_op_local_callback, ac->req); LDB_REQ_SET_LOCATION(local_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } } else { /* Prepare the local operation */ ret = ldb_build_mod_req(&local_req, ldb, ac, ac->local_msg, ac->req->controls, ac, map_op_local_callback, ac->req); LDB_REQ_SET_LOCATION(local_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } } return ldb_next_request(ac->module, local_req); } /***************************************************************************** * DELETE operations *****************************************************************************/ /* Delete a record. */ int ldb_map_delete(struct ldb_module *module, struct ldb_request *req) { struct ldb_request *search_req; struct ldb_context *ldb; struct map_context *ac; int ret; ldb = ldb_module_get_ctx(module); /* Do not manipulate our control entries */ if (ldb_dn_is_special(req->op.del.dn)) { return ldb_next_request(module, req); } /* No mapping requested (perhaps no DN mapping specified). * Skip to next module */ if (!ldb_dn_check_local(module, req->op.del.dn)) { return ldb_next_request(module, req); } /* Prepare context and handle */ ac = map_init_context(module, req); if (ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare the remote operation */ ret = ldb_build_del_req(&ac->remote_req, ldb, ac, ldb_dn_map_local(module, ac, req->op.del.dn), req->controls, ac, map_op_remote_callback, req); LDB_REQ_SET_LOCATION(ac->remote_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } /* No local db, just run the remote request */ if (!map_check_local_db(ac->module)) { /* Do the remote request. */ return ldb_next_remote_request(ac->module, ac->remote_req); } /* Prepare the search operation */ ret = map_search_self_req(&search_req, ac, req->op.del.dn); if (ret != LDB_SUCCESS) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(module, search_req); } /* Delete the local record. */ static int map_delete_do_local(struct map_context *ac) { struct ldb_request *local_req; struct ldb_context *ldb; int ret; ldb = ldb_module_get_ctx(ac->module); /* No local record, continue remotely */ if (ac->local_dn == NULL) { /* Do the remote request. */ return ldb_next_remote_request(ac->module, ac->remote_req); } /* Prepare the local operation */ ret = ldb_build_del_req(&local_req, ldb, ac, ac->req->op.del.dn, ac->req->controls, ac, map_op_local_callback, ac->req); LDB_REQ_SET_LOCATION(local_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(ac->module, local_req); } /***************************************************************************** * RENAME operations *****************************************************************************/ /* Rename a record. */ int ldb_map_rename(struct ldb_module *module, struct ldb_request *req) { struct ldb_request *search_req = NULL; struct ldb_context *ldb; struct map_context *ac; int ret; ldb = ldb_module_get_ctx(module); /* Do not manipulate our control entries */ if (ldb_dn_is_special(req->op.rename.olddn)) { return ldb_next_request(module, req); } /* No mapping requested (perhaps no DN mapping specified). * Skip to next module */ if ((!ldb_dn_check_local(module, req->op.rename.olddn)) && (!ldb_dn_check_local(module, req->op.rename.newdn))) { return ldb_next_request(module, req); } /* Rename into/out of the mapped partition requested, bail out */ if (!ldb_dn_check_local(module, req->op.rename.olddn) || !ldb_dn_check_local(module, req->op.rename.newdn)) { return LDB_ERR_AFFECTS_MULTIPLE_DSAS; } /* Prepare context and handle */ ac = map_init_context(module, req); if (ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare the remote operation */ ret = ldb_build_rename_req(&ac->remote_req, ldb, ac, ldb_dn_map_local(module, ac, req->op.rename.olddn), ldb_dn_map_local(module, ac, req->op.rename.newdn), req->controls, ac, map_op_remote_callback, req); LDB_REQ_SET_LOCATION(ac->remote_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } /* No local db, just run the remote request */ if (!map_check_local_db(ac->module)) { /* Do the remote request. */ return ldb_next_remote_request(ac->module, ac->remote_req); } /* Prepare the search operation */ ret = map_search_self_req(&search_req, ac, req->op.rename.olddn); if (ret != LDB_SUCCESS) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(module, search_req); } /* Rename the local record. */ static int map_rename_do_local(struct map_context *ac) { struct ldb_request *local_req; struct ldb_context *ldb; int ret; ldb = ldb_module_get_ctx(ac->module); /* No local record, continue remotely */ if (ac->local_dn == NULL) { /* Do the remote request. */ return ldb_next_remote_request(ac->module, ac->remote_req); } /* Prepare the local operation */ ret = ldb_build_rename_req(&local_req, ldb, ac, ac->req->op.rename.olddn, ac->req->op.rename.newdn, ac->req->controls, ac, map_rename_local_callback, ac->req); LDB_REQ_SET_LOCATION(local_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(ac->module, local_req); } static int map_rename_local_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct map_context *ac; int ret; ac = talloc_get_type(req->context, struct map_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* proceed with next step */ ret = map_rename_do_fixup(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } return LDB_SUCCESS; } /* Update the local 'IS_MAPPED' attribute. */ static int map_rename_do_fixup(struct map_context *ac) { struct ldb_request *local_req; /* Prepare the fixup operation */ /* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */ local_req = map_build_fixup_req(ac, ac->req->op.rename.newdn, ac->remote_req->op.rename.newdn, ac, map_op_local_callback); if (local_req == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(ac->module, local_req); } ldb-2.0.8/ldb_map/ldb_map_outbound.c0000660000000000000000000010716513573675413017325 0ustar rootroot00000000000000/* ldb database mapping module Copyright (C) Jelmer Vernooij 2005 Copyright (C) Martin Kuehl 2006 Copyright (C) Andrew Bartlett 2006 Copyright (C) Simo Sorce 2008 ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_map.h" #include "ldb_map_private.h" /* Mapping attributes * ================== */ /* Select attributes that stay in the local partition. */ static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs) { const struct ldb_map_context *data = map_get_context(module); const char **result; unsigned int i, last; if (attrs == NULL) return NULL; last = 0; result = talloc_array(mem_ctx, const char *, 1); if (result == NULL) { goto failed; } result[0] = NULL; for (i = 0; attrs[i]; i++) { /* Wildcards and ignored attributes are kept locally */ if ((ldb_attr_cmp(attrs[i], "*") == 0) || (!map_attr_check_remote(data, attrs[i]))) { result = talloc_realloc(mem_ctx, result, const char *, last+2); if (result == NULL) { goto failed; } result[last] = talloc_strdup(result, attrs[i]); result[last+1] = NULL; last++; } } return result; failed: talloc_free(result); map_oom(module); return NULL; } /* Collect attributes that are mapped into the remote partition. */ static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, const char * const *attrs) { const struct ldb_map_context *data = map_get_context(module); const char **result; const struct ldb_map_attribute *map; const char *name=NULL; unsigned int i, j, last; int ret; last = 0; result = talloc_array(mem_ctx, const char *, 1); if (result == NULL) { goto failed; } result[0] = NULL; for (i = 0; attrs[i]; i++) { /* Wildcards are kept remotely, too */ if (ldb_attr_cmp(attrs[i], "*") == 0) { const char **new_attrs = NULL; ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs); if (ret != LDB_SUCCESS) { goto failed; } ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes); if (ret != LDB_SUCCESS) { goto failed; } attrs = new_attrs; break; } } for (i = 0; attrs[i]; i++) { /* Wildcards are kept remotely, too */ if (ldb_attr_cmp(attrs[i], "*") == 0) { /* Add all 'include in wildcard' attributes */ name = attrs[i]; goto named; } /* Add remote names of mapped attrs */ map = map_attr_find_local(data, attrs[i]); if (map == NULL) { continue; } switch (map->type) { case LDB_MAP_IGNORE: continue; case LDB_MAP_KEEP: name = attrs[i]; goto named; case LDB_MAP_RENAME: case LDB_MAP_RENDROP: case LDB_MAP_CONVERT: name = map->u.rename.remote_name; goto named; case LDB_MAP_GENERATE: /* Add all remote names of "generate" attrs */ for (j = 0; map->u.generate.remote_names[j]; j++) { result = talloc_realloc(mem_ctx, result, const char *, last+2); if (result == NULL) { goto failed; } result[last] = talloc_strdup(result, map->u.generate.remote_names[j]); result[last+1] = NULL; last++; } continue; } named: /* We found a single remote name, add that */ result = talloc_realloc(mem_ctx, result, const char *, last+2); if (result == NULL) { goto failed; } result[last] = talloc_strdup(result, name); result[last+1] = NULL; last++; } return result; failed: talloc_free(result); map_oom(module); return NULL; } /* Split attributes that stay in the local partition from those that * are mapped into the remote partition. */ static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs) { *local_attrs = map_attrs_select_local(module, mem_ctx, attrs); *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs); return 0; } /* Mapping message elements * ======================== */ /* Add an element to a message, overwriting any old identically named elements. */ static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el) { struct ldb_message_element *old; unsigned j; old = ldb_msg_find_element(msg, el->name); /* no local result, add as new element */ if (old == NULL) { if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) { return LDB_ERR_OPERATIONS_ERROR; } } else { talloc_free(old->values); } old->values = talloc_array(msg->elements, struct ldb_val, el->num_values); old->num_values = el->num_values; if (old->values == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* copy the values into the element */ for (j=0;jnum_values;j++) { old->values[j] = ldb_val_dup(old->values, &el->values[j]); if (old->values[j].data == NULL && el->values[j].length != 0) { return LDB_ERR_OPERATIONS_ERROR; } } return 0; } /* Map a message element back into the local partition. */ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const char *attr_name, const struct ldb_message_element *old) { const struct ldb_map_context *data = map_get_context(module); const char *local_attr_name = attr_name; struct ldb_message_element *el; unsigned int i; el = talloc_zero(mem_ctx, struct ldb_message_element); if (el == NULL) { map_oom(module); return NULL; } el->values = talloc_array(el, struct ldb_val, old->num_values); if (el->values == NULL) { talloc_free(el); map_oom(module); return NULL; } for (i = 0; data->attribute_maps[i].local_name; i++) { struct ldb_map_attribute *am = &data->attribute_maps[i]; if (((am->type == LDB_MAP_RENAME || am->type == LDB_MAP_RENDROP) && !strcmp(am->u.rename.remote_name, attr_name)) || (am->type == LDB_MAP_CONVERT && !strcmp(am->u.convert.remote_name, attr_name))) { local_attr_name = am->local_name; break; } } el->name = talloc_strdup(el, local_attr_name); if (el->name == NULL) { talloc_free(el); map_oom(module); return NULL; } for (i = 0; i < old->num_values; i++) { el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]); /* Conversions might fail, in which case bail */ if (!el->values[i].data) { talloc_free(el); return NULL; } el->num_values++; } return el; } /* Merge a remote message element into a local message. */ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const char *attr_name) { const struct ldb_map_context *data = map_get_context(module); const struct ldb_map_attribute *map; struct ldb_message_element *old, *el=NULL; const char *remote_name = NULL; struct ldb_context *ldb; ldb = ldb_module_get_ctx(module); /* We handle wildcards in ldb_msg_el_merge_wildcard */ if (ldb_attr_cmp(attr_name, "*") == 0) { return LDB_SUCCESS; } map = map_attr_find_local(data, attr_name); /* Unknown attribute in remote message: * skip, attribute was probably auto-generated */ if (map == NULL) { return LDB_SUCCESS; } switch (map->type) { case LDB_MAP_IGNORE: break; case LDB_MAP_CONVERT: remote_name = map->u.convert.remote_name; break; case LDB_MAP_KEEP: remote_name = attr_name; break; case LDB_MAP_RENAME: case LDB_MAP_RENDROP: remote_name = map->u.rename.remote_name; break; case LDB_MAP_GENERATE: break; } switch (map->type) { case LDB_MAP_IGNORE: return LDB_SUCCESS; case LDB_MAP_CONVERT: if (map->u.convert.convert_remote == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "Skipping attribute '%s': " "'convert_remote' not set", attr_name); return LDB_SUCCESS; } FALL_THROUGH; case LDB_MAP_KEEP: case LDB_MAP_RENAME: case LDB_MAP_RENDROP: old = ldb_msg_find_element(remote, remote_name); if (old) { el = ldb_msg_el_map_remote(module, local, map, attr_name, old); } else { return LDB_ERR_NO_SUCH_ATTRIBUTE; } break; case LDB_MAP_GENERATE: if (map->u.generate.generate_local == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "Skipping attribute '%s': " "'generate_local' not set", attr_name); return LDB_SUCCESS; } el = map->u.generate.generate_local(module, local, attr_name, remote); if (!el) { /* Generation failure is probably due to lack of source attributes */ return LDB_ERR_NO_SUCH_ATTRIBUTE; } break; } if (el == NULL) { return LDB_ERR_NO_SUCH_ATTRIBUTE; } return ldb_msg_replace(local, el); } /* Handle wildcard parts of merging a remote message element into a local message. */ static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote) { const struct ldb_map_context *data = map_get_context(module); const struct ldb_map_attribute *map = map_attr_find_local(data, "*"); struct ldb_message_element *el=NULL; unsigned int i; int ret; /* Perhaps we have a mapping for "*" */ if (map && map->type == LDB_MAP_KEEP) { /* We copy everything over, and hope that anything with a more specific rule is overwritten */ for (i = 0; i < remote->num_elements; i++) { el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name, &remote->elements[i]); if (el == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_msg_replace(local, el); if (ret) { return ret; } } } /* Now walk the list of possible mappings, and apply each */ for (i = 0; data->attribute_maps[i].local_name; i++) { ret = ldb_msg_el_merge(module, local, remote, data->attribute_maps[i].local_name); if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { continue; } else if (ret) { return ret; } else { continue; } } return LDB_SUCCESS; } /* Mapping messages * ================ */ /* Merge two local messages into a single one. */ static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2) { unsigned int i; int ret; for (i = 0; i < msg2->num_elements; i++) { ret = ldb_msg_replace(msg1, &msg2->elements[i]); if (ret) { return ret; } } return LDB_SUCCESS; } /* Merge a local and a remote message into a single local one. */ static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, struct ldb_message *remote) { unsigned int i; int ret; const char * const *attrs = ac->all_attrs; if (!attrs) { ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); if (ret) { return ret; } } for (i = 0; attrs && attrs[i]; i++) { if (ldb_attr_cmp(attrs[i], "*") == 0) { ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); if (ret) { return ret; } break; } } /* Try to map each attribute back; * Add to local message is possible, * Overwrite old local attribute if necessary */ for (i = 0; attrs && attrs[i]; i++) { ret = ldb_msg_el_merge(ac->module, local, remote, attrs[i]); if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { } else if (ret) { return ret; } } return LDB_SUCCESS; } /* Mapping search results * ====================== */ /* Map a search result back into the local partition. */ static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares) { struct ldb_message *msg; struct ldb_dn *dn; int ret; /* There is no result message, skip */ if (ares->type != LDB_REPLY_ENTRY) { return 0; } /* Create a new result message */ msg = ldb_msg_new(ares); if (msg == NULL) { map_oom(ac->module); return LDB_ERR_OPERATIONS_ERROR; } /* Merge remote message into new message */ ret = ldb_msg_merge_remote(ac, msg, ares->message); if (ret) { talloc_free(msg); return ret; } /* Create corresponding local DN */ dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn); if (dn == NULL) { talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } msg->dn = dn; /* Store new message with new DN as the result */ talloc_free(ares->message); ares->message = msg; return 0; } /* Mapping parse trees * =================== */ /* Check whether a parse tree can safely be split in two. */ static bool ldb_parse_tree_check_splittable(const struct ldb_parse_tree *tree) { const struct ldb_parse_tree *subtree = tree; bool negate = false; while (subtree) { switch (subtree->operation) { case LDB_OP_NOT: negate = !negate; subtree = subtree->u.isnot.child; continue; case LDB_OP_AND: return !negate; /* if negate: False */ case LDB_OP_OR: return negate; /* if negate: True */ default: return true; /* simple parse tree */ } } return true; /* no parse tree */ } /* Collect a list of attributes required to match a given parse tree. */ static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx, const char ***attrs, const struct ldb_parse_tree *tree) { const char **new_attrs; unsigned int i; int ret; if (tree == NULL) { return 0; } switch (tree->operation) { case LDB_OP_OR: case LDB_OP_AND: /* attributes stored in list of subtrees */ for (i = 0; i < tree->u.list.num_elements; i++) { ret = ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.list.elements[i]); if (ret) { return ret; } } return 0; case LDB_OP_NOT: /* attributes stored in single subtree */ return ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.isnot.child); default: /* single attribute in tree */ new_attrs = ldb_attr_list_copy_add(mem_ctx, *attrs, tree->u.equality.attr); talloc_free(*attrs); *attrs = new_attrs; return 0; } } static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); /* Select a negated subtree that queries attributes in the local partition */ static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { struct ldb_parse_tree *child; int ret; /* Prepare new tree */ *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); if (*new == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* Generate new subtree */ ret = map_subtree_select_local(module, *new, &child, tree->u.isnot.child); if (ret) { talloc_free(*new); return ret; } /* Prune tree without subtree */ if (child == NULL) { talloc_free(*new); *new = NULL; return 0; } (*new)->u.isnot.child = child; return ret; } /* Select a list of subtrees that query attributes in the local partition */ static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { unsigned int i, j; int ret=0; /* Prepare new tree */ *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); if (*new == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* Prepare list of subtrees */ (*new)->u.list.num_elements = 0; (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); if ((*new)->u.list.elements == NULL) { map_oom(module); talloc_free(*new); return LDB_ERR_OPERATIONS_ERROR; } /* Generate new list of subtrees */ j = 0; for (i = 0; i < tree->u.list.num_elements; i++) { struct ldb_parse_tree *child = NULL; ret = map_subtree_select_local(module, *new, &child, tree->u.list.elements[i]); if (ret) { talloc_free(*new); return ret; } if (child) { (*new)->u.list.elements[j] = child; j++; } } /* Prune tree without subtrees */ if (j == 0) { talloc_free(*new); *new = NULL; return 0; } /* Fix subtree list size */ (*new)->u.list.num_elements = j; (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); return ret; } /* Select a simple subtree that queries attributes in the local partition */ static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { /* Prepare new tree */ *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); if (*new == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } return 0; } /* Select subtrees that query attributes in the local partition */ static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { const struct ldb_map_context *data = map_get_context(module); if (tree == NULL) { return 0; } if (tree->operation == LDB_OP_NOT) { return map_subtree_select_local_not(module, mem_ctx, new, tree); } if (tree->operation == LDB_OP_AND || tree->operation == LDB_OP_OR) { return map_subtree_select_local_list(module, mem_ctx, new, tree); } if (map_attr_check_remote(data, tree->u.equality.attr)) { *new = NULL; return 0; } return map_subtree_select_local_simple(module, mem_ctx, new, tree); } static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); /* Collect a negated subtree that queries attributes in the remote partition */ static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { struct ldb_parse_tree *child; int ret; /* Prepare new tree */ *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); if (*new == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* Generate new subtree */ ret = map_subtree_collect_remote(module, *new, &child, tree->u.isnot.child); if (ret) { talloc_free(*new); return ret; } /* Prune tree without subtree */ if (child == NULL) { talloc_free(*new); *new = NULL; return 0; } (*new)->u.isnot.child = child; return ret; } /* Collect a list of subtrees that query attributes in the remote partition */ static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { unsigned int i, j; int ret=0; /* Prepare new tree */ *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); if (*new == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* Prepare list of subtrees */ (*new)->u.list.num_elements = 0; (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); if ((*new)->u.list.elements == NULL) { map_oom(module); talloc_free(*new); return LDB_ERR_OPERATIONS_ERROR; } /* Generate new list of subtrees */ j = 0; for (i = 0; i < tree->u.list.num_elements; i++) { struct ldb_parse_tree *child; ret = map_subtree_collect_remote(module, *new, &child, tree->u.list.elements[i]); if (ret) { talloc_free(*new); return ret; } if (child) { (*new)->u.list.elements[j] = child; j++; } } /* Prune tree without subtrees */ if (j == 0) { talloc_free(*new); *new = NULL; return 0; } /* Fix subtree list size */ (*new)->u.list.num_elements = j; (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); return ret; } /* Collect a simple subtree that queries attributes in the remote partition */ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map) { const char *attr; /* Prepare new tree */ *new = talloc(mem_ctx, struct ldb_parse_tree); if (*new == NULL) { map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } **new = *tree; if (map->type == LDB_MAP_KEEP) { /* Nothing to do here */ return 0; } /* Store attribute and value in new tree */ switch (tree->operation) { case LDB_OP_PRESENT: attr = map_attr_map_local(*new, map, tree->u.present.attr); (*new)->u.present.attr = attr; break; case LDB_OP_SUBSTRING: { attr = map_attr_map_local(*new, map, tree->u.substring.attr); (*new)->u.substring.attr = attr; break; } case LDB_OP_EQUALITY: attr = map_attr_map_local(*new, map, tree->u.equality.attr); (*new)->u.equality.attr = attr; break; case LDB_OP_LESS: case LDB_OP_GREATER: case LDB_OP_APPROX: attr = map_attr_map_local(*new, map, tree->u.comparison.attr); (*new)->u.comparison.attr = attr; break; case LDB_OP_EXTENDED: attr = map_attr_map_local(*new, map, tree->u.extended.attr); (*new)->u.extended.attr = attr; break; default: /* unknown kind of simple subtree */ talloc_free(*new); return LDB_ERR_OPERATIONS_ERROR; } if (attr == NULL) { talloc_free(*new); *new = NULL; return 0; } if (map->type == LDB_MAP_RENAME || map->type == LDB_MAP_RENDROP) { /* Nothing more to do here, the attribute has been renamed */ return 0; } /* Store attribute and value in new tree */ switch (tree->operation) { case LDB_OP_PRESENT: break; case LDB_OP_SUBSTRING: { int i; /* Map value */ (*new)->u.substring.chunks = NULL; for (i=0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) { (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2); if (!(*new)->u.substring.chunks) { talloc_free(*new); *new = NULL; return 0; } (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val); if (!(*new)->u.substring.chunks[i]) { talloc_free(*new); *new = NULL; return 0; } *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]); (*new)->u.substring.chunks[i+1] = NULL; } break; } case LDB_OP_EQUALITY: (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value); break; case LDB_OP_LESS: case LDB_OP_GREATER: case LDB_OP_APPROX: (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value); break; case LDB_OP_EXTENDED: (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value); (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); break; default: /* unknown kind of simple subtree */ talloc_free(*new); return LDB_ERR_OPERATIONS_ERROR; } return 0; } /* Collect subtrees that query attributes in the remote partition */ static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { const struct ldb_map_context *data = map_get_context(module); const struct ldb_map_attribute *map; struct ldb_context *ldb; ldb = ldb_module_get_ctx(module); if (tree == NULL) { return 0; } if (tree->operation == LDB_OP_NOT) { return map_subtree_collect_remote_not(module, mem_ctx, new, tree); } if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) { return map_subtree_collect_remote_list(module, mem_ctx, new, tree); } if (!map_attr_check_remote(data, tree->u.equality.attr)) { *new = NULL; return 0; } map = map_attr_find_local(data, tree->u.equality.attr); if (map == NULL) { return LDB_ERR_OPERATIONS_ERROR; } if (map->convert_operator) { return map->convert_operator(module, mem_ctx, new, tree); } if (map->type == LDB_MAP_GENERATE) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Skipping attribute '%s': " "'convert_operator' not set", tree->u.equality.attr); *new = NULL; return 0; } return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map); } /* Split subtrees that query attributes in the local partition from * those that query the remote partition. */ static int ldb_parse_tree_partition(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **local_tree, struct ldb_parse_tree **remote_tree, const struct ldb_parse_tree *tree) { int ret; *local_tree = NULL; *remote_tree = NULL; /* No original tree */ if (tree == NULL) { return 0; } /* Generate local tree */ ret = map_subtree_select_local(module, mem_ctx, local_tree, tree); if (ret) { return ret; } /* Generate remote tree */ ret = map_subtree_collect_remote(module, mem_ctx, remote_tree, tree); if (ret) { talloc_free(*local_tree); return ret; } return 0; } /* Collect a list of attributes required either explicitly from a * given list or implicitly from a given parse tree; split the * collected list into local and remote parts. */ static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac, const char * const *search_attrs, const struct ldb_parse_tree *tree) { void *tmp_ctx; const char **tree_attrs; const char **remote_attrs; const char **local_attrs; int ret; /* There is no tree, just partition the searched attributes */ if (tree == NULL) { ret = map_attrs_partition(module, ac, &local_attrs, &remote_attrs, search_attrs); if (ret == 0) { ac->local_attrs = local_attrs; ac->remote_attrs = remote_attrs; ac->all_attrs = search_attrs; } return ret; } /* Create context for temporary memory */ tmp_ctx = talloc_new(ac); if (tmp_ctx == NULL) { goto oom; } /* Prepare list of attributes from tree */ tree_attrs = talloc_array(tmp_ctx, const char *, 1); if (tree_attrs == NULL) { talloc_free(tmp_ctx); goto oom; } tree_attrs[0] = NULL; /* Collect attributes from tree */ ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree); if (ret) { goto done; } /* Merge attributes from search operation */ ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs); if (ret) { goto done; } /* Split local from remote attributes */ ret = map_attrs_partition(module, ac, &local_attrs, &remote_attrs, tree_attrs); if (ret == 0) { ac->local_attrs = local_attrs; ac->remote_attrs = remote_attrs; talloc_steal(ac, tree_attrs); ac->all_attrs = tree_attrs; } done: /* Free temporary memory */ talloc_free(tmp_ctx); return ret; oom: map_oom(module); return LDB_ERR_OPERATIONS_ERROR; } /* Outbound requests: search * ========================= */ static int map_remote_search_callback(struct ldb_request *req, struct ldb_reply *ares); static int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares); static int map_search_local(struct map_context *ac); static int map_save_entry(struct map_context *ac, struct ldb_reply *ares) { struct map_reply *mr; mr = talloc_zero(ac, struct map_reply); if (mr == NULL) { map_oom(ac->module); return LDB_ERR_OPERATIONS_ERROR; } mr->remote = talloc_steal(mr, ares); if (ac->r_current) { ac->r_current->next = mr; } else { /* first entry */ ac->r_list = mr; } ac->r_current = mr; return LDB_SUCCESS; } /* Pass a merged search result up the callback chain. */ int map_return_entry(struct map_context *ac, struct ldb_reply *ares) { struct ldb_message_element *el; const char * const *attrs; struct ldb_context *ldb; unsigned int i; int ret; bool matched; ldb = ldb_module_get_ctx(ac->module); /* Merged result doesn't match original query, skip */ ret = ldb_match_msg_error(ldb, ares->message, ac->req->op.search.tree, ac->req->op.search.base, ac->req->op.search.scope, &matched); if (ret != LDB_SUCCESS) return ret; if (!matched) { ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " "Skipping record '%s': " "doesn't match original search", ldb_dn_get_linearized(ares->message->dn)); return LDB_SUCCESS; } /* Limit result to requested attrs */ if (ac->req->op.search.attrs && (! ldb_attr_in_list(ac->req->op.search.attrs, "*"))) { attrs = ac->req->op.search.attrs; i = 0; while (i < ares->message->num_elements) { el = &ares->message->elements[i]; if ( ! ldb_attr_in_list(attrs, el->name)) { ldb_msg_remove_element(ares->message, el); } else { i++; } } } return ldb_module_send_entry(ac->req, ares->message, ares->controls); } /* Search a record. */ int ldb_map_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_parse_tree *remote_tree; struct ldb_parse_tree *local_tree; struct ldb_request *remote_req; struct ldb_context *ldb; struct map_context *ac; int ret; const char *wildcard[] = { "*", NULL }; const char * const *attrs; ldb = ldb_module_get_ctx(module); /* if we're not yet initialized, go to the next module */ if (!ldb_module_get_private(module)) return ldb_next_request(module, req); /* Do not manipulate our control entries */ if (ldb_dn_is_special(req->op.search.base)) { return ldb_next_request(module, req); } /* No mapping requested, skip to next module */ if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) { return ldb_next_request(module, req); } /* TODO: How can we be sure about which partition we are * targetting when there is no search base? */ /* Prepare context and handle */ ac = map_init_context(module, req); if (ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* It is easier to deal with the two different ways of * expressing the wildcard in the same codepath */ attrs = req->op.search.attrs; if (attrs == NULL) { attrs = wildcard; } /* Split local from remote attrs */ ret = map_attrs_collect_and_partition(module, ac, attrs, req->op.search.tree); if (ret) { return LDB_ERR_OPERATIONS_ERROR; } /* Split local from remote tree */ ret = ldb_parse_tree_partition(module, ac, &local_tree, &remote_tree, req->op.search.tree); if (ret) { return LDB_ERR_OPERATIONS_ERROR; } if (((local_tree != NULL) && (remote_tree != NULL)) && (!ldb_parse_tree_check_splittable(req->op.search.tree))) { /* The query can't safely be split, enumerate the remote partition */ local_tree = NULL; remote_tree = NULL; } if (local_tree == NULL) { /* Construct default local parse tree */ local_tree = talloc_zero(ac, struct ldb_parse_tree); if (local_tree == NULL) { map_oom(ac->module); return LDB_ERR_OPERATIONS_ERROR; } local_tree->operation = LDB_OP_PRESENT; local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED); } if (remote_tree == NULL) { /* Construct default remote parse tree */ remote_tree = ldb_parse_tree(ac, NULL); if (remote_tree == NULL) { return LDB_ERR_OPERATIONS_ERROR; } } ac->local_tree = local_tree; /* Prepare the remote operation */ ret = ldb_build_search_req_ex(&remote_req, ldb, ac, req->op.search.base, req->op.search.scope, remote_tree, ac->remote_attrs, req->controls, ac, map_remote_search_callback, req); LDB_REQ_SET_LOCATION(remote_req); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_remote_request(module, remote_req); } /* Now, search the local part of a remote search result. */ static int map_remote_search_callback(struct ldb_request *req, struct ldb_reply *ares) { struct map_context *ac; int ret; ac = talloc_get_type(req->context, struct map_context); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_REFERRAL: /* ignore referrals */ talloc_free(ares); return LDB_SUCCESS; case LDB_REPLY_ENTRY: /* Map result record into a local message */ ret = map_reply_remote(ac, ares); if (ret) { talloc_free(ares); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* if we have no local db, then we can just return the reply to * the upper layer, otherwise we must save it and process it * when all replies ahve been gathered */ if ( ! map_check_local_db(ac->module)) { ret = map_return_entry(ac, ares); } else { ret = map_save_entry(ac,ares); } if (ret != LDB_SUCCESS) { talloc_free(ares); return ldb_module_done(ac->req, NULL, NULL, ret); } break; case LDB_REPLY_DONE: if ( ! map_check_local_db(ac->module)) { return ldb_module_done(ac->req, ares->controls, ares->response, LDB_SUCCESS); } /* reset the pointer to the start of the list */ ac->r_current = ac->r_list; /* no entry just return */ if (ac->r_current == NULL) { ret = ldb_module_done(ac->req, ares->controls, ares->response, LDB_SUCCESS); talloc_free(ares); return ret; } ac->remote_done_ares = talloc_steal(ac, ares); ret = map_search_local(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } } return LDB_SUCCESS; } static int map_search_local(struct map_context *ac) { struct ldb_request *search_req; if (ac->r_current == NULL || ac->r_current->remote == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* Prepare local search request */ /* TODO: use GUIDs here instead? */ search_req = map_search_base_req(ac, ac->r_current->remote->message->dn, NULL, NULL, ac, map_local_merge_callback); if (search_req == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(ac->module, search_req); } /* Merge the remote and local parts of a search result. */ int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct map_context *ac; int ret; ac = talloc_get_type(req->context, struct map_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: /* We have already found a local record */ if (ac->r_current->local) { talloc_free(ares); ldb_set_errstring(ldb, "ldb_map: Too many results!"); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* Store local result */ ac->r_current->local = talloc_steal(ac->r_current, ares); break; case LDB_REPLY_REFERRAL: /* ignore referrals */ talloc_free(ares); break; case LDB_REPLY_DONE: /* We don't need the local 'ares', but we will use the remote one from below */ talloc_free(ares); /* No local record found, map and send remote record */ if (ac->r_current->local != NULL) { /* Merge remote into local message */ ret = ldb_msg_merge_local(ac->module, ac->r_current->local->message, ac->r_current->remote->message); if (ret == LDB_SUCCESS) { ret = map_return_entry(ac, ac->r_current->local); } if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } else { ret = map_return_entry(ac, ac->r_current->remote); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } } if (ac->r_current->next != NULL) { ac->r_current = ac->r_current->next; if (ac->r_current->remote->type == LDB_REPLY_ENTRY) { ret = map_search_local(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } break; } } /* ok we are done with all search, finally it is time to * finish operations for this module */ return ldb_module_done(ac->req, ac->remote_done_ares->controls, ac->remote_done_ares->response, ac->remote_done_ares->error); } return LDB_SUCCESS; } ldb-2.0.8/ldb_map/ldb_map_private.h0000660000000000000000000000721112406075657017132 0ustar rootroot00000000000000#include "replace.h" #include "system/filesys.h" #include "system/time.h" /* A handy macro to report Out of Memory conditions */ #define map_oom(module) ldb_set_errstring(ldb_module_get_ctx(module), talloc_asprintf(module, "Out of Memory")); /* The type of search callback functions */ typedef int (*ldb_map_callback_t)(struct ldb_request *, struct ldb_reply *); /* The special DN from which the local and remote base DNs are fetched */ #define MAP_DN_NAME "@MAP" #define MAP_DN_FROM "@FROM" #define MAP_DN_TO "@TO" /* Private data structures * ======================= */ struct map_reply { struct map_reply *next; struct ldb_reply *remote; struct ldb_reply *local; }; /* Context data for mapped requests */ struct map_context { struct ldb_module *module; struct ldb_request *req; struct ldb_dn *local_dn; const struct ldb_parse_tree *local_tree; const char * const *local_attrs; const char * const *remote_attrs; const char * const *all_attrs; struct ldb_message *local_msg; struct ldb_request *remote_req; struct map_reply *r_list; struct map_reply *r_current; /* The response continaing any controls the remote server gave */ struct ldb_reply *remote_done_ares; }; /* Common operations * ================= */ /* The following definitions come from lib/ldb/modules/ldb_map.c */ const struct ldb_map_context *map_get_context(struct ldb_module *module); struct map_context *map_init_context(struct ldb_module *module, struct ldb_request *req); int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request); bool map_check_local_db(struct ldb_module *module); bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr); bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn); const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name); const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name); const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs); struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback); struct ldb_request *map_build_fixup_req(struct map_context *ac, struct ldb_dn *olddn, struct ldb_dn *newdn, void *context, ldb_map_callback_t callback); int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map); int map_return_fatal_error(struct ldb_request *req, struct ldb_reply *ares); int map_return_normal_error(struct ldb_request *req, struct ldb_reply *ares, int error); int map_return_entry(struct map_context *ac, struct ldb_reply *ares); ldb-2.0.8/ldb_mdb/ldb_mdb.c0000660000000000000000000006305213573675413015354 0ustar rootroot00000000000000/* 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 . */ #include "ldb_mdb.h" #include "../ldb_key_value/ldb_kv.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; #ifdef EBADE case EBADE: #endif 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 ldb_kv_private *ldb_kv) { return ldb_kv->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 ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val data, int flags) { struct lmdb_private *lmdb = ldb_kv->lmdb_private; MDB_val mdb_key; MDB_val mdb_data; int mdb_flags; MDB_txn *txn = NULL; MDB_dbi dbi = 0; if (ldb_kv->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 ldb_kv_private *ldb_kv, struct ldb_val key) { struct lmdb_private *lmdb = ldb_kv->lmdb_private; MDB_val mdb_key; MDB_txn *txn = NULL; MDB_dbi dbi = 0; if (ldb_kv->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 ldb_kv_private *ldb_kv, ldb_kv_traverse_fn fn, void *ctx) { struct lmdb_private *lmdb = ldb_kv->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(ldb_kv, key, data, ctx); if (ret != 0) { /* * NOTE: This DOES NOT set lmdb->error! * * This means that the caller will get success. * This matches TDB traverse behaviour, where callbacks * may terminate the traverse, but do not change the * return code from success. * * Callers SHOULD store their own error codes. */ 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 ldb_kv_private *ldb_kv, struct ldb_val key, struct ldb_val key2, struct ldb_val data, void *state) { struct lmdb_private *lmdb = ldb_kv->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(ldb_kv, data.data, data.length); if (copy.data == NULL) { lmdb->error = MDB_PANIC; return ldb_oom(lmdb->ldb); } lmdb->error = lmdb_delete(ldb_kv, 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(ldb_kv, 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 ldb_kv_private *ldb_kv, struct ldb_val key, int (*parser)(struct ldb_val key, struct ldb_val data, void *private_data), void *ctx) { struct lmdb_private *lmdb = ldb_kv->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); } /* * Exactly the same as iterate, except we have a start key and an end key * (which are both included in the results if present). * * If start > end, return MDB_PANIC. */ static int lmdb_iterate_range(struct ldb_kv_private *ldb_kv, struct ldb_val start_key, struct ldb_val end_key, ldb_kv_traverse_fn fn, void *ctx) { struct lmdb_private *lmdb = ldb_kv->lmdb_private; MDB_val mdb_key; MDB_val mdb_data; MDB_txn *txn = NULL; MDB_dbi dbi = 0; MDB_cursor *cursor = NULL; int ret; MDB_val mdb_s_key; MDB_val mdb_e_key; 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); } mdb_s_key.mv_size = start_key.length; mdb_s_key.mv_data = start_key.data; mdb_e_key.mv_size = end_key.length; mdb_e_key.mv_data = end_key.data; if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) { lmdb->error = MDB_PANIC; return ldb_mdb_error(lmdb->ldb, lmdb->error); } lmdb->error = mdb_cursor_open(txn, dbi, &cursor); if (lmdb->error != MDB_SUCCESS) { goto done; } lmdb->error = mdb_cursor_get(cursor, &mdb_s_key, &mdb_data, MDB_SET_RANGE); if (lmdb->error != MDB_SUCCESS) { if (lmdb->error == MDB_NOTFOUND) { lmdb->error = MDB_SUCCESS; } goto done; } else { struct ldb_val key = { .length = mdb_s_key.mv_size, .data = mdb_s_key.mv_data, }; struct ldb_val data = { .length = mdb_data.mv_size, .data = mdb_data.mv_data, }; if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) { goto done; } ret = fn(ldb_kv, key, data, ctx); if (ret != 0) { /* * NOTE: This DOES NOT set lmdb->error! * * This means that the caller will get success. * This matches TDB traverse behaviour, where callbacks * may terminate the traverse, but do not change the * return code from success. * * Callers SHOULD store their own error codes. */ 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, }; if (mdb_cmp(txn, dbi, &mdb_key, &mdb_e_key) > 0) { goto done; } ret = fn(ldb_kv, key, data, ctx); if (ret != 0) { /* * NOTE: This DOES NOT set lmdb->error! * * This means that the caller will get success. * This matches TDB traverse behaviour, where callbacks * may terminate the traverse, but do not change the * return code from success. * * Callers SHOULD store their own error codes. */ 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_lock_read(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); struct lmdb_private *lmdb = ldb_kv->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(ldb_kv) == false && ldb_kv->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); } ldb_kv->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 ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); if (lmdb_transaction_active(ldb_kv) == false && ldb_kv->read_lock_count == 1) { struct lmdb_private *lmdb = ldb_kv->lmdb_private; mdb_txn_commit(lmdb->read_txn); lmdb->read_txn = NULL; ldb_kv->read_lock_count--; return LDB_SUCCESS; } ldb_kv->read_lock_count--; return LDB_SUCCESS; } static int lmdb_transaction_start(struct ldb_kv_private *ldb_kv) { struct lmdb_private *lmdb = ldb_kv->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 (ldb_kv->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, <x->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 ldb_kv_private *ldb_kv) { struct lmdb_trans *ltx; struct lmdb_private *lmdb = ldb_kv->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 ldb_kv_private *ldb_kv) { /* No need to prepare a commit */ return LDB_SUCCESS; } static int lmdb_transaction_commit(struct ldb_kv_private *ldb_kv) { struct lmdb_trans *ltx; struct lmdb_private *lmdb = ldb_kv->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 ldb_kv_private *ldb_kv) { return ldb_mdb_err_map(ldb_kv->lmdb_private->error); } static const char *lmdb_errorstr(struct ldb_kv_private *ldb_kv) { return mdb_strerror(ldb_kv->lmdb_private->error); } static const char *lmdb_name(struct ldb_kv_private *ldb_kv) { return "lmdb"; } static bool lmdb_changed(struct ldb_kv_private *ldb_kv) { /* * 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; } /* * Get the number of records in the database. * * The mdb_env_stat call returns an accurate count, so we return the actual * number of records in the database rather than an estimate. */ static size_t lmdb_get_size(struct ldb_kv_private *ldb_kv) { struct MDB_stat stats = {0}; struct lmdb_private *lmdb = ldb_kv->lmdb_private; int ret = 0; ret = mdb_env_stat(lmdb->env, &stats); if (ret != 0) { return 0; } return stats.ms_entries; } /* * Start a sub transaction * As lmdb supports nested transactions we can start a new transaction */ static int lmdb_nested_transaction_start(struct ldb_kv_private *ldb_kv) { int ret = lmdb_transaction_start(ldb_kv); return ret; } /* * Commit a sub transaction * As lmdb supports nested transactions we can commit the nested transaction */ static int lmdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv) { int ret = lmdb_transaction_commit(ldb_kv); return ret; } /* * Cancel a sub transaction * As lmdb supports nested transactions we can cancel the nested transaction */ static int lmdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv) { int ret = lmdb_transaction_cancel(ldb_kv); return ret; } static struct kv_db_ops lmdb_key_value_ops = { .options = LDB_KV_OPTION_STABLE_READ_LOCK, .store = lmdb_store, .delete = lmdb_delete, .iterate = lmdb_traverse_fn, .update_in_iterate = lmdb_update_in_iterate, .fetch_and_parse = lmdb_parse_record, .iterate_range = lmdb_iterate_range, .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, .get_size = lmdb_get_size, .begin_nested_write = lmdb_nested_transaction_start, .finish_nested_write = lmdb_nested_transaction_commit, .abort_nested_write = lmdb_nested_transaction_cancel, }; 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, const size_t env_map_size, unsigned int flags) { int ret; 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); } if (env_map_size > 0) { ret = mdb_env_set_mapsize(*env, env_map_size); if (ret != 0) { ldb_asprintf_errstring( ldb, "Could not set MDB mmap() size to %llu " "on %s: %s\n", (unsigned long long)(env_map_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); } { MDB_envinfo stat = {0}; ret = mdb_env_info (*env, &stat); if (ret != 0) { ldb_asprintf_errstring( ldb, "Could not get MDB environment stats %s: %s\n", path, mdb_strerror(ret)); 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); if (v == -1) { TALLOC_FREE(w); return LDB_ERR_OPERATIONS_ERROR; } ret = fcntl(fd, F_SETFD, v | FD_CLOEXEC); if (ret == -1) { TALLOC_FREE(w); return LDB_ERR_OPERATIONS_ERROR; } 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, const size_t env_map_size, 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, env_map_size, 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 ldb_kv_private *ldb_kv = NULL; int ret; size_t env_map_size = 0; /* * 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; } ldb_kv = talloc_zero(ldb, struct ldb_kv_private); if (!ldb_kv) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } lmdb = talloc_zero(ldb_kv, struct lmdb_private); if (lmdb == NULL) { TALLOC_FREE(ldb_kv); return ldb_oom(ldb); } lmdb->ldb = ldb; ldb_kv->kv_ops = &lmdb_key_value_ops; { const char *size = ldb_options_find( ldb, ldb->options, "lmdb_env_size"); if (size != NULL) { env_map_size = strtoull(size, NULL, 0); } } ret = lmdb_pvt_open(lmdb, ldb, path, env_map_size, flags); if (ret != LDB_SUCCESS) { TALLOC_FREE(ldb_kv); return ret; } ldb_kv->lmdb_private = lmdb; if (flags & LDB_FLG_RDONLY) { ldb_kv->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. */ ldb_kv->max_key_length = LDB_MDB_MAX_KEY_LENGTH; return ldb_kv_init_store( ldb_kv, "ldb_mdb backend", ldb, options, _module); } ldb-2.0.8/ldb_mdb/ldb_mdb.h0000660000000000000000000000304413444661620015344 0ustar rootroot00000000000000/* 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 . */ #ifndef _LDB_MDB_H_ #define _LDB_MDB_H_ #include "ldb_private.h" #include 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_ */ ldb-2.0.8/ldb_mdb/ldb_mdb_init.c0000660000000000000000000000211113444661620016354 0ustar rootroot00000000000000/* 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 . */ #include "ldb_mdb.h" int ldb_mdb_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_backend("mdb", lmdb_connect, false); } ldb-2.0.8/ldb_sqlite3/README0000660000000000000000000000066312406075657015324 0ustar rootroot00000000000000trees.ps contains an explanation of the Genealogical Representation of Trees in Databases which is being used in ldb_sqlite3. Note that we use fgID representation with 4 bytes per level, so we can represent 6.5E+08 subclasses of any object class. This should be adequate for our purposes. :-) The following document is the primary basis for the schema currently being used here: http://www.research.ibm.com/journal/sj/392/shi.html ldb-2.0.8/ldb_sqlite3/base160.c0000660000000000000000000001123212406075657015743 0ustar rootroot00000000000000/* base160 code used by ldb_sqlite3 Copyright (C) 2004 Derrell Lipman 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 . */ /* * ldb_sqlite3_base160() * * Convert an integer value to a string containing the base 160 representation * of the integer. We always convert to a string representation that is 4 * bytes in length, and we always null terminate. * * Parameters: * val -- * The value to be converted * * result -- * Buffer in which the result is to be placed * * Returns: * nothing */ static unsigned char base160tab[161] = { 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , /* 0-9 */ 58 , 59 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , /* : ; A-H */ 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , /* I-R */ 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 97 , 98 , /* S-Z , a-b */ 99 , 100, 101, 102, 103, 104, 105, 106, 107, 108, /* c-l */ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, /* m-v */ 119, 120, 121, 122, 160, 161, 162, 163, 164, 165, /* w-z, latin1 */ 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, /* latin1 */ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, /* latin1 */ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, /* latin1 */ 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, /* latin1 */ 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, /* latin1 */ 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, /* latin1 */ 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* latin1 */ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, /* latin1 */ 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* latin1 */ '\0' }; /* * lsqlite3_base160() * * Convert an unsigned long integer into a base160 representation of the * number. * * Parameters: * val -- * value to be converted * * result -- * character array, 5 bytes long, into which the base160 representation * will be placed. The result will be a four-digit representation of the * number (with leading zeros prepended as necessary), and null * terminated. * * Returns: * Nothing */ void lsqlite3_base160(unsigned long val, unsigned char result[5]) { int i; for (i = 3; i >= 0; i--) { result[i] = base160tab[val % 160]; val /= 160; } result[4] = '\0'; } /* * lsqlite3_base160Next() * * Retrieve the next-greater number in the base160 sequence for the terminal * tree node (the last four digits). Only one tree level (four digits) are * operated on. * * Parameters: * base160 -- a character array containing either an empty string (in which * case no operation is performed), or a string of base160 digits * with a length of a multiple of four digits. * * Upon return, the trailing four digits (one tree level) will * have been incremented by 1. * * Returns: * base160 -- the modified array */ char * lsqlite3_base160Next(char base160[]) { int i; int len; unsigned char * pTab; char * pBase160 = base160; /* * We need a minimum of four digits, and we will always get a multiple of * four digits. */ if ((len = strlen(pBase160)) >= 4) { pBase160 += strlen(pBase160) - 1; /* We only carry through four digits: one level in the tree */ for (i = 0; i < 4; i++) { /* What base160 value does this digit have? */ pTab = strchr(base160tab, *pBase160); /* Is there a carry? */ if (pTab < base160tab + sizeof(base160tab) - 1) { /* Nope. Just increment this value and we're done. */ *pBase160 = *++pTab; break; } else { /* * There's a carry. This value gets base160tab[0], we * decrement the buffer pointer to get the next higher-order * digit, and continue in the loop. */ *pBase160-- = base160tab[0]; } } } return base160; } ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c0000660000000000000000000014766713444661620017027 0ustar rootroot00000000000000/* ldb database library Copyright (C) Derrell Lipman 2005 Copyright (C) Simo Sorce 2005-2009 ** 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 . */ /* * Name: ldb * * Component: ldb sqlite3 backend * * Description: core files for SQLITE3 backend * * Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) */ #include "ldb_module.h" #include struct lsqlite3_private { int trans_count; char **options; sqlite3 *sqlite; }; struct lsql_context { struct ldb_module *module; struct ldb_request *req; /* search stuff */ long long current_eid; const char * const * attrs; struct ldb_reply *ares; bool callback_failed; struct tevent_timer *timeout_event; }; /* * Macros used throughout */ #ifndef FALSE # define FALSE (0) # define TRUE (! FALSE) #endif #define RESULT_ATTR_TABLE "temp_result_attrs" /* for testing, define to nothing, (create non-temporary table) */ #define TEMPTAB "TEMPORARY" /* * Static variables */ sqlite3_stmt * stmtGetEID = NULL; static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...) { char *str, *ret; va_list ap; va_start(ap, fmt); str = sqlite3_vmprintf(fmt, ap); va_end(ap); if (str == NULL) return NULL; ret = talloc_strdup(mem_ctx, str); if (ret == NULL) { sqlite3_free(str); return NULL; } sqlite3_free(str); return ret; } static char base160tab[161] = { 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */ 58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */ 73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */ 83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */ 99 ,100,101,102,103,104,105,106,107,108, /* c-l */ 109,110,111,112,113,114,115,116,117,118, /* m-v */ 119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */ 166,167,168,169,170,171,172,173,174,175, /* latin1 */ 176,177,178,179,180,181,182,183,184,185, /* latin1 */ 186,187,188,189,190,191,192,193,194,195, /* latin1 */ 196,197,198,199,200,201,202,203,204,205, /* latin1 */ 206,207,208,209,210,211,212,213,214,215, /* latin1 */ 216,217,218,219,220,221,222,223,224,225, /* latin1 */ 226,227,228,229,230,231,232,233,234,235, /* latin1 */ 236,237,238,239,240,241,242,243,244,245, /* latin1 */ 246,247,248,249,250,251,252,253,254,255, /* latin1 */ '\0' }; /* * base160() * * Convert an unsigned long integer into a base160 representation of the * number. * * Parameters: * val -- * value to be converted * * result -- * character array, 5 bytes long, into which the base160 representation * will be placed. The result will be a four-digit representation of the * number (with leading zeros prepended as necessary), and null * terminated. * * Returns: * Nothing */ static void base160_sql(sqlite3_context * hContext, int argc, sqlite3_value ** argv) { int i; long long val; char result[5]; val = sqlite3_value_int64(argv[0]); for (i = 3; i >= 0; i--) { result[i] = base160tab[val % 160]; val /= 160; } result[4] = '\0'; sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT); } /* * base160next_sql() * * This function enhances sqlite by adding a "base160_next()" function which is * accessible via queries. * * Retrieve the next-greater number in the base160 sequence for the terminal * tree node (the last four digits). Only one tree level (four digits) is * operated on. * * Input: * A character string: either an empty string (in which case no operation is * performed), or a string of base160 digits with a length of a multiple of * four digits. * * Output: * Upon return, the trailing four digits (one tree level) will have been * incremented by 1. */ static void base160next_sql(sqlite3_context * hContext, int argc, sqlite3_value ** argv) { int i; int len; char * pTab; char * pBase160 = strdup((const char *)sqlite3_value_text(argv[0])); char * pStart = pBase160; /* * We need a minimum of four digits, and we will always get a multiple * of four digits. */ if (pBase160 != NULL && (len = strlen(pBase160)) >= 4 && len % 4 == 0) { if (pBase160 == NULL) { sqlite3_result_null(hContext); return; } pBase160 += strlen(pBase160) - 1; /* We only carry through four digits: one level in the tree */ for (i = 0; i < 4; i++) { /* What base160 value does this digit have? */ pTab = strchr(base160tab, *pBase160); /* Is there a carry? */ if (pTab < base160tab + sizeof(base160tab) - 1) { /* * Nope. Just increment this value and we're * done. */ *pBase160 = *++pTab; break; } else { /* * There's a carry. This value gets * base160tab[0], we decrement the buffer * pointer to get the next higher-order digit, * and continue in the loop. */ *pBase160-- = base160tab[0]; } } sqlite3_result_text(hContext, pStart, strlen(pStart), free); } else { sqlite3_result_value(hContext, argv[0]); if (pBase160 != NULL) { free(pBase160); } } } static char *parsetree_to_sql(struct ldb_module *module, void *mem_ctx, const struct ldb_parse_tree *t) { struct ldb_context *ldb; const struct ldb_schema_attribute *a; struct ldb_val value, subval; char *wild_card_string; char *child, *tmp; char *ret = NULL; char *attr; unsigned int i; ldb = ldb_module_get_ctx(module); switch(t->operation) { case LDB_OP_AND: tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); if (tmp == NULL) return NULL; for (i = 1; i < t->u.list.num_elements; i++) { child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); if (child == NULL) return NULL; tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child); if (tmp == NULL) return NULL; } ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp); return ret; case LDB_OP_OR: tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); if (tmp == NULL) return NULL; for (i = 1; i < t->u.list.num_elements; i++) { child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); if (child == NULL) return NULL; tmp = talloc_asprintf_append(tmp, " UNION %s ", child); if (tmp == NULL) return NULL; } return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp); case LDB_OP_NOT: child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child); if (child == NULL) return NULL; return talloc_asprintf(mem_ctx, "SELECT eid FROM ldb_entry " "WHERE eid NOT IN ( %s ) ", child); case LDB_OP_EQUALITY: /* * For simple searches, we want to retrieve the list of EIDs that * match the criteria. */ attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; a = ldb_schema_attribute_by_name(ldb, attr); /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); if (value.data == NULL) { return NULL; } if (strcasecmp(t->u.equality.attr, "dn") == 0) { /* DN query is a special ldb case */ 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 " "WHERE norm_dn = '%q'", cdn); } else { /* A normal query. */ return lsqlite3_tprintf(mem_ctx, "SELECT eid FROM ldb_attribute_values " "WHERE norm_attr_name = '%q' " "AND norm_attr_value = '%q'", attr, value.data); } case LDB_OP_SUBSTRING: wild_card_string = talloc_strdup(mem_ctx, (t->u.substring.start_with_wildcard)?"*":""); if (wild_card_string == NULL) return NULL; for (i = 0; t->u.substring.chunks[i]; i++) { wild_card_string = talloc_asprintf_append(wild_card_string, "%s*", t->u.substring.chunks[i]->data); if (wild_card_string == NULL) return NULL; } if ( ! t->u.substring.end_with_wildcard ) { /* remove last wildcard */ wild_card_string[strlen(wild_card_string) - 1] = '\0'; } attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr); if (attr == NULL) return NULL; a = ldb_schema_attribute_by_name(ldb, attr); subval.data = (void *)wild_card_string; subval.length = strlen(wild_card_string) + 1; /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, mem_ctx, &(subval), &value); if (value.data == NULL) { return NULL; } return lsqlite3_tprintf(mem_ctx, "SELECT eid FROM ldb_attribute_values " "WHERE norm_attr_name = '%q' " "AND norm_attr_value GLOB '%q'", attr, value.data); case LDB_OP_GREATER: attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; a = ldb_schema_attribute_by_name(ldb, attr); /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); if (value.data == NULL) { return NULL; } return lsqlite3_tprintf(mem_ctx, "SELECT eid FROM ldb_attribute_values " "WHERE norm_attr_name = '%q' " "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ", attr, value.data, attr); case LDB_OP_LESS: attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; a = ldb_schema_attribute_by_name(ldb, attr); /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); if (value.data == NULL) { return NULL; } return lsqlite3_tprintf(mem_ctx, "SELECT eid FROM ldb_attribute_values " "WHERE norm_attr_name = '%q' " "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ", attr, value.data, attr); case LDB_OP_PRESENT: if (strcasecmp(t->u.present.attr, "dn") == 0) { return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); } attr = ldb_attr_casefold(mem_ctx, t->u.present.attr); if (attr == NULL) return NULL; return lsqlite3_tprintf(mem_ctx, "SELECT eid FROM ldb_attribute_values " "WHERE norm_attr_name = '%q' ", attr); case LDB_OP_APPROX: attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; a = ldb_schema_attribute_by_name(ldb, attr); /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); if (value.data == NULL) { return NULL; } return lsqlite3_tprintf(mem_ctx, "SELECT eid FROM ldb_attribute_values " "WHERE norm_attr_name = '%q' " "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ", attr, value.data, attr); case LDB_OP_EXTENDED: #warning "work out how to handle bitops" return NULL; default: break; }; /* should never occur */ abort(); return NULL; } /* * query_int() * * This function is used for the common case of queries that return a single * integer value. * * NOTE: If more than one value is returned by the query, all but the first * one will be ignored. */ static int query_int(const struct lsqlite3_private * lsqlite3, long long * pRet, const char * pSql, ...) { int ret; int bLoop; char * p; sqlite3_stmt * pStmt; va_list args; /* Begin access to variable argument list */ va_start(args, pSql); /* Format the query */ if ((p = sqlite3_vmprintf(pSql, args)) == NULL) { va_end(args); return SQLITE_NOMEM; } /* * Prepare and execute the SQL statement. Loop allows retrying on * certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes, * requiring retrying the operation. */ for (bLoop = TRUE; bLoop; ) { /* Compile the SQL statement into sqlite virtual machine */ if ((ret = sqlite3_prepare(lsqlite3->sqlite, p, -1, &pStmt, NULL)) == SQLITE_SCHEMA) { if (stmtGetEID != NULL) { sqlite3_finalize(stmtGetEID); stmtGetEID = NULL; } continue; } else if (ret != SQLITE_OK) { break; } /* One row expected */ if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) { if (stmtGetEID != NULL) { sqlite3_finalize(stmtGetEID); stmtGetEID = NULL; } (void) sqlite3_finalize(pStmt); continue; } else if (ret != SQLITE_ROW) { (void) sqlite3_finalize(pStmt); break; } /* Get the value to be returned */ *pRet = sqlite3_column_int64(pStmt, 0); /* Free the virtual machine */ if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) { if (stmtGetEID != NULL) { sqlite3_finalize(stmtGetEID); stmtGetEID = NULL; } continue; } else if (ret != SQLITE_OK) { (void) sqlite3_finalize(pStmt); break; } /* * Normal condition is only one time through loop. Loop is * rerun in error conditions, via "continue", above. */ bLoop = FALSE; } /* All done with variable argument list */ va_end(args); /* Free the memory we allocated for our query string */ sqlite3_free(p); return ret; } /* * This is a bad hack to support ldap style comparisons within sqlite. * val is the attribute in the row currently under test * func is the desired test "<=" ">=" "~" ":" * cmp is the value to compare against (eg: "test") * attr is the attribute name the value of which we want to test */ static void lsqlite3_compare(sqlite3_context *ctx, int argc, sqlite3_value **argv) { struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx); const char *val = (const char *)sqlite3_value_text(argv[0]); const char *func = (const char *)sqlite3_value_text(argv[1]); const char *cmp = (const char *)sqlite3_value_text(argv[2]); const char *attr = (const char *)sqlite3_value_text(argv[3]); const struct ldb_schema_attribute *a; struct ldb_val valX; struct ldb_val valY; int ret; switch (func[0]) { /* greater */ case '>': /* >= */ a = ldb_schema_attribute_by_name(ldb, attr); valX.data = (uint8_t *)cmp; valX.length = strlen(cmp); valY.data = (uint8_t *)val; valY.length = strlen(val); ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); if (ret >= 0) sqlite3_result_int(ctx, 1); else sqlite3_result_int(ctx, 0); return; /* lesser */ case '<': /* <= */ a = ldb_schema_attribute_by_name(ldb, attr); valX.data = (uint8_t *)cmp; valX.length = strlen(cmp); valY.data = (uint8_t *)val; valY.length = strlen(val); ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); if (ret <= 0) sqlite3_result_int(ctx, 1); else sqlite3_result_int(ctx, 0); return; /* approx */ case '~': /* TODO */ sqlite3_result_int(ctx, 0); return; /* bitops */ case ':': /* TODO */ sqlite3_result_int(ctx, 0); return; default: break; } sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1); return; } /* rename a record */ static int lsqlite3_safe_rollback(sqlite3 *sqlite) { char *errmsg; int ret; /* execute */ ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3_safe_rollback: Error: %s\n", errmsg); free(errmsg); } return -1; } return 0; } /* return an eid as result */ static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names) { long long *eid = (long long *)result; if (col_num != 1) return SQLITE_ABORT; if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT; *eid = atoll(cols[0]); return SQLITE_OK; } /* * add a single set of ldap message values to a ldb_message */ static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names) { struct ldb_context *ldb; struct lsql_context *ac; struct ldb_message *msg; long long eid; unsigned int i; int ret; ac = talloc_get_type(result, struct lsql_context); ldb = ldb_module_get_ctx(ac->module); /* eid, dn, attr_name, attr_value */ if (col_num != 4) return SQLITE_ABORT; eid = atoll(cols[0]); if (ac->ares) { msg = ac->ares->message; } if (eid != ac->current_eid) { /* here begin a new entry */ /* call the async callback for the last entry * except the first time */ if (ac->current_eid != 0) { ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); if (ret != LDB_SUCCESS) { return SQLITE_ABORT; } ret = ldb_module_send_entry(ac->req, msg, NULL); if (ret != LDB_SUCCESS) { ac->callback_failed = true; /* free msg object */ TALLOC_FREE(msg); return SQLITE_ABORT; } /* free msg object */ TALLOC_FREE(msg); } /* start over */ ac->ares = talloc_zero(ac, struct ldb_reply); if (!ac->ares) return SQLITE_ABORT; msg = ldb_msg_new(ac->ares); if (!msg) return SQLITE_ABORT; ac->ares->type = LDB_REPLY_ENTRY; ac->current_eid = eid; } if (msg->dn == NULL) { msg->dn = ldb_dn_new(msg, ldb, cols[1]); if (msg->dn == NULL) return SQLITE_ABORT; } if (ac->attrs) { int found = 0; for (i = 0; ac->attrs[i]; i++) { if (strcasecmp(cols[2], ac->attrs[i]) == 0) { found = 1; break; } } if (!found) goto done; } if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) { return SQLITE_ABORT; } done: ac->ares->message = msg; return SQLITE_OK; } /* * lsqlite3_get_eid() * lsqlite3_get_eid_ndn() * * These functions are used for the very common case of retrieving an EID value * given a (normalized) DN. */ static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn) { char *errmsg; char *query; long long eid = -1; long long ret; /* get object eid */ query = lsqlite3_tprintf(mem_ctx, "SELECT eid " "FROM ldb_entry " "WHERE norm_dn = '%q';", norm_dn); if (query == NULL) return -1; ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg); free(errmsg); } return -1; } return eid; } static long long lsqlite3_get_eid(struct lsqlite3_private *lsqlite3, struct ldb_dn *dn) { TALLOC_CTX *local_ctx; long long eid = -1; char *cdn; /* ignore ltdb specials */ if (ldb_dn_is_special(dn)) { return -1; } /* create a local ctx */ local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context"); if (local_ctx == NULL) { return -1; } cdn = ldb_dn_alloc_casefold(local_ctx, dn); if (!cdn) goto done; eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn); done: talloc_free(local_ctx); return eid; } /* * Interface functions referenced by lsqlite3_ops */ /* search for matching records, by tree */ int lsql_search(struct lsql_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; struct lsqlite3_private *lsqlite3; struct ldb_context *ldb; char *norm_basedn; char *sqlfilter; char *errmsg; char *query = NULL; int ret; ldb = ldb_module_get_ctx(module); lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); if ((( ! ldb_dn_is_valid(req->op.search.base)) || ldb_dn_is_null(req->op.search.base)) && (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL)) { return LDB_ERR_OPERATIONS_ERROR; } if (req->op.search.base) { norm_basedn = ldb_dn_alloc_casefold(ctx, req->op.search.base); if (norm_basedn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } } else norm_basedn = talloc_strdup(ctx, ""); /* Convert filter into a series of SQL conditions (constraints) */ sqlfilter = parsetree_to_sql(module, ctx, req->op.search.tree); switch(req->op.search.scope) { case LDB_SCOPE_DEFAULT: case LDB_SCOPE_SUBTREE: if (*norm_basedn != '\0') { query = lsqlite3_tprintf(ctx, "SELECT entry.eid,\n" " entry.dn,\n" " av.attr_name,\n" " av.attr_value\n" " FROM ldb_entry AS entry\n" " LEFT OUTER JOIN ldb_attribute_values AS av\n" " ON av.eid = entry.eid\n" " WHERE entry.eid IN\n" " (SELECT DISTINCT ldb_entry.eid\n" " FROM ldb_entry\n" " WHERE (ldb_entry.norm_dn GLOB('*,%q')\n" " OR ldb_entry.norm_dn = '%q')\n" " AND ldb_entry.eid IN\n" " (%s)\n" " )\n" " ORDER BY entry.eid ASC;", norm_basedn, norm_basedn, sqlfilter); } else { query = lsqlite3_tprintf(ctx, "SELECT entry.eid,\n" " entry.dn,\n" " av.attr_name,\n" " av.attr_value\n" " FROM ldb_entry AS entry\n" " LEFT OUTER JOIN ldb_attribute_values AS av\n" " ON av.eid = entry.eid\n" " WHERE entry.eid IN\n" " (SELECT DISTINCT ldb_entry.eid\n" " FROM ldb_entry\n" " WHERE ldb_entry.eid IN\n" " (%s)\n" " )\n" " ORDER BY entry.eid ASC;", sqlfilter); } break; case LDB_SCOPE_BASE: query = lsqlite3_tprintf(ctx, "SELECT entry.eid,\n" " entry.dn,\n" " av.attr_name,\n" " av.attr_value\n" " FROM ldb_entry AS entry\n" " LEFT OUTER JOIN ldb_attribute_values AS av\n" " ON av.eid = entry.eid\n" " WHERE entry.eid IN\n" " (SELECT DISTINCT ldb_entry.eid\n" " FROM ldb_entry\n" " WHERE ldb_entry.norm_dn = '%q'\n" " AND ldb_entry.eid IN\n" " (%s)\n" " )\n" " ORDER BY entry.eid ASC;", norm_basedn, sqlfilter); break; case LDB_SCOPE_ONELEVEL: query = lsqlite3_tprintf(ctx, "SELECT entry.eid,\n" " entry.dn,\n" " av.attr_name,\n" " av.attr_value\n" " FROM ldb_entry AS entry\n" " LEFT OUTER JOIN ldb_attribute_values AS av\n" " ON av.eid = entry.eid\n" " WHERE entry.eid IN\n" " (SELECT DISTINCT ldb_entry.eid\n" " FROM ldb_entry\n" " WHERE norm_dn GLOB('*,%q')\n" " AND NOT norm_dn GLOB('*,*,%q')\n" " AND ldb_entry.eid IN\n(%s)\n" " )\n" " ORDER BY entry.eid ASC;", norm_basedn, norm_basedn, sqlfilter); break; } if (query == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* * / printf ("%s\n", query); / * */ ctx->current_eid = 0; ctx->attrs = req->op.search.attrs; ctx->ares = NULL; ldb_request_set_state(req, LDB_ASYNC_PENDING); ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, ctx, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } /* complete the last message if any */ if (ctx->ares) { ret = ldb_msg_normalize(ldb, ctx->ares, ctx->ares->message, &ctx->ares->message); if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_module_send_entry(req, ctx->ares->message, NULL); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } /* add a record */ static int lsql_add(struct lsql_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; struct lsqlite3_private *lsqlite3; struct ldb_context *ldb; struct ldb_message *msg = req->op.add.message; long long eid; char *dn, *ndn; char *errmsg; char *query; unsigned int i; int ret; ldb = ldb_module_get_ctx(module); lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); /* See if this is an ltdb special */ if (ldb_dn_is_special(msg->dn)) { /* struct ldb_dn *c; c = ldb_dn_new(local_ctx, ldb, "@INDEXLIST"); if (ldb_dn_compare(ldb, msg->dn, c) == 0) { #warning "should we handle indexes somehow ?" ret = LDB_ERR_UNWILLING_TO_PERFORM; goto done; } */ /* Others return an error */ return LDB_ERR_UNWILLING_TO_PERFORM; } /* create linearized and normalized dns */ dn = ldb_dn_alloc_linearized(ctx, msg->dn); ndn = ldb_dn_alloc_casefold(ctx, msg->dn); if (dn == NULL || ndn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } query = lsqlite3_tprintf(ctx, /* Add new entry */ "INSERT OR ABORT INTO ldb_entry " "('dn', 'norm_dn') " "VALUES ('%q', '%q');", dn, ndn); if (query == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, ctx, ndn); if (eid == -1) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0; i < msg->num_elements; i++) { const struct ldb_message_element *el = &msg->elements[i]; const struct ldb_schema_attribute *a; char *attr; unsigned int j; /* Get a case-folded copy of the attribute name */ attr = ldb_attr_casefold(ctx, el->name); if (attr == NULL) { return LDB_ERR_OPERATIONS_ERROR; } a = ldb_schema_attribute_by_name(ldb, el->name); if (el->num_value == 0) { ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", el->name, ldb_dn_get_linearized(msg->dn)); return LDB_ERR_CONSTRAINT_VIOLATION; } /* For each value of the specified attribute name... */ for (j = 0; j < el->num_values; j++) { struct ldb_val value; char *insert; /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); if (value.data == NULL) { return LDB_ERR_OPERATIONS_ERROR; } insert = lsqlite3_tprintf(ctx, "INSERT OR ROLLBACK INTO ldb_attribute_values " "('eid', 'attr_name', 'norm_attr_name'," " 'attr_value', 'norm_attr_value') " "VALUES ('%lld', '%q', '%q', '%q', '%q');", eid, el->name, attr, el->values[j].data, value.data); if (insert == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } } } return LDB_SUCCESS; } /* modify a record */ static int lsql_modify(struct lsql_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; struct lsqlite3_private *lsqlite3; struct ldb_context *ldb; struct ldb_message *msg = req->op.mod.message; long long eid; char *errmsg; unsigned int i; int ret; ldb = ldb_module_get_ctx(module); lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); /* See if this is an ltdb special */ if (ldb_dn_is_special(msg->dn)) { /* Others return an error */ return LDB_ERR_UNWILLING_TO_PERFORM; } eid = lsqlite3_get_eid(lsqlite3, msg->dn); if (eid == -1) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0; i < msg->num_elements; i++) { const struct ldb_message_element *el = &msg->elements[i]; const struct ldb_schema_attribute *a; unsigned int flags = el->flags & LDB_FLAG_MOD_MASK; char *attr; char *mod; unsigned int j; /* Get a case-folded copy of the attribute name */ attr = ldb_attr_casefold(ctx, el->name); if (attr == NULL) { return LDB_ERR_OPERATIONS_ERROR; } a = ldb_schema_attribute_by_name(ldb, el->name); switch (flags) { case LDB_FLAG_MOD_REPLACE: struct ldb_val *duplicate = NULL; ret = ldb_msg_find_duplicate_val(ldb, el, el, &duplicate, 0); if (ret != LDB_SUCCESS) { return ret; } if (duplicate != NULL) { ldb_asprintf_errstring( ldb, "attribute '%s': value '%.*s' " "on '%s' provided more than " "once in REPLACE", el->name, (int)duplicate->length, duplicate->data, ldb_dn_get_linearized(msg2->dn)); return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } /* remove all attributes before adding the replacements */ mod = lsqlite3_tprintf(ctx, "DELETE FROM ldb_attribute_values " "WHERE eid = '%lld' " "AND norm_attr_name = '%q';", eid, attr); if (mod == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } /* MISSING break is INTENTIONAL */ case LDB_FLAG_MOD_ADD: if (el->num_values == 0) { ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)", el->name, ldb_dn_get_linearized(msg->dn)); return LDB_ERR_CONSTRAINT_VIOLATION; } /* For each value of the specified attribute name... */ for (j = 0; j < el->num_values; j++) { struct ldb_val value; /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); if (value.data == NULL) { return LDB_ERR_OPERATIONS_ERROR; } mod = lsqlite3_tprintf(ctx, "INSERT OR ROLLBACK INTO ldb_attribute_values " "('eid', 'attr_name', 'norm_attr_name'," " 'attr_value', 'norm_attr_value') " "VALUES ('%lld', '%q', '%q', '%q', '%q');", eid, el->name, attr, el->values[j].data, value.data); if (mod == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } } break; case LDB_FLAG_MOD_DELETE: #warning "We should throw an error if the attribute we are trying to delete does not exist!" if (el->num_values == 0) { mod = lsqlite3_tprintf(ctx, "DELETE FROM ldb_attribute_values " "WHERE eid = '%lld' " "AND norm_attr_name = '%q';", eid, attr); if (mod == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } } /* For each value of the specified attribute name... */ for (j = 0; j < el->num_values; j++) { struct ldb_val value; /* Get a canonicalised copy of the data */ a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); if (value.data == NULL) { return LDB_ERR_OPERATIONS_ERROR; } mod = lsqlite3_tprintf(ctx, "DELETE FROM ldb_attribute_values " "WHERE eid = '%lld' " "AND norm_attr_name = '%q' " "AND norm_attr_value = '%q';", eid, attr, value.data); if (mod == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } } break; } } return LDB_SUCCESS; } /* delete a record */ static int lsql_delete(struct lsql_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; struct lsqlite3_private *lsqlite3; struct ldb_context *ldb; long long eid; char *errmsg; char *query; int ret; ldb = ldb_module_get_ctx(module); lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); eid = lsqlite3_get_eid(lsqlite3, req->op.del.dn); if (eid == -1) { return LDB_ERR_OPERATIONS_ERROR; } query = lsqlite3_tprintf(ctx, /* Delete entry */ "DELETE FROM ldb_entry WHERE eid = %lld; " /* Delete attributes */ "DELETE FROM ldb_attribute_values WHERE eid = %lld; ", eid, eid); if (query == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } /* rename a record */ static int lsql_rename(struct lsql_context *ctx) { struct ldb_module *module = ctx->module; struct ldb_request *req = ctx->req; struct lsqlite3_private *lsqlite3; struct ldb_context *ldb; char *new_dn, *new_cdn, *old_cdn; char *errmsg; char *query; int ret; ldb = ldb_module_get_ctx(module); lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); /* create linearized and normalized dns */ old_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.olddn); new_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.newdn); new_dn = ldb_dn_alloc_linearized(ctx, req->op.rename.newdn); if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* build the SQL query */ query = lsqlite3_tprintf(ctx, "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' " "WHERE norm_dn = '%q';", new_dn, new_cdn, old_cdn); if (query == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* execute */ ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { ldb_set_errstring(ldb, errmsg); free(errmsg); } return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } static int lsql_start_trans(struct ldb_module * module) { int ret; char *errmsg; struct lsqlite3_private *lsqlite3; lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); if (lsqlite3->trans_count == 0) { ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3_start_trans: error: %s\n", errmsg); free(errmsg); } return -1; } }; lsqlite3->trans_count++; return 0; } static int lsql_end_trans(struct ldb_module *module) { int ret; char *errmsg; struct lsqlite3_private *lsqlite3; lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); if (lsqlite3->trans_count > 0) { lsqlite3->trans_count--; } else return -1; if (lsqlite3->trans_count == 0) { ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3_end_trans: error: %s\n", errmsg); free(errmsg); } return -1; } } return 0; } static int lsql_del_trans(struct ldb_module *module) { struct lsqlite3_private *lsqlite3; lsqlite3 = talloc_get_type(ldb_module_get_private(module), struct lsqlite3_private); if (lsqlite3->trans_count > 0) { lsqlite3->trans_count--; } else return -1; if (lsqlite3->trans_count == 0) { return lsqlite3_safe_rollback(lsqlite3->sqlite); } return -1; } static int destructor(struct lsqlite3_private *lsqlite3) { if (lsqlite3->sqlite) { sqlite3_close(lsqlite3->sqlite); } return 0; } static void lsql_request_done(struct lsql_context *ctx, int error) { struct ldb_context *ldb; struct ldb_request *req; struct ldb_reply *ares; ldb = ldb_module_get_ctx(ctx->module); req = ctx->req; /* if we already returned an error just return */ if (ldb_request_get_status(req) != LDB_SUCCESS) { return; } ares = talloc_zero(req, struct ldb_reply); if (!ares) { ldb_oom(ldb); req->callback(req, NULL); return; } ares->type = LDB_REPLY_DONE; ares->error = error; req->callback(req, ares); } static void lsql_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct lsql_context *ctx; ctx = talloc_get_type(private_data, struct lsql_context); lsql_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); } static void lsql_callback(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct lsql_context *ctx; int ret; ctx = talloc_get_type(private_data, struct lsql_context); switch (ctx->req->operation) { case LDB_SEARCH: ret = lsql_search(ctx); break; case LDB_ADD: ret = lsql_add(ctx); break; case LDB_MODIFY: ret = lsql_modify(ctx); break; case LDB_DELETE: ret = lsql_delete(ctx); break; case LDB_RENAME: ret = lsql_rename(ctx); break; /* TODO: case LDB_EXTENDED: ret = lsql_extended(ctx); break; */ default: /* no other op supported */ ret = LDB_ERR_PROTOCOL_ERROR; } if (!ctx->callback_failed) { /* Once we are done, we do not need timeout events */ talloc_free(ctx->timeout_event); lsql_request_done(ctx, ret); } } static int lsql_handle_request(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct tevent_context *ev; struct lsql_context *ac; struct tevent_timer *te; struct timeval tv; if (ldb_check_critical_controls(req->controls)) { return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; } if (req->starttime == 0 || req->timeout == 0) { ldb_set_errstring(ldb, "Invalid timeout settings"); return LDB_ERR_TIME_LIMIT_EXCEEDED; } ldb = ldb_module_get_ctx(module); ev = ldb_get_event_context(ldb); ac = talloc_zero(req, struct lsql_context); if (ac == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } ac->module = module; ac->req = req; tv.tv_sec = 0; tv.tv_usec = 0; te = tevent_add_timer(ev, ac, tv, lsql_callback, ac); if (NULL == te) { return LDB_ERR_OPERATIONS_ERROR; } if (req->timeout > 0) { tv.tv_sec = req->starttime + req->timeout; tv.tv_usec = 0; ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); if (NULL == ac->timeout_event) { return LDB_ERR_OPERATIONS_ERROR; } } return LDB_SUCCESS; } /* * Table of operations for the sqlite3 backend */ static const struct ldb_module_ops lsqlite3_ops = { .name = "sqlite", .search = lsql_handle_request, .add = lsql_handle_request, .modify = lsql_handle_request, .del = lsql_handle_request, .rename = lsql_handle_request, .extended = lsql_handle_request, .start_transaction = lsql_start_trans, .end_transaction = lsql_end_trans, .del_transaction = lsql_del_trans, }; /* * Static functions */ static int initialize(struct lsqlite3_private *lsqlite3, struct ldb_context *ldb, const char *url, unsigned int flags) { TALLOC_CTX *local_ctx; long long queryInt; int rollback = 0; char *errmsg; char *schema; int ret; /* create a local ctx */ local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context"); if (local_ctx == NULL) { return -1; } schema = lsqlite3_tprintf(local_ctx, "CREATE TABLE ldb_info AS " " SELECT 'LDB' AS database_type," " '1.0' AS version;" /* * The entry table holds the information about an entry. * This table is used to obtain the EID of the entry and to * support scope=one and scope=base. The parent and child * table is included in the entry table since all the other * attributes are dependent on EID. */ "CREATE TABLE ldb_entry " "(" " eid INTEGER PRIMARY KEY AUTOINCREMENT," " dn TEXT UNIQUE NOT NULL," " norm_dn TEXT UNIQUE NOT NULL" ");" "CREATE TABLE ldb_object_classes" "(" " class_name TEXT PRIMARY KEY," " parent_class_name TEXT," " tree_key TEXT UNIQUE," " max_child_num INTEGER DEFAULT 0" ");" /* * We keep a full listing of attribute/value pairs here */ "CREATE TABLE ldb_attribute_values" "(" " eid INTEGER REFERENCES ldb_entry," " attr_name TEXT," " norm_attr_name TEXT," " attr_value TEXT," " norm_attr_value TEXT " ");" /* * Indexes */ "CREATE INDEX ldb_attribute_values_eid_idx " " ON ldb_attribute_values (eid);" "CREATE INDEX ldb_attribute_values_name_value_idx " " ON ldb_attribute_values (attr_name, norm_attr_value);" /* * Triggers */ "CREATE TRIGGER ldb_object_classes_insert_tr" " AFTER INSERT" " ON ldb_object_classes" " FOR EACH ROW" " BEGIN" " UPDATE ldb_object_classes" " SET tree_key = COALESCE(tree_key, " " (" " SELECT tree_key || " " (SELECT base160(max_child_num + 1)" " FROM ldb_object_classes" " WHERE class_name = " " new.parent_class_name)" " FROM ldb_object_classes " " WHERE class_name = new.parent_class_name " " ));" " UPDATE ldb_object_classes " " SET max_child_num = max_child_num + 1" " WHERE class_name = new.parent_class_name;" " END;" /* * Table initialization */ "INSERT INTO ldb_object_classes " " (class_name, tree_key) " " VALUES " " ('TOP', '0001');"); /* Skip protocol indicator of url */ if (strncmp(url, "sqlite3://", 10) != 0) { return SQLITE_MISUSE; } /* Update pointer to just after the protocol indicator */ url += 10; /* Try to open the (possibly empty/non-existent) database */ if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) { return ret; } /* In case this is a new database, enable auto_vacuum */ ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3 initializaion error: %s\n", errmsg); free(errmsg); } goto failed; } if (flags & LDB_FLG_NOSYNC) { /* DANGEROUS */ ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3 initializaion error: %s\n", errmsg); free(errmsg); } goto failed; } } /* */ /* Establish a busy timeout of 30 seconds */ if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite, 30000)) != SQLITE_OK) { return ret; } /* Create a function, callable from sql, to increment a tree_key */ if ((ret = sqlite3_create_function(lsqlite3->sqlite,/* handle */ "base160_next", /* function name */ 1, /* number of args */ SQLITE_ANY, /* preferred text type */ NULL, /* user data */ base160next_sql, /* called func */ NULL, /* step func */ NULL /* final func */ )) != SQLITE_OK) { return ret; } /* Create a function, callable from sql, to convert int to base160 */ if ((ret = sqlite3_create_function(lsqlite3->sqlite,/* handle */ "base160", /* function name */ 1, /* number of args */ SQLITE_ANY, /* preferred text type */ NULL, /* user data */ base160_sql, /* called func */ NULL, /* step func */ NULL /* final func */ )) != SQLITE_OK) { return ret; } /* Create a function, callable from sql, to perform various comparisons */ if ((ret = sqlite3_create_function(lsqlite3->sqlite, /* handle */ "ldap_compare", /* function name */ 4, /* number of args */ SQLITE_ANY, /* preferred text type */ ldb , /* user data */ lsqlite3_compare, /* called func */ NULL, /* step func */ NULL /* final func */ )) != SQLITE_OK) { return ret; } /* Begin a transaction */ ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3: initialization error: %s\n", errmsg); free(errmsg); } goto failed; } rollback = 1; /* Determine if this is a new database. No tables means it is. */ if (query_int(lsqlite3, &queryInt, "SELECT COUNT(*)\n" " FROM sqlite_master\n" " WHERE type = 'table';") != 0) { goto failed; } if (queryInt == 0) { /* * Create the database schema */ ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3 initializaion error: %s\n", errmsg); free(errmsg); } goto failed; } } else { /* * Ensure that the database we opened is one of ours */ if (query_int(lsqlite3, &queryInt, "SELECT " " (SELECT COUNT(*) = 2" " FROM sqlite_master " " WHERE type = 'table' " " AND name IN " " (" " 'ldb_entry', " " 'ldb_object_classes' " " ) " " ) " " AND " " (SELECT 1 " " FROM ldb_info " " WHERE database_type = 'LDB' " " AND version = '1.0'" " );") != 0 || queryInt != 1) { /* It's not one that we created. See ya! */ goto failed; } } /* Commit the transaction */ ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { if (errmsg) { printf("lsqlite3: iniialization error: %s\n", errmsg); free(errmsg); } goto failed; } return SQLITE_OK; failed: if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); sqlite3_close(lsqlite3->sqlite); return -1; } /* * connect to the database */ static int lsqlite3_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[], struct ldb_module **_module) { struct ldb_module *module; struct lsqlite3_private *lsqlite3; unsigned int i; int ret; module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops); if (!module) return LDB_ERR_OPERATIONS_ERROR; lsqlite3 = talloc(module, struct lsqlite3_private); if (!lsqlite3) { goto failed; } lsqlite3->sqlite = NULL; lsqlite3->options = NULL; lsqlite3->trans_count = 0; ret = initialize(lsqlite3, ldb, url, flags); if (ret != SQLITE_OK) { goto failed; } talloc_set_destructor(lsqlite3, destructor); ldb_module_set_private(module, lsqlite3); if (options) { /* * take a copy of the options array, so we don't have to rely * on the caller keeping it around (it might be dynamic) */ for (i=0;options[i];i++) ; lsqlite3->options = talloc_array(lsqlite3, char *, i+1); if (!lsqlite3->options) { goto failed; } for (i=0;options[i];i++) { lsqlite3->options[i+1] = NULL; lsqlite3->options[i] = talloc_strdup(lsqlite3->options, options[i]); if (!lsqlite3->options[i]) { goto failed; } } } *_module = module; return LDB_SUCCESS; failed: if (lsqlite3 && lsqlite3->sqlite != NULL) { (void) sqlite3_close(lsqlite3->sqlite); } talloc_free(lsqlite3); return LDB_ERR_OPERATIONS_ERROR; } int ldb_sqlite3_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_backend("sqlite3", lsqlite3_connect, false); } ldb-2.0.8/ldb_sqlite3/schema0000660000000000000000000002434712406075657015634 0ustar rootroot00000000000000 -- ------------------------------------------------------ PRAGMA auto_vacuum=1; -- ------------------------------------------------------ BEGIN EXCLUSIVE; -- ------------------------------------------------------ CREATE TABLE ldb_info AS SELECT 'LDB' AS database_type, '1.0' AS version; /* * Get the next USN value with: * BEGIN EXCLUSIVE; * UPDATE usn SET value = value + 1; * SELECT value FROM usn; * COMMIT; */ CREATE TABLE usn ( value INTEGER ); CREATE TABLE ldb_object ( /* tree_key is auto-generated by the insert trigger */ tree_key TEXT PRIMARY KEY, parent_tree_key TEXT, dn TEXT, attr_name TEXT REFERENCES ldb_attributes, attr_value TEXT, /* * object_type can take on these values (to date): * 1: object is a node of a DN * 2: object is an attribute/value pair of its parent DN */ object_type INTEGER, /* * if object_type is 1, the node can have children. * this tracks the maximum previously assigned child * number so we can generate a new unique tree key for * a new child object. note that this is always incremented, * so if children are deleted, this will not represent * the _number_ of children. */ max_child_num INTEGER, /* * Automatically maintained meta-data (a gift for metze) */ object_guid TEXT UNIQUE, timestamp INTEGER, -- originating_time invoke_id TEXT, -- GUID: originating_invocation_id usn INTEGER, -- hyper: originating_usn /* do not allow duplicate name/value pairs */ UNIQUE (parent_tree_key, attr_name, attr_value, object_type) ); CREATE TABLE ldb_attributes ( attr_name TEXT PRIMARY KEY, parent_tree_key TEXT, objectclass_p BOOLEAN DEFAULT 0, case_insensitive_p BOOLEAN DEFAULT 0, wildcard_p BOOLEAN DEFAULT 0, hidden_p BOOLEAN DEFAULT 0, integer_p BOOLEAN DEFAULT 0, /* tree_key is auto-generated by the insert trigger */ tree_key TEXT, -- null if not a object/sub class -- level 1 if an objectclass -- level 1-n if a subclass max_child_num INTEGER ); -- ------------------------------------------------------ CREATE INDEX ldb_object_dn_idx ON ldb_object (dn); CREATE INDEX ldb_attributes_tree_key_ids ON ldb_attributes (tree_key); -- ------------------------------------------------------ /* Gifts for metze. Automatically updated meta-data */ CREATE TRIGGER ldb_object_insert_tr AFTER INSERT ON ldb_object FOR EACH ROW BEGIN UPDATE ldb_object SET max_child_num = max_child_num + 1 WHERE tree_key = new.parent_tree_key; UPDATE usn SET value = value + 1; UPDATE ldb_object SET tree_key = (SELECT new.tree_key || base160(SELECT max_child_num FROM ldb_object WHERE tree_key = new.parent_tree_key)); max_child_num = 0, object_guid = random_guid(), timestamp = strftime('%s', 'now'), usn = (SELECT value FROM usn); WHERE tree_key = new.tree_key; END; CREATE TRIGGER ldb_object_update_tr AFTER UPDATE ON ldb_object FOR EACH ROW BEGIN UPDATE usn SET value = value + 1; UPDATE ldb_object SET timestamp = strftime('%s', 'now'), usn = (SELECT value FROM usn); WHERE tree_key = new.tree_key; END; CREATE TRIGGER ldb_attributes_insert_tr AFTER INSERT ON ldb_attributes FOR EACH ROW BEGIN UPDATE ldb_attributes SET max_child_num = max_child_num + 1 WHERE tree_key = new.parent_tree_key; UPDATE ldb_attributes SET tree_key = (SELECT new.tree_key || base160(SELECT max_child_num FROM ldb_attributes WHERE tree_key = new.parent_tree_key)); max_child_num = 0 WHERE tree_key = new.tree_key; END; -- ------------------------------------------------------ /* Initialize usn */ INSERT INTO usn (value) VALUES (0); /* Create root object */ INSERT INTO ldb_object (tree_key, parent_tree_key, dn, object_type, max_child_num) VALUES ('', NULL, '', 1, 0); /* We need an implicit "top" level object class */ INSERT INTO ldb_attributes (attr_name, parent_tree_key) SELECT 'top', ''; -- ------------------------------------------------------ COMMIT; -- ------------------------------------------------------ /* * dn: o=University of Michigan,c=US * objectclass: organization * objectclass: domainRelatedObject */ -- newDN BEGIN; INSERT OR IGNORE INTO ldb_object (parent_tree_key dn, attr_name, attr_value, object_type, max_child_num) VALUES ('', 'c=US', 'c', 'US', 1, 0); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('0001', 'o=University of Michigan,c=US', 'o', 'University of Michigan', 1, 0); -- newObjectClass INSERT OR IGNORE INTO ldb_attributes (attr_name, parent_tree_key, objectclass_p) VALUES ('objectclass', '', 1); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'objectclass', 'organization', 2, 0); INSERT OR IGNORE INTO ldb_attributes (attr_name, parent_tree_key, objectclass_p) VALUES ('objectclass', '', 1); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'objectclass', 'domainRelatedObject', 2, 0); COMMIT; /* * dn: o=University of Michigan,c=US * l: Ann Arbor, Michigan * st: Michigan * o: University of Michigan * o: UMICH * seeAlso: * telephonenumber: +1 313 764-1817 */ -- addAttrValuePair BEGIN; INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'l', 'Ann Arbor, Michigan', 2, 0); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'st', 'Michigan', 2, 0); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'o', 'University of Michigan', 2, 0); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'o', 'UMICH', 2, 0); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'seeAlso', '', 2, 0); INSERT INTO ldb_object (parent_tree_key, dn, attr_name, attr_value, object_type, max_child_num) VALUES ('00010001', NULL, 'telephonenumber', '+1 313 764-1817', 2, 0); COMMIT; -- ---------------------------------------------------------------------- /* * dn: @ATTRIBUTES * uid: CASE_INSENSITIVE WILDCARD * cn: CASE_INSENSITIVE * ou: CASE_INSENSITIVE * dn: CASE_INSENSITIVE */ -- newAttribute BEGIN; INSERT OR IGNORE INTO ldb_attributes (attr_name, parent_tree_key, objectclass_p) VALUES ('uid', '', 0); UPDATE ldb_attributes SET case_insensitive_p = 1, wildcard_p = 1, hidden_p = 0, integer_p = 0 WHERE attr_name = 'uid' UPDATE ldb_attributes SET case_insensitive_p = 1, wildcard_p = 0, hidden_p = 0, integer_p = 0 WHERE attr_name = 'cn' UPDATE ldb_attributes SET case_insensitive_p = 1, wildcard_p = 0, hidden_p = 0, integer_p = 0 WHERE attr_name = 'ou' UPDATE ldb_attributes SET case_insensitive_p = 1, wildcard_p = 0, hidden_p = 0, integer_p = 0 WHERE attr_name = 'dn' ldb-2.0.8/ldb_sqlite3/trees.ps0000660000000000000000000035166712406075657016147 0ustar rootroot00000000000000%!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software %%Title: trees.dvi %%Pages: 7 %%PageOrder: Ascend %%BoundingBox: 0 0 596 842 %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -f trees.dvi %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2000.05.06:2055 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet TeXDict begin 39158280 55380996 1000 600 600 (trees.dvi) @start %DVIPSBitmapFont: Fa cmr10 10 6 /Fa 6 55 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B 120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A2 6C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D48 DI54 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fb cmr7 7 3 /Fb 3 55 df48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 15267BA521>I54 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fc cmmi10 10 1 /Fc 1 69 df<0103B7FC4916E018F8903B0007F80007FE4BEB00FFF03F80020FED1FC018 0F4B15E0F007F0021F1503A24B15F81801143F19FC5DA2147FA292C8FCA25C18035CA213 0119F84A1507A2130319F04A150FA2010717E0181F4A16C0A2010FEE3F80A24AED7F0018 7E011F16FE4D5A4A5D4D5A013F4B5A4D5A4A4A5A057FC7FC017F15FEEE03FC91C7EA0FF0 49EC7FC0B8C8FC16FC16C03E397DB845>68 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fd ectt1000 10 73 /Fd 73 126 df37 D39 D<143814FC13011303EB07F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F 5B485AA2123F90C7FCA25A127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F 12037F6C7E6C7E137FEB3F80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C> I<127012FC7E7E6C7E6C7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0 A214F01303A214F81301A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F 1480133F14005B13FE485A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I< EB0380497EA60020140800F8143E00FE14FE00FF13C1EBC7C7EBE7CF003FB512F8000F14 E0000314806C140038007FFCA248B5FC481480000F14E0003F14F839FFE7CFFEEBC7C7EB 07C100FE13C000F8143E0020140800001400A66D5A1F247AAA2C>I<147014F8AF003FB6 12E0B712F8A4C700F8C7FCB0147025267DAB2C>II<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>46 D<1507ED0F80A2151F16005D153E157E157CA215FC5D14015D14035D14075D140F5D141F 92C7FC5C143EA2147E147C14FC5C13015C13035C13075C130F5C131F91C8FC5B133EA213 7E137C13FC5B12015B12035B12075B120F5B121F90C9FCA25A123E127E127C12FC5AA212 7021417BB92C>II<1307497EA2131F A2133F137F13FF5A1207127FB5FC13DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14 E01C3477B32C>II<000FB512FE4880A35D0180C8FCADEB83FE90389FFF8090B512E015F881 9038FE03FE9038F000FF01C07F49EB3F8090C7121F6C15C0C8120FA2ED07E0A4123C127E B4FC150F16C0A248141F007EEC3F80007FEC7F006C6C5B6D485A391FF80FFC6CB55A6C5C 000114C06C6C90C7FCEB0FF823347CB22C>53 DI<1278B712C016E0A316C000FCC7EA3F80ED7F0015FE00785CC712014A 5A4A5A5D140F5D4A5A143F92C7FC5C147E14FE5C13015CA2495AA213075CA3495AA4495A A5133F91C8FCAA131E23357CB32C>I59 D<1502ED0F80151F157F15 FF913803FE00EC0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390 C8FCEA07FCEA1FF8EA3FE0EAFF8090C9FCA27FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE0 6D7EEB07FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157F151F150FED 0200212A7BAD2C>I<007FB612F0B712F8A36C15F0CAFCA8007FB612F0B712F8A36C15F0 25127DA12C>I<122012F87EB4FC7FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE06D7EEB07 FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157FA215FF913803FE00EC 0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390C8FCEA07FCEA1F F8EA3FE0EAFF8090C9FC12FC5A1220212A7BAD2C>I<14FE497EA4497FA214EFA2130781 A214C7A2010F7FA314C390381F83F0A590383F01F8A490387E00FCA549137E90B512FEA3 4880A29038F8003FA34848EB1F80A4000715C049130FD87FFEEBFFFC6D5AB514FE6C15FC 497E27347EB32C>65 D<007FB512E015F8B612FE6C8016C03903F0003FED0FE0ED07F015 03A2ED01F8A6ED03F0A21507ED0FE0ED1FC0EDFF8090B612005D5D15FF16C09039F0001F E0ED07F0ED03F81501ED00FCA216FE167EA616FE16FC1501ED03F8150FED3FF0007FB612 E016C0B712806CECFE0015F027337FB22C>I<02FF13700107EBE0F84913F9013F13FD49 13FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148C7FCA25A00 7EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C13036D14F06C6C 130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13F001001380 25357DB32C>I<007FB5FCB612C015F0816C803907E003FEEC00FFED7F80153FED1FC0ED 0FE0A2150716F0150316F81501A4ED00FCACED01F8A3150316F0A2150716E0150FED1FC0 153FED7F80EDFF00EC03FE007FB55AB65A5D15C06C91C7FC26337EB22C>I<007FB612F0 B712F8A37E3903F00001A7ED00F01600A4EC01E04A7EA490B5FCA5EBF003A46E5A91C8FC A5163C167EA8007FB612FEB7FCA36C15FC27337EB22C>I<007FB612F8B712FCA37ED803 F0C7FCA716781600A515F04A7EA490B5FCA5EBF001A46E5A92C7FCAD387FFFE0B5FC805C 7E26337EB22C>I<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC 01497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE 5AA8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D 137F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC2635 7DB32C>II<007FB512F8B612FCA36C14 F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I75 D<387FFFE0B57EA36C5BD803F0C8FCB3AE16F0 ED01F8A8007FB6FCB7FCA36C15F025337DB22C>IIII<007FB512C0B612 F88115FF6C15802603F00013C0153FED0FE0ED07F0A2150316F81501A6150316F01507A2 ED0FE0ED3FC015FF90B61280160015FC5D15C001F0C8FCB0387FFF80B57EA36C5B25337E B22C>II<387FFFFCB67E15E015F86C803907E007FE1401EC007F6F7E151FA2 6F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E081819038E007FCEC01FE1400157F 81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8EA01F029347EB22C>I<90 381FF80790B5EA0F804814CF000714FF5A381FF01F383FC003497E48C7FC007E147F00FE 143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFCEBFFC06C13FC0003EBFFC06C 14F06C6C7F01077F9038007FFEEC07FF02001380153FED1FC0A2ED0FE0A20078140712FC A56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90B55A5D00F914F0D8F83F13C0 D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC007E007EA70078153CC71400 B3AF90383FFFFCA2497F6D5BA227337EB22C>I<3B7FFF803FFFC0B56C4813E0A36C496C 13C03B03F00001F800B3AF6D130300015DA26D130700005D6D130F017F495A6D6C485AEC E0FF6DB5C7FC6D5B010313F86D5B9038003F802B3480B22C>III<3A3FFF03FFE0484913F0148714076C6D13E03A01 F800FE007F0000495A13FE017E5BEB7F03013F5B1487011F5B14CF010F5B14FF6D5BA26D 90C7FCA26D5AA26D5AA2497EA2497EA2497F81EB0FCF81EB1FC7EC87F0EB3F83EC03F8EB 7F01017E7FEBFE00497F0001147E49137F000380491480151FD87FFEEBFFFC6D5AB514FE 6C15FC497E27337EB22C>II<387FFFFCB512FEA314FC00FCC7FCB3B3B3B512FC14FEA36C13FC 17416FB92C>91 D<127012F8A27E127C127E123E123F7EA27F120F7F12077F12037F1201 7F12007F137C137E133EA2133F7F80130F80130780130380130180130080147C147E143E A2143F8081140F81140781140381140181140081157CA2157E153E153F811680150FA2ED 070021417BB92C>I<387FFFFCB512FEA37EC7127EB3B3B3387FFFFEB5FCA36C13FC1741 7DB92C>II<007FB6FCB71280A46C150021067B7D 2C>I<1338137CEA01FC1203EA07F813F0EA0FC0EA1F80A2EA3F00123E127E127CA212FC 5AA3EAFFC013E013F013F8A2127FA2123F13F0EA1FE0EA07C00E1D72B82C>I<3801FFF0 000713FE001F6D7E15E048809038C01FF81407EC01FC381F80000006C77EC8127EA3ECFF FE131F90B5FC1203120F48EB807E383FF800EA7FC090C7FC12FE5AA47E007F14FEEB8003 383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003FF007FC27247CA32C>II<90 3803FFE0011F13F8017F13FE48B5FC48804848C6FCEA0FF0485A49137E4848131890C9FC 5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D133F6C6CEB7F003907FE03FF6CB55A 6C5C6C6C5B011F13E0010390C7FC21247AA32C>III103 DI< 1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7EA2EA0007B3A8007F B512FCB612FEA36C14FC1F3479B32C>I107 D<387FFFE0B57EA37EEA0003B3B3A5007F B61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1FF83AFFDFFE3FFCD8 7FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E013C0A301C01380B3 3B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D2481A32C>I<397F F01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC01F02807FEC000F5B 5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>II<397FF01FE0 39FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091380007F049EB03F8 5BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F9138801FE0 9138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFFE0B57EA36C5B2736 7FA32C>I<903903FC078090391FFF0FC0017F13CF48B512EF4814FF3807FE07380FF001 48487E49137F4848133F90C7FC48141F127E150F5AA87E007E141FA26C143F7F6C6C137F 6D13FF380FF0033807FC0F6CB6FC6C14EF6C6C138F6D130FEB07F890C7FCAD0203B5FC4A 1480A36E140029367DA32C>II<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA36CEB 00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007EC00 FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E000F8 148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8FCB1 ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003FE023 2E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D137F39 00FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A3FFF03FFF04801 8713F8A36C010313F03A00FC007E005D90387E01F8013F5BEB1F83EC87E090380FCFC090 3807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803EF80903807CFC0EB0FC7EC83 E090381F01F0013F7FEB7E00017C137C49137E0001803A7FFF01FFFC1483B514FE6C15FC 140127247EA32C>120 D<3A7FFF01FFFCB5008113FE148314816C010113FC3A03E0000F 806C7E151F6D140012005D6D133E137C017E137E013E137CA2013F13FC6D5BA2EB0F815D A2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC80A2143EA2147E147CA2 14FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C90C8FC6C5A6C5AEA07E0 27367EA32C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1F E013FF007F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E 1380141F14070200130021417BB92C>123 D<127812FCB3B3B3A9127806416DB92C>II E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fe ecti1000 10 33 /Fe 33 122 df28 D<150C151C153815F0EC01E0EC03C0EC0780EC0F00141E5C147C5C5C495A1303 495A5C130F49C7FCA2133EA25BA25BA2485AA212035B12075BA2120F5BA2121FA290C8FC A25AA2123EA2127EA2127CA412FC5AAD1278A57EA3121C121EA2120E7EA26C7E6C7EA212 001E5274BD22>40 D<140C140E80EC0380A2EC01C015E0A2140015F0A21578A4157C153C AB157CA715FCA215F8A21401A215F0A21403A215E0A21407A215C0140F1580A2141F1500 A2143EA25CA25CA2495AA2495A5C1307495A91C7FC5B133E133C5B5B485A12035B48C8FC 120E5A12785A12C01E527FBD22>I<4B7EA3150393C8FCA35D1506A3150E150CA3151C15 18A315381530A31570B912E0A2C80060C8FC15E05DA314015DA3140392C9FCA35C1406A3 140E140CA3141C1418A2333275AD40>43 DI<120E EA3F80127F12FFA31300127E123C0909778819>46 D<0103B612FEEFFFC018F0903B0007 F8000FF84BEB03FCEF00FE020F157FF03F804B141F19C0021F150F19E05D1807143F19F0 5DA2147FA292C8FCA25C180F5CA2130119E04A151FA2130319C04A153FA201071780187F 4A1600A2010F16FEA24A4A5A60011F15034D5A4A5D4D5A013F4B5A173F4A4AC7FC17FC01 7FEC03F84C5A91C7EA1FC04949B45A007F90B548C8FCB712F016803C397CB83F>68 D<0103B512F8A390390007F8005DA2140FA25DA2141FA25DA2143FA25DA2147FA292C7FC A25CA25CA21301A25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA213 7FA291C8FC497EB6FCA25C25397CB820>73 D<0107B512FCA25E9026000FF8C7FC5D5D14 1FA25DA2143FA25DA2147FA292C8FCA25CA25CA21301A25CA21303A25CA21307A25CA213 0F170C4A141CA2011F153C17384A1478A2013F157017F04A14E01601017F140317C091C7 1207160F49EC1F80163F4914FF000102071300B8FCA25E2E397BB834>76 D79 D81 D<92383FC00E913901FFF01C020713FC91 391FC07E3C91393F001F7C027CEB0FF84A130749481303495A4948EB01F0A2495AA2011F 15E091C7FCA34915C0A36E90C7FCA2806D7E14FCECFF806D13F015FE6D6D7E6D14E00100 80023F7F14079138007FFC150F15031501A21500A2167C120EA3001E15FC5EA3003E4A5A A24B5AA2007F4A5A4B5A6D49C7FC6D133ED8F9F013FC39F8FC03F839F07FFFE0D8E01F13 8026C003FCC8FC2F3D7ABA2F>83 D<0007B812E0A25AD9F800EB001F01C049EB07C0485A D900011403121E001C5C003C17801403123800785C00701607140700F01700485CA2140F C792C7FC5DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA21301A25CA21303A25C A21307A25CA2130FA25CEB3FF0007FB512F8B6FCA2333971B83B>I<14F8EB07FE90381F 871C90383E03FE137CEBF801120148486C5A485A120FEBC001001F5CA2EA3F801403007F 5C1300A21407485C5AA2140F5D48ECC1C0A2141F15831680143F1587007C017F1300ECFF 076C485B9038038F8E391F0F079E3907FE03FC3901F000F0222677A42A>97 D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0F8EBE7FE9038EF0F 80390FFC07C013F89038F003E013E0D81FC013F0A21380A2123F1300A214075A127EA214 0F12FE4814E0A2141F15C05AEC3F80A215005C147E5C387801F8007C5B383C03E0383E07 C0381E1F80D80FFEC7FCEA01F01C3B77B926>I<147F903803FFC090380FC1E090381F00 70017E13784913383901F801F83803F003120713E0120FD81FC013F091C7FC485AA2127F 90C8FCA35A5AA45AA3153015381578007C14F0007EEB01E0003EEB03C0EC0F806CEB3E00 380F81F83803FFE0C690C7FC1D2677A426>II<147F903803FFC090380FC1E09038 3F00F0017E13785B485A485A485A120F4913F8001F14F0383F8001EC07E0EC1F80397F81 FF00EBFFF8148090C8FC5A5AA55AA21530007C14381578007E14F0003EEB01E0EC03C06C EB0F806CEB3E00380781F83803FFE0C690C7FC1D2677A426>IIIII108 DII<147F903803FFC090380FC1F090381F00F8 017E137C5B4848137E4848133E0007143F5B120F485AA2485A157F127F90C7FCA215FF5A 4814FEA2140115FC5AEC03F8A2EC07F015E0140F007C14C0007EEB1F80003EEB3F00147E 6C13F8380F83F03803FFC0C648C7FC202677A42A>I<9039078007C090391FE03FF09039 3CF0787C903938F8E03E9038787FC00170497EECFF00D9F0FE148013E05CEA01E113C15C A2D80003143FA25CA20107147FA24A1400A2010F5C5E5C4B5A131F5EEC80035E013F495A 6E485A5E6E48C7FC017F133EEC70FC90387E3FF0EC0F8001FEC9FCA25BA21201A25BA212 03A25B1207B512C0A3293580A42A>I<3903C003F0390FF01FFC391E783C0F381C7C703A 3C3EE03F8038383FC0EB7F800078150000701300151CD8F07E90C7FCEAE0FE5BA2120012 015BA312035BA312075BA3120F5BA3121F5BA3123F90C9FC120E212679A423>114 D<14FE903807FF8090380F83C090383E00E04913F00178137001F813F00001130313F0A2 15E00003EB01C06DC7FC7FEBFFC06C13F814FE6C7F6D13807F010F13C01300143F141F14 0F123E127E00FE1480A348EB1F0012E06C133E00705B6C5B381E03E06CB45AD801FEC7FC 1C267AA422>II<01F013 0ED803FC133FD8071EEB7F80EA0E1F121C123C0038143F49131F0070140FA25BD8F07E14 0000E08013FEC6485B150E12015B151E0003141C5BA2153C000714385B5DA35DA24A5A14 0300035C6D48C7FC0001130E3800F83CEB7FF8EB0FC0212679A426>118 D<903907E007C090391FF81FF89039787C383C9038F03E703A01E01EE0FE3803C01F0180 13C0D8070014FC481480000E1570023F1300001E91C7FC121CA2C75AA2147EA214FEA25C A21301A24A1370A2010314F016E0001C5B007E1401010714C000FEEC0380010F1307010E EB0F0039781CF81E9038387C3C393FF03FF03907C00FC027267CA427>120 D<13F0D803FCEB01C0D8071EEB03E0D80E1F1307121C123C0038140F4914C01270A24913 1FD8F07E148012E013FEC648133F160012015B5D0003147E5BA215FE00075C5BA214015D A314035D14070003130FEBF01F3901F87FE038007FF7EB1FC7EB000F5DA2141F003F5C48 133F92C7FC147E147C007E13FC387001F8EB03E06C485A383C1F80D80FFEC8FCEA03F023 3679A428>I E %EndDVIPSBitmapFont %DVIPSBitmapFont: Ff cmsy10 10 1 /Ff 1 16 df15 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fg ecbx1000 10 36 /Fg 36 119 df<913803FFC0027F13F00103B512FC010FEB00FED93FF8133FD97FE0EBFF 8049485A5A1480484A13C04A6C1380A36F1300167E93C7FCA592383FFFC0B8FCA4000390 C7FCB3ABB5D8FC3F13FFA4303A7EB935>28 D45 DI<141E143E 14FE1307137FB5FCA3138FEA000FB3B3A5007FB61280A4213679B530>49 DI54 D58 D66 DII73 D76 DII< EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C 4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>III83 D85 DII<13 FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB 3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14 C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB9 35>98 D100 D<903803FF80011F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC 1FE05B003FEC0FF0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F 6C6C14F86D14F000071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025 257DA42C>II<161FD907FEEBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C13 8F003F15CF4990387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907 FE07FE48B512F86D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E0 6C15F86C816C815A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C 6C495AD81FF0EB07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I< EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412077EB3A9B512F8 A4153B7DBA1B>105 D<13FFB5FCA412077EAF92380FFFE0A4923803FC0016F0ED0FE0ED 1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0FFF496C7F80 6E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C 6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9038FE03F000FFEB 0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00150C92C7FC 91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13FF381FC00F 383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF806C14C06C 14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C6C14FC6C14 F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA55BA45BA25B 5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816CEBC3E09038 3FFFC06D1380903803FE001D357EB425>I118 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fh ecrm1000 10 89 /Fh 89 126 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I21 D27 DI30 D36 D<141FEC7FC0903801F0 E0903803C0600107137090380F803090381F00381518A25BA2133E133F15381530A21570 5D5D140190381F838092CAFC1487148E02DC49B51280EB0FF85C4A9039003FF8000107ED 0FC06E5D71C7FC6E140E010F150CD91DFC141C01391518D970FE143801E015302601C07F 1470D803805D00076D6C5BD80F00EBC00148011F5C4890380FE003003E6E48C8FC007E90 3807F8060203130E00FE6E5A6E6C5A1400ED7F706C4B13036F5A6F7E6C6C6D6C5B701306 6C6C496C130E6DD979FE5B281FF001F07F133C3C07F80FE03FC0F86CB539800FFFF0C690 26FE000313C0D91FF0D9007FC7FC393E7DBB41>38 D<121C127FEAFF80A213C0A3127F12 1C1200A412011380A2120313005A1206120E5A5A5A12600A1979B917>I<146014E0EB01 C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B120F90C7FCA25A121EA2123E A35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A26C7EA26C7E1378A27F7F130E 7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12707E7E7E120F6C7E6C7EA26C7E 6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F 80A31400A25B131EA2133E133C137C1378A25BA2485A485AA2485A48C7FC120E5A5A5A5A 5A13527CBD20>I<1530B3A8B912FCA2C80030C8FCB3A836367BAF41>43 D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A 12600A19798817>II<121C127FEAFF80A5EA7F00121C09097988 17>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A214011580A214 0315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA213015CA21303 91C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05BA212015B1203 90C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05AA21F537BBD2A >II III<1538A2157815F8A214011403 1407A2140F141F141B14331473146314C313011483EB030313071306130C131C13181330 1370136013C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AA 4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F890B5FC5D5D1580 92C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E03907C003F0496C 7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12FC00605C12704A 5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB1FE021397CB62A >II<12301238123E003FB612E0A316C05A168016 000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC1406140E5CA25C 1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA96DC8FC131E233A 7BB72A>III<121C127FEAFF80A5 EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<121C127FEAFF80A5 EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A 1206120E5A5A5A12600A3479A317>II<007FB812F8B912FCCCFCB0B912FC6C17F836147B9E41>I<12E01278121EEA07C0 EA01F0EA003C130FEB03C0EB00F0143C140FEC03E0EC00F8151EED0780ED01E0ED007816 1EEE07C0EE01F0EE003C170FEF03C0A2EF0F00173CEE01F0EE07C0041EC7FC1678ED01E0 ED0780031EC8FC15F8EC03E0020FC9FC143C14F0EB03C0010FCAFC133CEA01F0EA07C000 1ECBFC127812E0322E79AB41>II<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA202 0E7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D90180 7F81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7E A213E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 DI<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D 7BBA3C>IIIIIII<013FB512 E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C 5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>IIIIIIIII< D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F 003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< 003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>IIII89 D<003FB7FCA39039FC0001FE 01C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7 FCA24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB 0180A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E48 48495A49130FB8FCA329397BB833>II93 D<007FB81280B912C0A26C17 803204797041>95 D97 DIIII<147E903803FF8090 380FC1E0EB1F8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FC B3AB487E387FFFF8A31C3B7FBA19>IIIIIII<2703F00FF0EB1FE000FFD93FFCEB 7FF8913AF03F01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC 49D907F8EB0FC0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445 >I<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7E A25BA35BB3A3486C497EB500C1B51280A329257EA42E>II<3903F01F E000FFEB7FF89038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F8 49130116FC150016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614 C09039F7803F009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E> II<3807E01F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E0 9038FC0080491300A45BB3A2487EB512F0A31C257EA421>II<1318A51338A31378A313F812011203 1207001FB5FCB6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFE EB01F81A347FB220>IIIIII<003FB512FCA2EB8003D83E0013F8003CEB07F00038 EB0FE012300070EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495A A290387F000613FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48 EB03FC90B5FCA21F247EA325>II<126012F0B3B3B3 B3A91260045377BD17>I<12FCEAFFC0EA07F0EA01FCEA007E7F80131F80130FB3A78013 07806D7E6D7EEB007EEC1FF0EC07F8EC1FF0EC7E00495A495A495A5C130F5CB3A7131F5C 133F91C7FC137E485AEA07F0EAFFC000FCC8FC1D537ABD2A>I E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fi ecbx1440 14.4 34 /Fi 34 118 df28 D45 D<151E153E15FE1403140F147FEB07FF00 03B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A6007FB712FCA52E4E76CD42>49 DI<913807FFC0027F13FC0103B67E010F15E090 261FF80313F890267FC0007F01FEC7EA3FFE48488148486E138013FE486C6C6D13C08048 17E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300A24C5A5F4C5A4B5B4B13C0 030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E09238007FF8EE3FFE707E70 138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0FF0EA3FFC487EA2B5FCA218 FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD80FF04A1380D807FE91387F FE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114FCD9001F1380374F7BCD42 >I<17FC1601A216031607160FA2161F163F167FA216FF5D5DA25D5D5D167F153E157E15 FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14FC495A5C495A1307495A5C 49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E127E5ABA1280A5C901FCC7 FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FEEC01FED9FFF0133F91B65A 5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFCAC913807FF80023F13F891 B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E496E7E01F86E7E5B70138049 16C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212FF7FA218F0A25B5E6C4816 E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CECFFFCD803FE4913F02701FF E00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFCC8FC354F7ACD42>I58 D<932603FFF01407047F01FF5C0307B600E05B033F03F85B92B700FE5B02039126C003FF 5B020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC814949814901E082011F 498249498292CA7E4948834948835A4A83485B4885A2484984A2485B87A2485B87A25AA2 98C8FC91CFFCA2B5FCAE7E067FB7128080A37E95C76C90C7FC807EA36C7FA26C7FA26C7F 7E806C7F137F6D7E816D6D93B5FC01077F6D01F85D6D7F6D01FF5D023F01E0EC0FEF020F 01FCEC3FE30203903AFFE001FF81020091B6C6FC033F03FC133F030703F0130FDB007F02 801303040301F8CAFC595479D267>71 D73 D76 D78 D80 D<93381FFF800303B512FC033FECFFC0 92B712F00207D9F80113FE021F903AC0003FFF804A48C700077FDAFFF8020113F049496E 7F49496F7E49496F7E49496F7E4990C96C7F4948707F4948707F01FF854849707F4A8248 86A24849717E48864A83A2481B80A248497113C0A4481BE0A291CB7EA3B51AF0AF6C1BE0 A36E5FA26C1BC0A36C1B806E5FA26C1B006E5F6C62A26C6DD903FC4A5A6CDB0FFF5D6E49 EBC0016C4B01E05C6D6C90277E07F0035B6E9039F801F807902A3FFF01F000780F5B6D04 7C5C6DD981E06D4890C7FC6D01E191381F7FFE010101F1EDFFF86DD9F9F06D5BDA3FFF16 C06E6D013F5B02079027FE01FFFEC8FC020190B612F8DA003F4B141003071838DB001FEB 83F893C7EA03FC1C7885726C14F8F2C003F2F01F97B512F084A31CE085A27314C01C8085 1C00735B735B735B735B9638003FC0556A79D263>III<003FBB12FCA59126C0007FEB000301FCC7ED003FD87FF0F00FFE491807 49180349180190C81600A2007E1A7EA3007C1A3EA500FC1A3F481A1FA6C91700B3B3AC49 B912C0A550517BD05B>I97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB 07FC4948497E4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92 C8FC5BA312FFAD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E 6C6D5C6D6C495A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203 138031387CB63A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F8 49B512FE0107ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048 4980484980488291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D 5C5F6C6D91B5FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F 010114FC6D6C13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01 076E7E011F010313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E488248 90C77E1880485A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F12 3FA2EF03E06C7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495A D91FFFEB07F86D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C >IIII<133FEBFFC0 487F487FA2487FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B6 12F0A51C547CD324>I108 DII<913801FFC0023F13FE91B67E010315E001 0F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F48496D7F91C8127F4883 488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F1800A3003F5F6D153F A2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990C7FCD93FFCEB1FFE 6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387CB642>II<90393FF001FCB590 380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC6CEBF3E015C0ECF7 80A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E367DB535>114 D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF0130F484813034848 1301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF806C13FEECFFF06C 14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0EC003F030713E0 150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001F85C6DEB03FE90 39FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387CB634>I<147CA6 14FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512FEB7FCA426007F FCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEBFFF001005C023F 1380DA03FEC7FC294D7ECB33>II E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fj ecrm0900 9 5 /Fj 5 109 df<123C127E12FFA4127E123C08087A8715>46 D97 DI104 D108 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fk ecbx0900 9 7 /Fk 7 117 df65 D97 DI<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB 007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fl ecrm1200 12 25 /Fl 25 122 df<121EEA7F8012FF13C0A213E0A3127FEA1E601200A413E013C0A3120113 80120313005A1206120E5A5A5A12600B1D78891B>44 D<14FF010713E090381F81F89038 3E007C01FC133F4848EB1F8049130F4848EB07C04848EB03E0A2000F15F0491301001F15 F8A2003F15FCA390C8FC4815FEA54815FFB3A46C15FEA56D1301003F15FCA3001F15F8A2 6C6CEB03F0A36C6CEB07E0000315C06D130F6C6CEB1F806C6CEB3F00013E137C90381F81 F8903807FFE0010090C7FC28447CC131>48 D50 D54 D<16C04B7EA34B7EA34B7EA34B7EA3ED 19FEA3ED30FFA203707FED607FA203E07FEDC03FA2020180ED801FA2DA03007F160FA202 06801607A24A6D7EA34A6D7EA34A6D7EA20270810260147FA202E08191B7FCA249820280 C7121FA249C87F170FA20106821707A2496F7EA3496F7EA3496F7EA201788313F8486C83 D80FFF03037FB500E0027FEBFFC0A342477DC649>65 DI68 D77 D<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA20070 181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>84 D I97 D99 D<167FED3FFFA315018182B3EC7F80903803 FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B000F81485AA2485AA2 127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C6C6C9038077F806C6C 010E13C0013F011C13FE90380FC0F8903803FFE09026007F0013002F467DC436>II103 D105 D108 D<3901FC01FE00FF903807FFC091381E 07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA25BA35BB3A8 486CECFF80B5D8F83F13FEA32F2C7DAB36>110 DI<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC00 7E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 D<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800F8 1438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0 011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14 F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130E A4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C 017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC26 >III< B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E0000150C6D141C6D1418A2 6E1338013F1430A26D6C5BA26E13E0010F5CA26D6C485AA2ECF803010391C7FCA2903801 FC06A2ECFE0E0100130CA2EC7F18A215B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA214 06A35CA25CA2123C007E5BB4FC5CA25CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03 F02E3F7EAA33>121 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fm ecbx1200 12 47 /Fm 47 123 df<0118140C017C143E01FC147E48485C4848495A495C4848495A4848495A 001F140F90C75B003E4AC7FCA2003C141E007C143E0078143CA200F8147CA2481478D8F1 F014F8D8F7FCEB7BFEB46CEB7FFF6D1580028014C0A36C80A36C806C496C13806C486D13 006C486D5AD801F0EB00F82A2283C427>16 DI28 D46 D48 DIII<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7140715 C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E5BA25B 485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280A53141 7DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15E092C8 FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01FC6D7E 01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF7FA317 F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD807FEEB FFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E021F13F0 027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFFE04849 5A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC91381F FF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A6C13C0 5B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C15C06D 4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC903800 3FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248168000 7EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E5DA24A 5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D5A6D5A 6D5A2F447AC238>I58 D<1A60F101F01907191FF17FC0953801FF00F007FCF01FF0F07FC04D48C7FCEF07 FCEF3FF0EFFFC0040390C8FCEE0FFCEE3FE0EEFF80DB03FEC9FCED0FF8ED3FE0EDFF80DA 07FECAFCEC1FF8EC7FE0903801FF80D907FCCBFCEB1FF0EB7FC04848CCFCEA07FCEA1FF0 EA7FC048CDFCA2EA7FC0EA1FF0EA07FCEA01FF38007FC0EB1FF0EB07FC903801FF809038 007FE0EC1FF8EC07FE913800FF80ED3FE0ED0FF8ED03FE923800FF80EE3FE0EE0FFCEE03 FF040013C0EF3FF0EF07FCEF01FF9438007FC0F01FF0F007FCF001FF9538007FC0F11FF0 19071901F10060444277B957>60 D<126012F812FE6C7EEA3FE0EA0FF8EA03FEC66C7EEB 3FE0EB0FF8EB03FE903800FFC0EC3FF0EC0FFCEC03FF9138007FC0ED1FF0ED07FCED01FF 9238007FC0EE1FF0EE07FE933801FF809338007FE0EF1FF8EF03FE943800FF80F03FE0F0 0FF8F003FE953800FF80F13FE0F10FF0A2F13FE0F1FF80953803FE00F00FF8F03FE0F0FF 80DD03FEC7FCEF1FF8EF7FE0933801FF80DC07FEC8FCEE1FF0EE7FC04B48C9FCED07FCED 1FF0ED7FC0DA03FFCAFCEC0FFCEC3FF0ECFFC0D903FECBFCEB0FF8EB3FE0EBFF80D803FE CCFCEA0FF8EA3FE0EAFF8048CDFC12F81260444277B957>62 D<923803FFF0037FEBFF80 0203B612F0020F15FC913A3FFC000FFFDAFFC0010013C0D903FEC8EA1FF0D907F0ED03F8 D91FC0ED00FE4948167F017ECAEA1F8049717E4848717E49DAFF8013034848010F01F06D 7E4848013F01FC6D7E92B6FC4848489026C07F80137C49489026001FC0133C484948D907 E0133E001E49486D6C131E003E49480101141F023F913800FFE0003C4A82007C017F1880 007819074A5AA300F81AC04848491603AB6C6C7F12781B801A076E7E127C003C133F003E 6E1700021F4A5C001E6D6C5B001F6D6C49EBF01E6C6D6C011F143E6D6CD9C07F6D5A6C6C 6C90B5383FFFF8033FD9FC0F5B6C6C010FD9F0035B6C6C0100903980007F806D91CBFC6C 7E137E6D7E6D6CEF7FC0D907F0EE03FFD903FE043F1300902600FFC0913803FFF8DA3FFC 49B512C0020FB748C7FC020316E0DA007F02FCC8FC030349C9FC4A477AC557>64 DIIII73 D77 D<923807FFC092B512FE0207ECFFC0021F15F0 91267FFE0013FC902601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E4948 6F7E49486F7E01FF8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F049 82003F19F8A3007F19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19 F0A26E5D6C19E0A26C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D 6C4A5B6D01C001075B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002 004AC8FC030713C047467AC454>79 D83 D<007FBA12E0BB12F0A46C19E04406776757>95 D<903801FFE0011F13FE017F6D 7E48B612E03A03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F0 90C7FCA40203B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B 127F5B12FF5BA35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF8 6CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97 DIIIIIII<137C48B4FC4813804813C0A24813E0A56C13 C0A26C13806C1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520> I108 D<90277F8007FEEC0FFC B590263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D 8FC00FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7E A24A5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB59038 3FFF8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02 F86D7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>II<90397FC00FF8B590B57E02C314E002CF14F89139DFC03F FC9139FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF 3FFCACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07F FC02CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>II<90387F807FB53881FFE002 8313F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED 01E092C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F 381FF003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387F FFF014FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000 F0143FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A 00FC5CD8F03F13E026E007FEC7FC232F7CAD2C>II< D97FC049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F7 13FE9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I I120 D<001FB71280A49026FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B00 3C495BA24A90C7FC4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A49 48130F49481400A2485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4 292C7DAB32>122 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fn ecrm1728 17.28 8 /Fn 8 117 df68 D70 D97 D102 D<1378EA01FE487E487FA66C 90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203C6FCA2137FB3B3AC497E487F B61280A4195F7BDE25>105 D<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC091 3801E03F913903C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB 0600027090C7FCA2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE 381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F 13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 FC2A597ED734>I E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fo ecbx1728 17.28 18 /Fo 18 117 df68 D<942603FFF8151C94B66C 143C040F03F0147C047F03FC14FC0303B81301030FDAC00113C0033F01F8C7381FF00392 B500C0913807F807020349C83801FE0F020F01F89238007F1F4A01E0EE3FBF4A49EE0FFF 91B5CA7E494983494983494983495B4949187F4B183F491A1F495B90B5CC120FA2484919 075A4A19035A4A19015AA24A19005AA348491A7CA35A9AC8FCA35CA2B5FCB07EA26E043F B81280A47E96C7000701FCC7FCA26C7FA37E80A27E807E807E6C7FA26D7F6D7F7F816D7F 6D6D5F6D7F6D6D5F6D6D7E023F6D5E6E01F05E6E6DEEFE7F020301FF923801FC3F020002 C0913807F80F033F01FC91381FF007030F903BFFE001FFC001030391B6EA8000DB007F4B C7123C040F03F8140C040003C091C8FC050301F8CBFC696677E37A>71 D82 D<001FBD12F0A59126F8000191C7123F4801C0 060713F849C71700491A7F01F01A1F491A0F491A07A2491A03A290C81801A2007EF300FC A4007C1C7CA7481C3EA5C91900B3B3B3A5023FB912F8A55F617AE06C>84 D<913803FFF0027F13FF0103B612E0010F15F890263FFC0013FED97FC090381FFF8049C7 6C7F4801C06D7F486D6D7F6E6D7F48836E7F84177F84A36C496E7FA26C5B6C5B013FC8FC 90C9FCA75F0307B6FC4AB7FC141F91B5EAF03F0103EBFE00010F13F0013F1380D9FFFEC7 FC485B485B485B485B485B485BA24890C8FC1A7CA2485AA35FA394B5FC7F6C5D6EEB03DF 6CDB07CFEBC0F86C6DEB0F8F6C6DD91F07EBF3F06C01F8017E14FF6C9027FE01FC0314E0 C690B5D8F00114C0013F9126C0007F1380010791C7383FFE009026003FF8EC07F846437B C14D>97 D<903807FF80B6FCA5C6FC7F7FB3A9933801FFE0041F13FE047FEBFFC00381B6 12F0922687FC0113FC923A9FE0003FFEDBBF8090380FFF8003FEC76C7F4B6E7F4B6E7F4B 6E7F4B824B157F4B82737EA21B80851BC0A31BE085A41BF0AE1BE0A44F13C0A31B80A24F 1300A262197F6F5E6F4B5A4E5B6F4A5BDAFCF84A5BDAF87E4A5B4A6C4A90C7FC9126E01F C0EB7FFC913BC00FF803FFF8DA8003B612E091C71580013E023F01FCC8FC90C800031380 4C657CE356>II101 DII105 D<903807FF80B6FCA5C6FC7F7FB3B3B3B3AFB7 12E0A523647CE32A>108 D110 D<92381FFF804AB512F8020F 14FF023F15C09126FFFC0313F001039039E0007FFC490180EB1FFED91FFEC73807FF8049 486E7F49486E7F49486E7F48496F7EA248496F7E4884A248496F7EA2481980A24819C091 C97EA24819E0A5B518F0AD6C19E0A46C6D4B13C0A36C1980A26C6D4B1300A26C606E157F 6C606C6D4B5A6C606D6C4A5B6D6C4A5B6D6C4A5B6D6C6C011F90C7FC010301E0EB7FFC6D 9039FC03FFF86D6CB612E0020F92C8FC020114F8DA001F138044437CC14D>I<903B07FF 8001FFE0B6011F13FE047FEBFFC00381B612F0922687FC0313FC923A9FE0007FFEC6DABF 806D6C7E6D01FEC7000F7F6D496E7F4B824B6E7F4B6E7F4B804B82737EA21B80851BC0A2 851BE0A4851BF0AE4F13E0A41BC061A21B80A24F1300A24F5AA26F4A5B6F4A5B626F4A5B 6F4A5B03FE4A5B03BF027F90C7FCDB9FC0EBFFFC92268FF8075B0383B612E00380158004 3F01FCC8FC0403138093CBFCB3A4B712E0A54C5D7CC056>I114 DII E %EndDVIPSBitmapFont end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: A4 %%EndSetup %%Page: 1 1 1 0 bop 290 639 a Fo(Genealogical)56 b(Represen)l(tation)e(of)f(T)-13 b(rees)52 b(in)g(Databases)1686 822 y Fn(First)46 b(Draft)1247 1063 y Fm(Miguel)36 b(Sofer)i()1359 1179 y Fl(Univ)m(ersidad)33 b(T)-8 b(orcuato)33 b(Di)f(T)-8 b(ella)1728 1295 y(Buenos)33 b(Aires)1797 1411 y(Argen)m(tina)1746 1606 y(Ma)m(y)h(6,)e(2000)1839 1905 y Fk(Abstract)441 2035 y Fj(blah)25 b(blah)h(.)13 b(.)g(.)118 2310 y Fi(1)131 b(In)l(tro)t(duction)118 2491 y Fh(T)-7 b(rees)28 b(are)h(a)g(v)n(ery)f (frequen)n(t)h(data)f(structure.)41 b(They)30 b(are)e(the)h(natural)g (represen)n(tation)e(for)i(instance)g(for)f(organiza-)118 2591 y(tional)f(c)n(harts,)g(threaded)g(discussion)g(groups,)f(some)h (bills)g(of)h(materials,)e(.)14 b(.)g(.)243 2691 y(A)n(t)28 b(least)f(t)n(w)n(o)f(alternativ)n(e)h(represen)n(tations)e(for)i (trees)g(in)h(RDBMs)g(are)e(kno)n(wn)h(and)h(used:)220 2857 y(1.)41 b Fg(P)m(oin)m(ters:)k Fh(a)31 b(\034eld)h(in)h(the)f(c)n (hild)g(record)e(references)h(the)h(paren)n(t)f(no)r(de.)50 b(This)32 b(seems)g(to)f(b)r(e)i(the)f(canonical)326 2956 y(represen)n(tation.)38 b(Some)29 b(DB)g(engines)f(pro)n(vide)g (sp)r(ecial)g(SQL)g(extensions)g(to)h(simplify)g(tree)g(searc)n(hes;)e (Oracle)326 3056 y(tree)d(extensions)g(are)g(an)h(example)f(\(see)h (for)f(instance)g([1]\);)i(DB2's)f(WITH)g(can)f(b)r(e)i(used)e(for)h (this)g(purp)r(ose)f(to)r(o)326 3156 y(\(see)j([3],)g(pp)h(139-162\).) 220 3322 y(2.)41 b Fg(Nested)35 b(Sets:)43 b Fh(t)n(w)n(o)30 b(n)n(umeric)h(\034elds)g(in)g(ev)n(ery)f(no)r(de)h(record)f(co)r(de)h (the)g(tree)g(structure.)47 b(I)31 b(can't)g(pro)n(vide)f(a)326 3421 y(b)r(etter)e(or)e(briefer)h(description)g(of)h(this)g(metho)r(d)g (than)f(the)h(four)f(articles)g([2].)118 3587 y(These)g(t)n(w)n(o)g (metho)r(ds)h(o\033er)f(di\033eren)n(t)h(adv)-5 b(an)n(tages)25 b(and)j(disadv)-5 b(an)n(tages:)243 3753 y Ff(\017)41 b Fh(P)n(oin)n(ters)30 b(are)g(extremely)g(e\036cien)n(t)h(for)f(no)r (de)h(insertion)f(and/or)g(deletion,)h(but)h(require)e(recursiv)n(e)f (table)i(ac-)326 3853 y(cesses)e(to)h(searc)n(h)f(the)h(tree)g(\(I)h (do)f(not)g(kno)n(w)f(the)i(implemen)n(tation)f(details)g(of)g(the)h (Oracle)e(tree)g(extensions,)326 3953 y(whic)n(h)e(as)g(far)g(as)g(I)g (kno)n(w)g(ma)n(y)g(solv)n(e)f(this)i(problem)f(in)n(ternally;)g(they)g (de\034nitely)h(solv)n(e)f(it)g(for)g(the)h(end)g(user\).)243 4119 y Ff(\017)41 b Fh(Nested)30 b(sets)g(are)f(v)n(ery)f(e\036cien)n (t)i(for)g(tree)f(searc)n(hes,)g(but)i(are)e(rather)f(exp)r(ensiv)n(e)i (for)f(no)r(de)h(insertion)f(and/or)326 4218 y(deletion:)37 b(they)27 b(require)g(up)r(dating)g(p)r(oten)n(tially)h(man)n(y)f(no)r (des.)243 4384 y(W)-7 b(e)30 b(prop)r(ose)f(here)h(a)g(di\033eren)n(t)h (represen)n(tation,)e(based)g(on)i(no)r(de)f(iden)n(ti\034ers)g(whic)n (h)g(are)f(\020genealogical)f(iden)n(ti-)118 4484 y(\034ers\021:)44 b(they)32 b(con)n(tain)f(the)h(complete)f(genealogy)f(of)h(the)h(no)r (de,)h(i.e.,)g(the)f(list)g(of)g(ancestors)d(up)j(to)g(the)g(ro)r(ot)f (of)g(the)118 4584 y(tree.)243 4683 y(This)j(allo)n(ws)f(to)i(replace)e (man)n(y)h(searc)n(hes)f(in)h(database)g(tables)g(with)h(string)f(op)r (erations)f(on)h(the)h(index.)58 b(The)118 4783 y(result,)24 b(as)f(explained)h(in)g(Section)g(3)f(is)h(that)g(tree)f(searc)n(hes)f (pro)r(ceed)h(at)h(\020nested)f(sets\021)30 b(sp)r(eed,)25 b(while)f(no)r(de)g(insertions)118 4882 y(and)k(deletions)f(are)f(as)h (fast)h(as)f(with)h(p)r(oin)n(ters.)243 4982 y(The)i(ob)n(vious)f(do)n (wnside)h(of)h(the)g(metho)r(d)g(is)f(that)h(the)g(primary)f(k)n(ey)f (in)i(the)g(tree)f(needs)h(to)f(b)r(e)h(a)g(v)-5 b(ariable)29 b(size)118 5082 y(text)j(\034eld,)h(and)f(that)g(the)g(iden)n (ti\034ers)f(ma)n(y)g(b)r(e)i(extremelly)e(long)g(for)g(deep)h(trees.) 49 b(W)-7 b(e)32 b(will)g(pro)n(vide)e(estimates)i(of)118 5181 y(the)c(size)f(required)g(as)g(a)g(function)h(of)g(the)f (magnitude)h(of)f(the)h(tree.)1987 5653 y(1)p eop %%Page: 2 2 2 1 bop 118 291 a Fi(2)131 b(Genealogical)45 b(iden)l(ti\034ers)g(for)f (trees)118 489 y Fm(2.1)112 b(De\034nition)118 642 y Fh(W)-7 b(e)28 b(de\034ne)g Fe(gene)l(alo)l(gic)l(al)k(identi\034ers)j Fh(recursiv)n(ely)25 b(as)i(follo)n(ws:)326 808 y Fg(De\034nition:)59 b Fe(The)42 b(gene)l(alo)l(gic)l(al)h(identi\034er)f(\(gID\))e(of)i(a)f (no)l(de)h(is)f(obtaine)l(d)h(by)g(app)l(ending)g(a)f(child)326 908 y(identi\034er)30 b(to)g(the)g(gene)l(alo)l(gic)l(al)h (identi\034er)g(of)f(the)g(p)l(ar)l(ent)f(no)l(de.)243 1074 y Fh(Remark)40 b(that)h(genealogical)e(iden)n(ti\034ers)i(are)f (rather)g(w)n(ell)h(kno)n(wn)f(and)h(used;)48 b(common)41 b(examples)f(are)g(the)118 1174 y(\020path+\034le-name\021)33 b(in)28 b(a)f(computer)g(\034le)h(system)f(and)h(the)f(URLs)h(within)g (a)f(WWW.)243 1273 y(The)d(name)g(\020genealogical)e(iden)n (ti\034er\021)30 b(is)24 b(suggested)g(b)n(y)g(the)g(fact)h(that)f(the) h(v)-5 b(alue)24 b(of)g(the)h(iden)n(ti\034er)f(con)n(tains)f(the)118 1373 y(complete)30 b(genealogy)d(of)j(the)g(no)r(de:)41 b(it)30 b(con)n(tains)e(as)h(a)h(substring)f(the)h(gID)f(of)h(its)g (father,)g(whic)n(h)f(in)h(turn)g(con)n(tains)118 1472 y(as)d(a)g(substring)g(the)h(gID)g(of)f(the)h(grandfather,)e(.)14 b(.)g(.)243 1572 y(The)27 b(ro)r(ot)g(no)r(de)h(of)f(the)h(tree)f(has)g (a)h(gID)f(with)h(v)-5 b(alue)28 b(\021)34 b(\(the)28 b(empt)n(y)g(string\),)f(as)g(it)h(has)f(no)g(paren)n(t.)118 1804 y Fm(2.2)112 b(Child)36 b(iden)m(ti\034ers)118 1958 y Fh(The)26 b(ob)n(vious)e(c)n(hild)i(iden)n(ti\034er)g(is)f(a)h (zero-based)d(coun)n(ter:)35 b(iden)n(tify)26 b(the)h(c)n(hild)e(b)n(y) h(the)g(n)n(um)n(b)r(er)f(of)h(older)f(brethren)g(it)118 2057 y(has.)243 2157 y(W)-7 b(e)25 b(could)f(represen)n(t)g(the)h(coun) n(ter)f(in)h(base)f(10;)h(this)g(ho)n(w)n(ev)n(er)e(is)i(extremely)f(w) n(asteful)g(of)h(resources.)34 b(It)25 b(is)g(m)n(uc)n(h)118 2257 y(b)r(etter)33 b(to)f(represen)n(t)f(the)h(coun)n(ter)g(in)g(as)g (large)e(a)i(base)g(as)f(p)r(ossible:)46 b(in)n(terpret)32 b(as)f(n)n(um)n(b)r(ers)h(a)g(set)g(of)g(c)n(haracters)118 2356 y(larger)26 b(than)h({0,1,.)14 b(.)g(.)g(9}.)243 2456 y(As)26 b(tree)f(op)r(erations)f(will)i(in)n(v)n(olv)n(e)f(string) g(op)r(erations)f(on)i(the)g(indices,)g(in)g(order)f(to)g(a)n(v)n(oid)g (a)g(\020quoting)g(hell\021)33 b(it)26 b(is)118 2555 y(desirable)d(to)h(a)n(v)n(oid)e(using)h(an)n(y)g(c)n(haracter)f(with)i (a)g(sp)r(ecial)f(meaning)h(in)g(LIKE)g(expressions)e(or)g(regular)g (expressions;)118 2655 y(i.e.,)28 b(w)n(e)f(will)h(not)f(use)h(an)n(y)f (of)g(the)h(sym)n(b)r(ols)70 b Fd(.)44 b(*)f(^)g(\\)g([)g(])g({)h(})f (\()g(\))g(<)g(>)71 b Fh(?)37 b(|)28 b(&)f($)243 2755 y(W)-7 b(e)28 b(prop)r(ose)e(to)h(reserv)n(e)f(also)g(/)i(as)f(a)g (separator)e(\(see)i(\020V)-7 b(ariable)27 b(Sized)g(gID\021)34 b(b)r(elo)n(w\).)243 2854 y(If)g(w)n(e)f(limit)i(ourselv)n(es)d(to)i (ascii)f(c)n(haracters,)g(and)h(a)n(v)n(oid)e(to)i(b)r(e)g(safe)f(a)h (lot)g(of)g(other)f(c)n(haracters,)g(w)n(e)g(can)h(use)118 2954 y(n)n(um)n(b)r(ers)27 b(in)h(base)f(64)g(b)n(y)g(represen)n(ting) 243 3120 y Ff(\017)41 b Fh(0-9)26 b(with)i('0'-'9')f(\(dec)g(ascii)g (co)r(de)h(48-57\))243 3286 y Ff(\017)41 b Fh(10)26 b(with)i(':')37 b(\(dec)28 b(ascii)f(co)r(de)h(58\))243 3452 y Ff(\017)41 b Fh(11)26 b(with)i(';')g(\(dec)g(ascii)f(co)r(de)g(59\))243 3618 y Ff(\017)41 b Fh(12-37)25 b(with)j('A'-'Z')g(\(dec)f(ascii)g(co)r (de)h(65-90\))243 3784 y Ff(\017)41 b Fh(38-63)25 b(with)j('a'-'z')f (\(dec)h(ascii)f(co)r(de)g(97-122\))118 3950 y(By)g(using)g(base)f(64,) h(up)g(to)h(4096)d(c)n(hildren)i(can)f(b)r(e)i(represen)n(ted)e(using)h (t)n(w)n(o)f(suc)n(h)h(digits,)g(up)h(to)f(262144)d(with)k(three)118 4050 y(digits,)g(and)f(up)h(to)f(16777216)d(with)k(four)f(digits.)243 4149 y(If)37 b(the)g(RDBMs)g(supp)r(orts)f(in)n(ternational)g(c)n (haracters,)h(it)g(is)g(p)r(ossible)f(to)h(further)f(increase)g(the)h (base;)k(as)36 b(an)118 4249 y(example,)30 b(b)n(y)f(using)g(the)h(95)f (additional)g(c)n(haracters)e(of)i(the)h(latin-1)f(c)n(haracter)e(set,) k(w)n(e)e(could)g(co)r(de)g(n)n(um)n(b)r(ers)g(in)h(a)118 4349 y(base)f(up)g(to)g(160)f(\025)g(remark)g(that)h(ev)n(ery)f(single) h(digit)g(is)g(still)h(one)e(b)n(yte)h(in)h(this)f(represen)n(tation.) 40 b(This)29 b(means)f(that)118 4448 y(w)n(e)f(expand)h(the)f(sym)n(b)r (ols)g(ab)r(o)n(v)n(e)f(b)n(y)i(represen)n(ting)243 4614 y Ff(\017)41 b Fh(64-159)25 b(with)j(dec)f(latin1)g(co)r(de)h(160-255) 243 4780 y(In)23 b(base)g(160,)g(up)g(to)h(25600)d(c)n(hildren)i(can)f (b)r(e)i(represen)n(ted)e(using)h(t)n(w)n(o)g(digits,)h(up)g(to)f (4096000)d(with)k(three)f(digits,)118 4880 y(and)28 b(up)f(to)h (6.5E+08)e(with)i(four)f(digits.)243 4980 y(Remark)g(that)h(base)f(con) n(v)n(ersions)f(only)h(need)i(to)e(b)r(e)i(p)r(erformed)e(at)h (insertion)g(time,)g(when)h(the)f(index)g(of)g(a)g(new)118 5079 y(no)r(de)g(is)f(computed.)37 b(They)28 b(will)f(therefore)g(only) g(ha)n(v)n(e)f(an)i(impact)f(on)h(insertion)f(timings.)1987 5653 y(2)p eop %%Page: 3 3 3 2 bop 118 291 a Fm(2.3)112 b(Coun)m(ters:)50 b(\020delimited\021)44 b(vs.)51 b(\020\034xed)38 b(size\021)118 444 y Fh(The)33 b(standard)g(represen)n(tation)e(of)i(gID)h(uses)e(a)h(v)-5 b(ariable)32 b(size)h(c)n(hild)h(iden)n(ti\034er,)g(and)f(delimiters)g (to)h(separate)d(the)118 543 y(gID)f(of)g(the)h(c)n(hild)f(no)r(de)g (from)f(the)i(gID)f(of)g(its)g(paren)n(t.)43 b(F)-7 b(or)30 b(example,)g(w)n(e)g(can)f(represen)n(t)g(the)i(\034fth)g(c)n(hild)f (of)g(no)r(de)118 643 y('/23/27/1')24 b(as)j('/23/27/1/4'.)32 b(Let)c(us)f(call)g(this)h(a)f Fg(vgID)h Fh(represen)n(tation)e(\(V)-7 b(ariable)27 b(Size)h(Genealogical)d(ID\).)243 743 y(This)30 b(represen)n(tation)f(allo)n(ws)f(for)i(an)n(y)g(n)n(um)n(b)r(er)g(of)g (c)n(hildren)g(of)h(a)f(no)r(de,)h(sub)5 b(ject)30 b(only)g(to)g(the)h (limitations)f(the)118 842 y(RDBMS)e(ma)n(y)f(ha)n(v)n(e)f(as)h(to)h (the)g(length)f(of)h(a)f(v)-5 b(ariable)27 b(sized)g(string.)243 942 y(Alternativ)n(ely)-7 b(,)24 b(w)n(e)f(could)h(c)n(ho)r(ose)f(to)h (limit)g(from)g(the)g(outset)g(the)g(quan)n(tit)n(y)g(of)f(c)n(hildren) h(that)g(a)g(no)r(de)g(ma)n(y)f(ha)n(v)n(e;)118 1042 y(this)28 b(limit)g(w)n(ould)f(dep)r(end)i(of)e(course)f(on)i(the)g (application.)36 b(Let)27 b(us)h(call)f(this)h(a)f Fg(fgID)h Fh(represen)n(tation.)243 1141 y(F)-7 b(or)25 b(example,)h(if)g(no)g (no)r(de)f(is)h(allo)n(w)n(ed)f(to)g(ha)n(v)n(e)g(more)g(than)h(25600)d (c)n(hildren,)j(w)n(e)g(could)f(represen)n(t)g(the)h(coun)n(ters)118 1241 y(alw)n(a)n(ys)36 b(with)i(2)f(digits.)67 b(The)38 b(no)r(de)f(whic)n(h)h(w)n(as)f(previously)f('/23/27/1/4')d(is)k(no)n (w)g('23270104'.)64 b(If)38 b(w)n(e)f(require)118 1340 y(a)g(three)g(digit)h(represen)n(tation)d(of)i(no)r(des)g(\(up)h(to)f (ab)r(out)h(4)f(million)g(c)n(hildren\),)j(then)d(it)h(will)g(b)r(e)f (represen)n(ted)f(as)118 1440 y('023027001004'.)118 1672 y Fm(2.4)112 b(Ordering)37 b(of)h(no)s(des)118 1825 y Fh(F)-7 b(or)35 b(some)g(applications)g(it)h(is)f(necessary)f(to)i (obtain)f(subtrees)g(ordered)f(according)g(to)i(some)f(sp)r(ecial)g (rules.)60 b(F)-7 b(or)118 1925 y(instance:)220 2090 y(1.)41 b(the)34 b(complete)g(subtree)f(starting)g(at)h(a)f(no)r(de)h (is)g(listed)g(immediately)g(after)f(the)i(no)r(de)f(in)g(question)f (\(\020depth)326 2189 y(\034rst\021\))220 2354 y(2.)41 b(no)r(des)27 b(with)h(a)f(common)g(paren)n(t)g(are)g(listed)g(c)n (hronologically)243 2519 y(F)-7 b(or)39 b(instance,)k(the)d(displa)n(y) f(of)h(an)f(organization)f(c)n(hart)h(is)g(usually)h(required)e(to)i (satisfy)g(at)f(least)h(the)g(\034rst)118 2619 y(condition.)h(In)29 b(a)g(threaded)f(discussion)h(group)e(one)i(wishes)g(to)f(satisfy)h(b)r (oth)h(conditions)e(to)h(displa)n(y)f(the)h(messages)118 2718 y(in)20 b(a)g(thread)g(\025)f(the)i(threads)e(themselv)n(es)h (\(i.e.,)i(c)n(hildren)e(of)g(the)g(ro)r(ot)f(no)r(de\))i(are)e (usually)g(listed)i(in)f(in)n(v)n(erse)f(c)n(hronolical)118 2818 y(order.)243 2917 y(T)-7 b(o)35 b(mak)n(e)f(a)h(particular)f (ordering)g(e\036cien)n(t,)j(it)f(w)n(ould)f(b)r(e)h(a)f(nice)g (feature)g(if)h(it)g(could)f(b)r(e)h(made)f(to)g(coincide)118 3017 y(with)28 b(a)f(lexicographic)f(ordering)f(of)j(the)g(indices)f (\025i.e.,)g(as)g(pro)r(duced)g(b)n(y)h(an)f(\020ORDER)h(BY)f(id)h (ASC\021)35 b(in)27 b(SQL.)h(The)118 3117 y(lexicographic)d(ordering)h (of)h(fgID)h(satis\034es)e(b)r(oth)i(conditions.)36 b(The)27 b(lexicographic)f(ordering)f(of)i(vgID)g(as)g(describ)r(ed)118 3216 y(ab)r(o)n(v)n(e)34 b(satis\034es)g(the)h(\034rst)g(requisite)f (if)i(the)f(separator)d(has)j(the)g(minimal)g(binary)g(represen)n (tation)e(of)i(all)f(allo)n(w)n(ed)118 3316 y(sym)n(b)r(ols)c(in)h(an)f (index)h(\025)f(this)h(is)g(wh)n(y)f(w)n(e)g(reserv)n(ed)f(/)h(for)g (the)i(separator.)43 b(But)31 b(the)g(second)f(prop)r(ert)n(y)g(is)g (missing:)118 3416 y(for)d(instance,)g(the)h(index)g('/1/10')d(is)j (lexicographically)d(b)r(efore)i('/1/2'.)243 3515 y(If)c(the)h(second)e (prop)r(ert)n(y)g(is)i(also)e(required)g(for)h(vgID,)g(w)n(e)f(can)h (sp)r(ecify)h(the)f(c)n(hild)h(iden)n(ti\034ers)e(with)i(coun)n(ters)e (built)118 3615 y(in)28 b(the)g(follo)n(wing)e(w)n(a)n(y:)36 b(represen)n(t)26 b(a)h(n)n(um)n(b)r(er)h(b)n(y)f(a)g(string)g(of)g (digits,)h(where)243 3779 y Ff(\017)41 b Fh(the)25 b(\034rst)g(digit)h Fc(D)896 3791 y Fb(0)958 3779 y Fh(represen)n(ts)e(the)i(length)f(in)h (digits)f(of)g(the)h(decimal)f(expansion)f(of)i(the)f(n)n(um)n(b)r(er,) h(min)n(us)f(one)243 3945 y Ff(\017)41 b Fh(the)28 b(follo)n(wing)e Fa(\()p Fc(D)920 3957 y Fb(0)976 3945 y Fa(+)18 b(1\))27 b Fh(digits)h(are)e(the)i(decimal)g(expansion)e(of)i(the)g(n)n(um)n(b)r (er)118 4109 y(Let)g(us)f(call)h(these)f(iden)n(ti\034ers)g Fg(m-vgID)p Fh(,)g(\020m\021)34 b(for)27 b(mo)r(di\034ed.)243 4209 y(As)e(an)f(example,)h(the)g(no)r(de)g(whic)n(h)g(w)n(as)f (previously)f(represen)n(ted)h(b)n(y)g(/15/3/182)d(will,)k(after)g (this)g(mo)r(di\034cation,)118 4309 y(ha)n(v)n(e)h(the)i(index)g (/115/03/2182.)243 4408 y(The)37 b(lexicographic)f(ordering)g(of)i (m-vgID)f(is)h(the)g(desired)f(ordering)f(of)h(the)h(tree)g(no)r(des.) 67 b(The)38 b(cost)f(of)g(this)118 4508 y(prop)r(ert)n(y)31 b(is)i(that)f(\(a\))h(the)g(ID)f(are)g(no)n(w)g(longer,)g(\(b\))h(no)f (no)r(de)g(can)g(ha)n(v)n(e)g(more)f(than)i Fa(160)3106 4478 y Fb(160)3240 4508 y Fh(c)n(hildren)f(\(actually)-7 b(,)118 4607 y(this)32 b(is)g(a)f(non-issue\),)h(and)f(\(c\))h(the)g (index)g(structure)f(is)h(redundan)n(t,)g(some)f(formally)f(correct)h (indices)g(are)g(in)n(v)-5 b(alid)118 4707 y(\025e.g.,)24 b(/316/013/11.)30 b(The)24 b(third)g(issue)g(can)g(b)r(e)g(addressed)f (b)n(y)g(k)n(eeping)g(a)h(strict)g(con)n(trol)e(on)i(the)g(generation)f (of)h(new)118 4807 y(indices)k(to)f(insure)g(that)h(all)f(indices)h (are)e(formally)h(correct.)243 4906 y(The)32 b(issue)f(of)h(the)g(rev)n (erse)e(c)n(hronological)f(indexing)j(of)f(threads)h(in)g(threaded)f (discussion)g(groups)g(can)g(b)r(e)h(ad-)118 5006 y(dressed)d(easily)f (enough)h(in)h(fgID:)f(coun)n(t)g(\020do)n(wn\021)36 b(instead)29 b(of)g(\020up\021)36 b(the)30 b(c)n(hildren)f(of)g(the)h (ro)r(ot)e(no)r(de)i(\025)f(this)h(implies)118 5106 y(only)e(an)g (inconsequen)n(tial)f(mo)r(di\034cation)h(of)g(the)g(no)r(de)h (insertion)e(routine,)h(as)g(sho)n(wn)f(b)r(elo)n(w.)38 b(The)29 b(problem)e(is)h(less)118 5205 y(trivial)i(with)g(vgID;)h(in)f (this)h(case,)f(ma)n(yb)r(e)f(a)h(thread)g(iden)n(ti\034er)g(should)g (b)r(e)h(k)n(ept)f(in)g(a)g(di\033eren)n(t)g(\034eld)h(-)f(i.e.,)h (repre-)118 5305 y(sen)n(ting)h(the)h(structure)f(as)g(a)h(forest)f (rather)f(than)i(a)f(tree,)i(where)e(the)h(thread_id)f(\034eld)h (selects)f(the)h(\020tree\021)38 b(in)33 b(the)118 5404 y(forest.)1987 5653 y(3)p eop %%Page: 4 4 4 3 bop 118 291 a Fi(3)131 b(T)-11 b(ree)45 b(op)t(erations)e(using)h (genealogical)g(indices)118 472 y Fh(In)32 b(this)f(section)g(w)n(e)g (sho)n(w)g(ho)n(w)g(to)g(implemen)n(t)h(v)-5 b(arious)30 b(tree)h(op)r(erations)f(using)h(gID)g(as)g(the)h(primary)e(k)n(ey)h (in)g(the)118 572 y(no)r(de)d(table.)243 672 y(Some)h(implemen)n (tation)h(issues)g(are)f(relev)-5 b(an)n(t)29 b(here,)h(esp)r(ecially)f (concerning)g(the)h(utilisation)g(of)g(indices)g(b)n(y)f(the)118 771 y(DB)f(engine.)243 871 y(W)-7 b(e)28 b(discuss)f(a)g(tree)g (represen)n(ted)f(in)i(a)f(table)h(of)f(the)h(form)326 1034 y Fd(CREATE)41 b(TABLE)g(tree)h(\()456 1134 y(gid)304 b(text)42 b(PRIMARY)f(KEY,)456 1234 y(nchildren)f(integer)h(DEFAULT)f (0,)456 1333 y(\\ldots)h(the)i(actual)e(node)h(data)326 1433 y(\);)118 1597 y Fh(The)26 b(\034eld)g(\020nc)n(hildren\021)32 b(is)26 b(a)f(coun)n(ter)g(for)g(the)i(n)n(um)n(b)r(er)e(of)h(c)n (hildren)f(that)h(the)h(no)r(de)f(has)f Fe(ever)35 b Fh(had;)27 b(w)n(e)e(assume)g(here)118 1696 y(it)j(is)g(not)f(up)r (dated)h(when)g(no)r(des)f(or)g(subtrees)g(are)f(deleted.)243 1796 y(Section)h(4)g(pro)n(vides)f(a)i(complete)f(implemen)n(tation)h (of)f(these)h(op)r(erations)e(for)h(fgID)h(in)g(P)n(ostgreSQL.)118 2028 y Fm(3.1)112 b(Computing)37 b(the)g(lev)m(el)f(of)h(a)h(no)s(de) 118 2181 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations)g(\(no)g(table)g (ac)l(c)l(ess\))243 2280 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r (eration,)f(no)i(table)f(access)g(is)g(required.)243 2460 y Ff(\017)41 b Fg(vgID:)27 b Fh(coun)n(t)h(the)g(n)n(um)n(b)r(er)f (of)g(separators)e(\('/'\))j(in)g(the)g(PK)243 2625 y Ff(\017)41 b Fg(fgID:)27 b Fh(coun)n(t)g(the)h(n)n(um)n(b)r(er)g(of)f (c)n(haracters)e(in)j(the)g(PK,)g(divide)g(b)n(y)f(the)h(\034xed)f (size)h(of)f(the)h(coun)n(ters.)118 2857 y Fm(3.2)112 b(Selecting)36 b(or)h(deleting)f(a)i(subtree)118 3010 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 3173 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g (/26/5/7)e(is)i(selected)g(b)n(y)508 3338 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/26/5/7\045')d(AND)j(id)h(<)g('/26/5/70')243 3503 y Ff(\017)e Fg(m-vgID:)26 b Fh(The)h(subtree)h(ro)r(oted)e(at)i (/126/05/07)22 b(is)28 b(selected)f(b)n(y)508 3668 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07\045')243 3833 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g (260507)e(is)i(selected)h(b)n(y)508 3997 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('260507\045')118 4229 y Fm(3.3)112 b(Selecting)36 b(the)h(direct)f(c)m(hildren)g(of)i(a)g(no)s(de)118 4382 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 4562 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h (/26/5/7)c(are)j(selected)g(b)n(y)508 4727 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/26/5/7/\045')d(AND)j(id)h(NOT)f(LIKE)g ('26/5/7/\045/\045')243 4892 y Ff(\017)f Fg(m-vgID:)26 b Fh(The)h(direct)h(c)n(hildren)f(of)g(/26/5/7)e(are)h(selected)i(b)n (y)508 5056 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07/\045')37 b(AND)43 b(id)f(NOT)h(LIKE)f('/126/05/07/\045/\045)o(')243 5221 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h (260507)c(are)j(selected)g(b)n(y)508 5386 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('260507\045')d(AND)k(char_length\(id\))37 b(=)43 b(\(char_length\('26)o(05)o(07')o(\)+)o(2\))1987 5653 y Fh(4)p eop %%Page: 5 5 5 4 bop 118 291 a Fm(3.4)112 b(Inserting)37 b(a)h(no)s(de)g(or)f(a)h (subtree)118 444 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l (e)l(e)f(+)h(string)f(and)h(math)g(op)l(er)l(ations)243 543 y Fh(Insertion)f(is)g(a)h(pro)r(cedural)e(op)r(eration.)42 b(As)30 b(eac)n(h)f(RDBMS)h(has)f(a)h(di\033eren)n(t)f(w)n(a)n(y)g(of)g (de\034ning)h(pro)r(cedures,)f(w)n(e)118 643 y(will)f(just)g(describ)r (e)f(here)g(the)h(necessary)e(steps.)37 b(Examples)27 b(for)g(P)n(ostgreSQL)f(are)h(pro)n(vided)f(in)i(4.)243 743 y(In)22 b(order)f(to)h(insert)g(a)g(new)g(c)n(hild)h(of)f (\020daddy\021)28 b(\(either)23 b(one)f(of)g(/26/5/7,)e(/126/05/07)d (or)22 b(260507)d(in)k(the)f(examples)118 842 y(ab)r(o)n(v)n(e\))27 b(y)n(ou)f(ha)n(v)n(e)h(to)220 1008 y(1.)41 b(add)27 b(one)g(to)h(the)g(n)n(um)n(b)r(er)f(of)g(c)n(hildren)h(of)f (\020daddy\021)508 1174 y Fd(UPDATE)41 b(tree)h(SET)h(nchildren)c(=)k (\(nchildren)d(+)j(1\))g(WHERE)e(ID)i(=)g(``daddy'';)220 1340 y Fh(2.)e(enco)r(de)27 b(the)h(n)n(um)n(b)r(er)f(of)g(c)n(hildren) g(of)h(\020daddy\021)33 b(in)28 b(base)f(160,)f(bring)h(it)h(to)f(the)h (correct)e(format)h(dep)r(ending)h(on)326 1440 y(the)c(v)-5 b(arian)n(t)23 b(of)h(gID)g(\(pad)g(with)h(0)e(or)g(not,)i(prep)r(end)f (a)g(digit)g(coun)n(ter)f(or)g(not,)i(prep)r(end)f(/)g(or)f(not,)i (coun)n(t)e(do)n(wn)326 1540 y(or)j(up,)i(.)14 b(.)g(.)g(\))37 b(and)28 b(app)r(end)f(it)h(to)g(daddy's)f(gID)g(to)h(obtain)f(the)h (new)g(no)r(de's)f(gID.)220 1706 y(3.)41 b(insert)27 b(the)h(new)f(no)r(de)243 1872 y(When)35 b(inserting)g(a)f(subtree,)j (the)e(index)g(of)g(the)h(ro)r(ot)e(of)h(the)g(subtree)g(has)f(to)h(b)r (e)h(computed)f(as)f(ab)r(o)n(v)n(e,)i(and)118 1971 y(prep)r(ended)28 b(to)f(the)h(index)g(of)f(eac)n(h)g(no)r(de)h(of)f(the)h(subtree)f(b)r (efore)h(insertion.)243 2071 y(Remark)e(that)i(only)f(the)h(paren)n(t)f (no)r(de)h(has)f(to)g(b)r(e)h(up)r(dated)g(on)f(insertion.)118 2303 y Fm(3.5)112 b(Selecting)36 b(the)h(ancestors)h(of)g(a)g(no)s(de) 118 2457 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 2556 y Fh(Y)-7 b(ou)27 b(can)g(sp)r(ecify)h(all)g(ancestors)d(of)j(a)f (no)r(de)h(in)f(a)h(single)f(SQL)g(statemen)n(t;)g(for)g(instance)h (for)f(vgID)326 2722 y Fd(...)42 b(WHERE)f('/25/6/7')f(LIKE)i(\(id)g (||)h('/\045'\))f(AND)g(id)h(<)g('/25/6/7')118 2888 y Fh(The)31 b(second)e(part)h(of)h(the)g(clause,)f(while)h(logically)e (redundan)n(t,)h(is)h(a)f(\020hin)n(t\021)37 b(to)30 b(the)h(optimizer.)45 b(A)n(t)31 b(least)f(in)g(P)n(ost-)118 2988 y(greSQL,)c(without)i(it)g(the)g(optimizer)f(will)h(c)n(ho)r(ose)e (a)i(sequen)n(tial)e(scan)h(of)h(the)g(table)f(and)h(disregard)d(the)j (index.)118 3220 y Fm(3.6)112 b(Selecting)36 b(all)g(lea)m(v)m(es)118 3374 y Fg(Cost:)h Fe(sc)l(an)30 b(of)g(the)g(tr)l(e)l(e)243 3473 y Fh(A)e(leaf)f(is)g(a)h(no)r(de)f(without)h(descendan)n(ts:)36 b(it)28 b(has)f(0)g(c)n(hildren.)37 b(Hence)326 3639 y Fd(...)42 b(WHERE)f(nchildren)f(=)j(0)118 3805 y Fh(If)28 b(this)g(t)n(yp)r(e)g(of)f(query)g(is)h(often)f(necessary)-7 b(,)26 b(y)n(ou)h(ma)n(y)g(b)r(e)h(w)n(ell)f(advised)g(to)g(k)n(eep)g (an)h(index)f(on)h(tree\(nc)n(hildren\).)118 4038 y Fm(3.7)112 b(Determining)35 b(if)i(A)g(is)g(a)h(descendan)m(t)g(of)g(B)118 4191 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations,)h(no)f(table)g(ac)l (c)l(ess)243 4291 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r(eration)f (on)i(the)g(indices,)f(no)g(table)h(access)e(is)i(necessary)-7 b(.)118 4565 y Fi(4)131 b(Putting)45 b(it)f(all)h(together:)57 b(a)44 b(P)l(ostgreSQL)f(implemen)l(tation)118 4747 y Fh(h)n(ttp://www.p)r(ostgresql.org/mhonarc/pgsq)o(l-sql/)o(20)o(00)o (-0)o(4/)o(msg0)o(02)o(67)o(.h)n(tml)243 4847 y(W)-7 b(e)30 b(describ)r(e)g(here)g(a)g(small)f(pac)n(k)-5 b(age)29 b(that)i(can)e(b)r(e)i(used)f(for)g(implemen)n(ting)g(gID)g (on)g(P)n(ostgreSQL.)f(It)i(can)e(b)r(e)118 4946 y(found)f(at)f()243 5046 y(The)21 b(pac)n(k)-5 b(age)21 b(uses)g(the)h(pro) r(cedural)e(language)h(PL/PGsql.)35 b(A)22 b(b)r(etter)g(implemen)n (tation)g(w)n(ould)f(probably)g(de\034ne)118 5145 y(the)28 b(gID)g(as)f(new)g(P)n(ostgres)f(t)n(yp)r(es,)i(and)f(co)r(de)g(all)h (this)g(in)f(C.)243 5245 y(The)g(\034les)h(should)f(b)r(e)h(loaded)f (in)h(alphab)r(etical)f(order.)1987 5653 y(5)p eop %%Page: 6 6 6 5 bop 118 291 a Fm(4.1)112 b(tree0_enco)s(ding.sql)118 444 y Fh(This)28 b(\034le)f(de\034nes)h(and)f(p)r(opulates)h(the)f (table)h(_b160_digits)d(of)j(\020digits\021)33 b(in)28 b(base)f(160,)326 604 y Fd(CREATE)41 b(TABLE)g(\\_b160\\_digits)d (\(deci)j(integer,)f(code)i(char\);)118 764 y Fh(and)28 b(the)f(t)n(w)n(o)g(functions)326 924 y Fd(CREATE)41 b(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er\))d(RETURNS)j(string) 413 1024 y(AS)j('....')e(LANGUAGE)f('plpgsql';)326 1124 y(CREATE)h(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er,)o(in)o(te)o (ger)o(\))d(RETURNS)k(string)413 1223 y(AS)i('....')e(LANGUAGE)f ('plpgsql';)118 1384 y Fh(The)22 b(\034rst)h(function)f(returns)g(a)g (v)-5 b(ariable)21 b(size)h(enco)r(ding;)i(the)f(second)e(a)h(\034xed)h (size)f(enco)r(ding)g(\(the)h(second)e(parameter)118 1483 y(is)g(the)h(size\),)g(and)f(raises)e(an)i(exception)g(if)h(the)f (n)n(um)n(b)r(er)g(is)g(to)r(o)g(large)e(to)i(b)r(e)h(represen)n(ted)e (with)h(the)h(requested)e(n)n(um)n(b)r(er)118 1583 y(of)28 b(digits.)118 1814 y Fm(4.2)112 b(tree1_de\034ne.sql)118 1967 y Fh(This)28 b(\034le)f(pro)n(vides)f(a)i(function)326 2127 y Fd(CREATE)41 b(FUNCTION)f(_tree_create\(tex)o(t,)o(in)o(teg)o (er)o(,t)o(ext)o(,t)o(ex)o(t\))d(RETURNS)k(bpchar)413 2227 y(AS)i('....')e(LANGUAGE)f('plpgsql';)118 2387 y Fh(that)e(creates)f(a)h(tree)f(infrastructure)g(of)h(either)g(fgID)g (or)f(vgID.)h(Assuming)f(y)n(ou)g(ha)n(v)n(e)g(a)h(table)f(\020m)n (ytable\021)44 b(with)118 2487 y(primary)26 b(k)n(ey)h(\020m)n (yid\021,)g(then)h(calling)326 2647 y Fd(SELECT)41 b(_tree_create\('m)o (yt)o(ree)o(',)o(2,')o(my)o(ta)o(ble)o(',)o('m)o(yid)o('\))o(;)118 2807 y Fh(will)28 b(cause:)220 2967 y(1.)41 b(the)28 b(creation)e(of)i(a)f(table)508 3131 y Fd(CREATE)41 b(TABLE)h (mytree_bkg\()683 3230 y(gid)g(text)g(PRIMARY)e(KEY,)683 3330 y(nchildren)f(int,)683 3429 y(sid)j(integer)f(REFERENCES)e (mytable\(myid\))508 3529 y(\);)508 3629 y(CREATE)i(UNIQUE)g(INDEX)h (mytree_bkg_sid)37 b(ON)43 b(mytree_bkg\(sid\);)326 3792 y Fh(for)27 b(the)h(tree)f(structure.)220 3955 y(2.)41 b(the)28 b(creation)e(of)i(a)f(view)508 4118 y Fd(CREATE)41 b(VIEW)h(mytree)f(AS)639 4218 y(SELECT)g(t.gid,n.*)900 4317 y(FROM)h(mytable)f(n,)i(mytree_bkg)c(t)900 4417 y(WHERE)j(t.sid=n.myid;)326 4580 y Fh(with:)35 b(a)23 b(trigger)e(on)i(UPD)n(A)-7 b(TE)25 b(that)e(blo)r(c)n(ks)g(up)r (dating)g(the)h(gid)f(and)g(allo)n(ws)f(up)r(dating)h(the)g(no)r(de)h (data,)f(a)g(rule)326 4680 y(on)k(DELETE)i(that)f(deletes)f(the)h (corresp)r(onding)e(en)n(try)h(b)r(oth)h(in)g(m)n(ytree_bkg)d(and)j(m)n (ytable,)f(and)g(a)g(trigger)326 4779 y(ON)h(INSER)-7 b(T)30 b(that)f(raises)e(an)h(exception)g(and)g(informs)h(the)f(user)g (to)h(use)f(the)h(insertion)f(function)h(describ)r(ed)326 4879 y(b)r(elo)n(w.)220 5042 y(3.)41 b(t)n(w)n(o)26 b(insertion)h (functions)h(that)g(compute)g(automatically)e(the)i(gID)g(of)f(the)h (new)g(no)r(de:)425 5205 y Ff(\017)41 b Fh(a)27 b(function)i(m)n (ytree_insert\(text,text,in)n(teger,text\))d(for)h(insertion)g(sim)n (ultaneosly)f(in)i(b)r(oth)g(tables:)508 5305 y(m)n (ytree_insert\('2201','hello',0,'not)15 b(m)n(uc)n(h'\))j(inserts)g(a)g (new)g(c)n(hild)h(of)f(2201)f(with)h(data1='hello',)h(data2=0)508 5404 y(and)28 b(data3='not)e(m)n(uc)n(h')1987 5653 y(6)p eop %%Page: 7 7 7 6 bop 425 291 a Ff(\017)41 b Fh(a)27 b(function)i(m)n (ytree_insert_no)r(de\(text,in)n(teger\))c(for)i(insertion)g(in)h(m)n (ytree_bkg)508 390 y(m)n(ytree_insert\('2201',25\))c(inserts)j(in)h(m)n (ytree_bkg)e(a)h(new)h(c)n(hild)f(of)h(2201)d(with)j(sid=25)220 556 y(4.)41 b(a)27 b(function)h(m)n(ytree_mo)n(v)n(e\(text,text\))e (that)i(mo)n(v)n(es)e(subtrees:)326 656 y(m)n(ytree_mo)n(v)n (e\('2201','23'\))d(mo)n(v)n(es)j(the)i(subtree)f(ro)r(oted)g(at)g (2201)f(to)h(a)h(place)f(b)r(elo)n(w)g(23)f(\(ma)n(yb)r(e)i(2307\))220 822 y(5.)41 b(a)c(function)g(m)n(ytree_len\(\))g(that)h(returns)e(the)i (length)f(of)g(the)h(enco)r(dings)f(used)g(in)h(the)f(gID)g(\(2)h (here;)j(0)c(if)326 922 y(v)-5 b(ariable)26 b(size\).)118 1196 y Fi(5)131 b(Non-tree)44 b(hierarc)l(hies)118 1378 y Fh(sequence)22 b(as)f(id,)j(table)e(with)h(\(id,g-index\))f(with)g(p) r(ossibly)g(man)n(y)g(g-indices)f(for)h(eac)n(h)f(id)h(\(if)h(TOO)f (man)n(y)-7 b(,)23 b(bad)f(mo)r(del:)118 1478 y(list)28 b(all)f(genealogies,)f(i.e.,)h(paths)h(from)f(the)h(ro)r(ot\))118 1752 y Fi(References)160 1934 y Fh([1])41 b(Philip)28 b(Greenspun,)g Fe(T)-6 b(r)l(e)l(es)29 b(in)h(Or)l(acle)g(SQL)p Fh(,)d(in)h Fg(SQL)k(for)g(W)-8 b(eb)31 b(Nerds)289 2033 y Fh()160 2200 y([2])41 b(Jo)r(e)27 b(Celk)n(o,)f Fe(SQL)j(for)i(Smarties)p Fh(,)d(in)g Fg(DBMS)j(Online)p Fh(,)26 b(Marc)n(h)h(to)g(June)h(1996) 289 2299 y()289 2399 y()289 2498 y()289 2598 y()160 2764 y([3])41 b(Graeme)26 b(Birc)n(hall,)h Fg(DB2)32 b(UDB)g(V6.1)f(SQL)h(Co)s(okb)s(o)s(ok)p Fh(,)289 2864 y()1987 5653 y(7)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF ldb-2.0.8/ldb_tdb/ldb_tdb.c0000660000000000000000000003524313573675413015373 0ustar rootroot00000000000000/* 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 . */ /* * 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" #include "../ldb_key_value/ldb_kv.h" #include /* lock the database for read - use by ltdb_search and ltdb_sequence_number */ static int ltdb_lock_read(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); int tdb_ret = 0; int ret; pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } if (tdb_transaction_active(ldb_kv->tdb) == false && ldb_kv->read_lock_count == 0) { tdb_ret = tdb_lockall_read(ldb_kv->tdb); } if (tdb_ret == 0) { ldb_kv->read_lock_count++; return LDB_SUCCESS; } ret = ltdb_err_map(tdb_error(ldb_kv->tdb)); if (ret == LDB_SUCCESS) { ret = LDB_ERR_OPERATIONS_ERROR; } ldb_debug_set(ldb_module_get_ctx(module), LDB_DEBUG_FATAL, "Failure during ltdb_lock_read(): %s -> %s", tdb_errorstr(ldb_kv->tdb), ldb_strerror(ret)); return ret; } /* unlock the database after a ltdb_lock_read() */ static int ltdb_unlock_read(struct ldb_module *module) { void *data = ldb_module_get_private(module); struct ldb_kv_private *ldb_kv = talloc_get_type(data, struct ldb_kv_private); pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } if (!tdb_transaction_active(ldb_kv->tdb) && ldb_kv->read_lock_count == 1) { tdb_unlockall_read(ldb_kv->tdb); ldb_kv->read_lock_count--; return 0; } ldb_kv->read_lock_count--; return 0; } static int ltdb_store(struct ldb_kv_private *ldb_kv, 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(ldb_kv->tdb); if (transaction_active == false){ return LDB_ERR_PROTOCOL_ERROR; } return tdb_store(ldb_kv->tdb, key, data, flags); } static int ltdb_error(struct ldb_kv_private *ldb_kv) { return ltdb_err_map(tdb_error(ldb_kv->tdb)); } static const char *ltdb_errorstr(struct ldb_kv_private *ldb_kv) { return tdb_errorstr(ldb_kv->tdb); } static int ltdb_delete(struct ldb_kv_private *ldb_kv, struct ldb_val ldb_key) { TDB_DATA tdb_key = { .dptr = ldb_key.data, .dsize = ldb_key.length }; bool transaction_active = tdb_transaction_active(ldb_kv->tdb); if (transaction_active == false){ return LDB_ERR_PROTOCOL_ERROR; } return tdb_delete(ldb_kv->tdb, tdb_key); } static int ltdb_transaction_start(struct ldb_kv_private *ldb_kv) { pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } return tdb_transaction_start(ldb_kv->tdb); } static int ltdb_transaction_cancel(struct ldb_kv_private *ldb_kv) { pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } return tdb_transaction_cancel(ldb_kv->tdb); } static int ltdb_transaction_prepare_commit(struct ldb_kv_private *ldb_kv) { pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } return tdb_transaction_prepare_commit(ldb_kv->tdb); } static int ltdb_transaction_commit(struct ldb_kv_private *ldb_kv) { pid_t pid = getpid(); if (ldb_kv->pid != pid) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), __location__ ": Reusing ldb opend by pid %d in " "process %d\n", ldb_kv->pid, pid); return LDB_ERR_PROTOCOL_ERROR; } return tdb_transaction_commit(ldb_kv->tdb); } struct kv_ctx { ldb_kv_traverse_fn kv_traverse_fn; void *ctx; struct ldb_kv_private *ldb_kv; int (*parser)(struct ldb_val key, struct ldb_val data, void *private_data); int parser_ret; }; static int ltdb_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->ldb_kv, key, data, kv_ctx->ctx); } static int ltdb_traverse_fn(struct ldb_kv_private *ldb_kv, ldb_kv_traverse_fn fn, void *ctx) { struct kv_ctx kv_ctx = { .kv_traverse_fn = fn, .ctx = ctx, .ldb_kv = ldb_kv}; if (tdb_transaction_active(ldb_kv->tdb)) { return tdb_traverse( ldb_kv->tdb, ltdb_traverse_fn_wrapper, &kv_ctx); } else { return tdb_traverse_read( ldb_kv->tdb, ltdb_traverse_fn_wrapper, &kv_ctx); } } static int ltdb_update_in_iterate(struct ldb_kv_private *ldb_kv, 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 ldb_kv_reindex_context *ctx = (struct ldb_kv_reindex_context *)state; struct ldb_module *module = ldb_kv->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(ldb_kv->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(ldb_kv->tdb)); ctx->error = ltdb_err_map(tdb_error(ldb_kv->tdb)); return -1; } tdb_ret = tdb_store(ldb_kv->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(ldb_kv->tdb)); ctx->error = ltdb_err_map(tdb_error(ldb_kv->tdb)); return -1; } return tdb_ret; } static int ltdb_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, }; kv_ctx->parser_ret = kv_ctx->parser(key, data, kv_ctx->ctx); return kv_ctx->parser_ret; } static int ltdb_parse_record(struct ldb_kv_private *ldb_kv, 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, .ldb_kv = ldb_kv}; TDB_DATA key = { .dptr = ldb_key.data, .dsize = ldb_key.length }; int ret; if (tdb_transaction_active(ldb_kv->tdb) == false && ldb_kv->read_lock_count == 0) { return LDB_ERR_PROTOCOL_ERROR; } ret = tdb_parse_record( ldb_kv->tdb, key, ltdb_parse_record_wrapper, &kv_ctx); if (kv_ctx.parser_ret != LDB_SUCCESS) { return kv_ctx.parser_ret; } else if (ret == 0) { return LDB_SUCCESS; } return ltdb_err_map(tdb_error(ldb_kv->tdb)); } static int ltdb_iterate_range(struct ldb_kv_private *ldb_kv, struct ldb_val start_key, struct ldb_val end_key, ldb_kv_traverse_fn fn, void *ctx) { /* * We do not implement this operation because we do not know how to * iterate from one key to the next (in a sorted fashion). * * We could mimic it potentially, but it would violate boundaries of * knowledge (data type representation). */ return LDB_ERR_OPERATIONS_ERROR; } static const char *ltdb_name(struct ldb_kv_private *ldb_kv) { return tdb_name(ldb_kv->tdb); } static bool ltdb_changed(struct ldb_kv_private *ldb_kv) { int seq = tdb_get_seqnum(ldb_kv->tdb); bool has_changed = (seq != ldb_kv->tdb_seqnum); ldb_kv->tdb_seqnum = seq; return has_changed; } static bool ltdb_transaction_active(struct ldb_kv_private *ldb_kv) { return tdb_transaction_active(ldb_kv->tdb); } /* * Get an estimate of the number of records in a tdb database. * * This implementation will overestimate the number of records in a sparsely * populated database. The size estimate is only used for allocating * an in memory tdb to cache index records during a reindex, overestimating * the contents is acceptable, and preferable to underestimating */ #define RECORD_SIZE 500 static size_t ltdb_get_size(struct ldb_kv_private *ldb_kv) { size_t map_size = tdb_map_size(ldb_kv->tdb); size_t size = map_size / RECORD_SIZE; return size; } /* * Start a sub transaction * As TDB does not currently support nested transactions, we do nothing and * return LDB_SUCCESS */ static int ltdb_nested_transaction_start(struct ldb_kv_private *ldb_kv) { return LDB_SUCCESS; } /* * Commit a sub transaction * As TDB does not currently support nested transactions, we do nothing and * return LDB_SUCCESS */ static int ltdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv) { return LDB_SUCCESS; } /* * Cancel a sub transaction * As TDB does not currently support nested transactions, we do nothing and * return LDB_SUCCESS */ static int ltdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv) { return LDB_SUCCESS; } static const struct kv_db_ops key_value_ops = { /* No support for any additional features */ .options = 0, .store = ltdb_store, .delete = ltdb_delete, .iterate = ltdb_traverse_fn, .update_in_iterate = ltdb_update_in_iterate, .fetch_and_parse = ltdb_parse_record, .iterate_range = ltdb_iterate_range, .lock_read = ltdb_lock_read, .unlock_read = ltdb_unlock_read, .begin_write = ltdb_transaction_start, .prepare_write = ltdb_transaction_prepare_commit, .finish_write = ltdb_transaction_commit, .abort_write = ltdb_transaction_cancel, .error = ltdb_error, .errorstr = ltdb_errorstr, .name = ltdb_name, .has_changed = ltdb_changed, .transaction_active = ltdb_transaction_active, .get_size = ltdb_get_size, .begin_nested_write = ltdb_nested_transaction_start, .finish_nested_write = ltdb_nested_transaction_commit, .abort_nested_write = ltdb_nested_transaction_cancel, }; /* connect to the database */ int ltdb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[], struct ldb_module **_module) { const char *path; int tdb_flags, open_flags; struct ldb_kv_private *ldb_kv; /* * 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 */ if (strchr(url, ':')) { if (strncmp(url, "tdb://", 6) != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url); return LDB_ERR_OPERATIONS_ERROR; } path = url+6; } else { path = url; } tdb_flags = TDB_DEFAULT | TDB_SEQNUM | TDB_DISALLOW_NESTING; /* check for the 'nosync' option */ if (flags & LDB_FLG_NOSYNC) { tdb_flags |= TDB_NOSYNC; } /* and nommap option */ if (flags & LDB_FLG_NOMMAP) { tdb_flags |= TDB_NOMMAP; } ldb_kv = talloc_zero(ldb, struct ldb_kv_private); if (!ldb_kv) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } if (flags & LDB_FLG_RDONLY) { /* * This is weird, but because we can only have one tdb * in this process, and the other one could be * read-write, we can't use the tdb readonly. Plus a * read only tdb prohibits the all-record lock. */ open_flags = O_RDWR; ldb_kv->read_only = true; } else if (flags & LDB_FLG_DONT_CREATE_DB) { /* * This is used by ldbsearch to prevent creation of the database * if the name is wrong */ open_flags = O_RDWR; } else { /* * This is the normal case */ open_flags = O_CREAT | O_RDWR; } ldb_kv->kv_ops = &key_value_ops; errno = 0; /* note that we use quite a large default hash size */ ldb_kv->tdb = ltdb_wrap_open(ldb_kv, path, 10000, tdb_flags, open_flags, ldb_get_create_perms(ldb), ldb); if (!ldb_kv->tdb) { ldb_asprintf_errstring(ldb, "Unable to open tdb '%s': %s", path, strerror(errno)); ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s': %s", path, strerror(errno)); talloc_free(ldb_kv); if (errno == EACCES || errno == EPERM) { return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; } return LDB_ERR_OPERATIONS_ERROR; } return ldb_kv_init_store( ldb_kv, "ldb_tdb backend", ldb, options, _module); } ldb-2.0.8/ldb_tdb/ldb_tdb.h0000660000000000000000000000103713573675413015372 0ustar rootroot00000000000000#include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "tdb.h" #include "ldb_module.h" TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); int ltdb_err_map(enum TDB_ERROR tdb_code); 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 ltdb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[], struct ldb_module **_module); ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c0000660000000000000000000000431113573675413017070 0ustar rootroot00000000000000/* 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 . */ /* * 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 /* map a tdb error code to a ldb error code */ int ltdb_err_map(enum TDB_ERROR tdb_code) { switch (tdb_code) { case TDB_SUCCESS: return LDB_SUCCESS; case TDB_ERR_CORRUPT: case TDB_ERR_OOM: case TDB_ERR_EINVAL: return LDB_ERR_OPERATIONS_ERROR; case TDB_ERR_IO: return LDB_ERR_PROTOCOL_ERROR; case TDB_ERR_LOCK: case TDB_ERR_NOLOCK: return LDB_ERR_BUSY; case TDB_ERR_LOCK_TIMEOUT: return LDB_ERR_TIME_LIMIT_EXCEEDED; case TDB_ERR_EXISTS: return LDB_ERR_ENTRY_ALREADY_EXISTS; case TDB_ERR_NOEXIST: return LDB_ERR_NO_SUCH_OBJECT; case TDB_ERR_RDONLY: return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; default: break; } return LDB_ERR_OTHER; } ldb-2.0.8/ldb_tdb/ldb_tdb_init.c0000660000000000000000000000327613444661620016407 0ustar rootroot00000000000000/* 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 . */ /* * 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); } ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c0000660000000000000000000000762413444661620016416 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2005 ** 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 . */ #include "ldb_tdb.h" #include "dlinklist.h" static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; const char *name = tdb_name(tdb); struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context); enum ldb_debug_level ldb_level; char *message; if (ldb == NULL) return; va_start(ap, fmt); message = talloc_vasprintf(ldb, fmt, ap); va_end(ap); switch (level) { case TDB_DEBUG_FATAL: ldb_level = LDB_DEBUG_FATAL; break; case TDB_DEBUG_ERROR: ldb_level = LDB_DEBUG_ERROR; break; case TDB_DEBUG_WARNING: ldb_level = LDB_DEBUG_WARNING; break; case TDB_DEBUG_TRACE: ldb_level = LDB_DEBUG_TRACE; break; default: ldb_level = LDB_DEBUG_FATAL; } ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); talloc_free(message); } /* the purpose of this code is to work around the braindead posix locking rules, to allow us to have a ldb open more than once while allowing locking to work TDB2 handles multiple opens, so we don't have this problem there. */ struct ltdb_wrap { struct ltdb_wrap *next, *prev; struct tdb_context *tdb; dev_t device; ino_t inode; pid_t pid; }; static struct ltdb_wrap *tdb_list; /* destroy the last connection to a tdb */ static int ltdb_wrap_destructor(struct ltdb_wrap *w) { tdb_close(w->tdb); DLIST_REMOVE(tdb_list, w); return 0; } /* wrapped connection to a tdb database. The caller should _not_ free this as it is not a talloc structure (as tdb does not use talloc yet). It will auto-close when the caller frees the mem_ctx that is passed to this call */ 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) { struct ltdb_wrap *w; struct tdb_logging_context lctx; struct stat st; 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; } } } w = talloc(mem_ctx, struct ltdb_wrap); if (w == NULL) { return NULL; } lctx.log_fn = ltdb_log_fn; lctx.log_private = ldb; w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, &lctx, NULL); if (w->tdb == NULL) { talloc_free(w); return NULL; } if (fstat(tdb_fd(w->tdb), &st) != 0) { tdb_close(w->tdb); talloc_free(w); return NULL; } w->device = st.st_dev; w->inode = st.st_ino; w->pid = getpid(); talloc_set_destructor(w, ltdb_wrap_destructor); DLIST_ADD(tdb_list, w); return w->tdb; } ldb-2.0.8/mainpage.dox0000660000000000000000000000537212406075657014536 0ustar rootroot00000000000000/** \mainpage ldb \section Overview ldb is a LDAP-like embedded database. It is not at all LDAP standards compliant, so if you want a standards compliant database then please see the excellent OpenLDAP project.

What ldb does is provide a fast database with an LDAP-like API designed to be used within an application. In some ways it can be seen as a intermediate solution between key-value pair databases and a real LDAP database.

ldb is the database engine used in Samba4. \section Features The main features that separate ldb from other solutions are: - Safe multi-reader, multi-writer, using byte range locking - LDAP-like API - fast operation - choice of local tdb, local sqlite3 or remote LDAP backends - integration with talloc - schema-less operation, for trivial setup - modules for extensions (such as schema support) - easy setup of indexes and attribute properties - ldbedit tool for database editing (reminiscent of 'vipw') - ldif for import/export \section Documentation ldb has limited programmer and administrator documentation: - a list of functions - a list of examples - a list of data structures - a list of constants If you need more information than is presented in this document, you may wish to look at the source code, especially the source code in the tools directory. ldb makes use of the LDAP Data Interchange Format (LDIF), which is documented in RFC 2849. \section Support ldb does not currently have its own mailing list or bug tracking system. For now, please use the samba-technical mailing list, and the Samba bugzilla bug tracking system. \section Download You can download the latest release either via rsync or anonymous svn. To fetch via svn use the following commands: \verbatim svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc \endverbatim To fetch via rsync use these commands: \verbatim rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/ldb . rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/tdb . rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/talloc . \endverbatim \section Credits ldb is another product of the prolific Andrew Tridgell. */ ldb-2.0.8/man/ldb.3.xml0000660000000000000000000001604613055076237014434 0ustar rootroot00000000000000 ldb 3 LDB System Administration tools 1.1 ldb The Samba Project A light-weight database library #include <ldb.h> description ldb is a light weight embedded database library and API. With a programming interface that is very similar to LDAP, ldb can store its data either in a tdb(3) database or in a real LDAP database. When used with the tdb backend ldb does not require any database daemon. Instead, ldb function calls are processed immediately by the ldb library, which does IO directly on the database, while allowing multiple readers/writers using operating system byte range locks. This leads to an API with very low overheads, often resulting in speeds of more than 10x what can be achieved with a more traditional LDAP architecture. In a taxonomy of databases ldb would sit half way between key/value pair databases (such as berkley db or tdb) and a full LDAP database. With a structured attribute oriented API like LDAP and good indexing capabilities, ldb can be used for quite sophisticated applications that need a light weight database, without the administrative overhead of a full LDAP installation. Included with ldb are a number of useful command line tools for manipulating a ldb database. These tools are similar in style to the equivalent ldap command line tools. In its default mode of operation with a tdb backend, ldb can also be seen as a "schema-less LDAP". By default ldb does not require a schema, which greatly reduces the complexity of getting started with ldb databases. As the complexity of you application grows you can take advantage of some of the optional schema-like attributes that ldb offers, or you can migrate to using the full LDAP api while keeping your exiting ldb code. If you are new to ldb, then I suggest starting with the manual pages for ldbsearch(1) and ldbedit(1), and experimenting with a local database. Then I suggest you look at the ldb_connect(3) and ldb_search(3) manual pages. TOOLS ldbsearch(1) - command line ldb search utility ldbedit(1) - edit all or part of a ldb database using your favourite editor ldbadd(1) - add records to a ldb database using LDIF formatted input ldbdel(1) - delete records from a ldb database ldbmodify(1) - modify records in a ldb database using LDIF formatted input FUNCTIONS ldb_connect(3) - connect to a ldb backend ldb_search(3) - perform a database search ldb_add(3) - add a record to the database ldb_delete(3) - delete a record from the database ldb_modify(3) - modify a record in the database ldb_errstring(3) - retrieve extended error information from the last operation ldb_ldif_write(3) - write a LDIF formatted message ldb_ldif_write_file(3) - write a LDIF formatted message to a file ldb_ldif_read(3) - read a LDIF formatted message ldb_ldif_read_free(3) - free the result of a ldb_ldif_read() ldb_ldif_read_file(3) - read a LDIF message from a file ldb_ldif_read_string(3) - read a LDIF message from a string ldb_msg_find_element(3) - find an element in a ldb_message ldb_val_equal_exact(3) - compare two ldb_val structures ldb_msg_find_val(3) - find an element by value ldb_msg_add_empty(3) - add an empty message element to a ldb_message ldb_msg_add(3) - add a non-empty message element to a ldb_message ldb_msg_element_compare(3) - compare two ldb_message_element structures ldb_msg_find_int(3) - return an integer value from a ldb_message ldb_msg_find_uint(3) - return an unsigned integer value from a ldb_message ldb_msg_find_double(3) - return a double value from a ldb_message ldb_msg_find_string(3) - return a string value from a ldb_message ldb_set_alloc(3) - set the memory allocation function to be used by ldb ldb_set_debug(3) - set a debug handler to be used by ldb ldb_set_debug_stderr(3) - set a debug handler for stderr output Author ldb was written by Andrew Tridgell. If you wish to report a problem or make a suggestion then please see the web site for current contact and maintainer information. ldb is released under the GNU Lesser General Public License version 2 or later. Please see the file COPYING for license details. ldb-2.0.8/man/ldbadd.1.xml0000660000000000000000000000472413573675413015111 0ustar rootroot00000000000000 ldbadd 1 LDB System Administration tools 1.1 ldbadd Command-line utility for adding records to an LDB ldbadd -h -H LDB-URL ldif-file1 ldif-file2 ... DESCRIPTION ldbadd adds records to an ldb(3) database. It reads the ldif(5) files specified on the command line and adds the records from these files to the LDB database, which is specified by the -H option or the LDB_URL environment variable. If - is specified as a ldb file, the ldif input is read from standard input. OPTIONS -h Show list of available options. -H <ldb-url> LDB URL to connect to. See ldb(3) for details. ENVIRONMENT LDB_URL LDB URL to connect to (can be overridden by using the -H command-line option.) VERSION This man page is correct for version 1.1 of LDB. SEE ALSO ldb(3), ldbmodify, ldbdel, ldif(5) AUTHOR ldb was written by Andrew Tridgell. If you wish to report a problem or make a suggestion then please see the web site for current contact and maintainer information. This manpage was written by Jelmer Vernooij. ldb-2.0.8/man/ldbdel.1.xml0000660000000000000000000000464413573675413015126 0ustar rootroot00000000000000 ldbdel 1 LDB System Administration tools 1.1 ldbdel Command-line program for deleting LDB records ldbdel -h -H LDB-URL dn ... DESCRIPTION ldbdel deletes records from an ldb(3) database. It deletes the records identified by the dn's specified on the command-line. ldbdel uses either the database that is specified with the -H option or the database specified by the LDB_URL environment variable. OPTIONS -h Show list of available options. -H <ldb-url> LDB URL to connect to. See ldb(3) for details. ENVIRONMENT LDB_URL LDB URL to connect to (can be overridden by using the -H command-line option.) VERSION This man page is correct for version 1.1 of LDB. SEE ALSO ldb(3), ldbmodify, ldbadd, ldif(5) AUTHOR ldb was written by Andrew Tridgell. If you wish to report a problem or make a suggestion then please see the web site for current contact and maintainer information. ldbdel was written by Andrew Tridgell. This manpage was written by Jelmer Vernooij. ldb-2.0.8/man/ldbedit.1.xml0000660000000000000000000001212313055076237015270 0ustar rootroot00000000000000 ldbedit 1 LDB System Administration tools 1.1 ldbedit Edit LDB databases using your preferred editor ldbedit -? --usage -s base|one|sub -b basedn -a -e editor -H LDB-URL expression attributes DESCRIPTION ldbedit is a utility that allows you to edit LDB entries (in tdb files, sqlite files or LDAP servers) using your preferred editor. ldbedit generates an LDIF file based on your query, allows you to edit the LDIF, and then merges that LDIF back into the LDB backend. OPTIONS -? --help Show list of available options, and a phrase describing what that option does. --usage Show list of available options. This is similar to the help option, however it does not provide any description, and is hence shorter. -H <ldb-url> LDB URL to connect to. For a tdb database, this will be of the form tdb://filename. For a LDAP connection over unix domain sockets, this will be of the form ldapi://socket. For a (potentially remote) LDAP connection over TCP, this will be of the form ldap://hostname. For an SQLite database, this will be of the form sqlite://filename. -s one|sub|base Search scope to use. One-level, subtree or base. -a -all Edit all records. This allows you to apply the same change to a number of records at once. You probably want to combine this with an expression of the form "objectclass=*". -e editor --editor editor Specify the editor that should be used (overrides the VISUAL and EDITOR environment variables). If this option is not used, and neither VISUAL nor EDITOR environment variables are set, then the vi editor will be used. -b basedn Specify Base Distinguished Name to use. -v --verbose Make ldbedit more verbose about the operations that are being performed. Without this option, ldbedit will only provide a summary change line. ENVIRONMENT LDB_URL LDB URL to connect to. This can be overridden by using the -H command-line option.) VISUAL and EDITOR Environment variables used to determine what editor to use. VISUAL takes precedence over EDITOR, and both are overridden by the -e command-line option. VERSION This man page is correct for version 1.1 of LDB. SEE ALSO ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1) AUTHOR ldb was written by Andrew Tridgell. If you wish to report a problem or make a suggestion then please see the web site for current contact and maintainer information. This manpage was written by Jelmer Vernooij and updated by Brad Hards. ldb-2.0.8/man/ldbmodify.1.xml0000660000000000000000000000427013573675413015644 0ustar rootroot00000000000000 ldbmodify 1 LDB System Administration tools 1.1 ldbmodify Modify records in a LDB database ldbmodify -H LDB-URL ldif-file DESCRIPTION ldbmodify changes, adds and deletes records in a LDB database. The changes that should be made to the LDB database are read from the specified LDIF-file. If - is specified as the filename, input is read from stdin. For now, see ldapmodify(1) for details on the LDIF file format. OPTIONS -H <ldb-url> LDB URL to connect to. See ldb(3) for details. ENVIRONMENT LDB_URL LDB URL to connect to (can be overridden by using the -H command-line option.) VERSION This man page is correct for version 1.1 of LDB. SEE ALSO ldb(3), ldbedit AUTHOR ldb was written by Andrew Tridgell. If you wish to report a problem or make a suggestion then please see the web site for current contact and maintainer information. This manpage was written by Jelmer Vernooij. ldb-2.0.8/man/ldbrename.1.xml0000660000000000000000000000466613573675413015635 0ustar rootroot00000000000000 ldbrename 1 LDB System Administration tools 1.1 ldbrename Edit LDB databases using your favorite editor ldbrename -h -o options olddn newdn DESCRIPTION ldbrename is a utility that allows you to rename trees in an LDB database based by DN. This utility takes two arguments: the original DN name of the top element and the DN to change it to. OPTIONS -h Show list of available options. -H <ldb-url> LDB URL to connect to. See ldb(3) for details. -o options Extra ldb options, such as modules. ENVIRONMENT LDB_URL LDB URL to connect to (can be overridden by using the -H command-line option.) VERSION This man page is correct for version 1.1 of LDB. SEE ALSO ldb(3), ldbmodify, ldbdel, ldif(5) AUTHOR ldb was written by Andrew Tridgell. If you wish to report a problem or make a suggestion then please see the web site for current contact and maintainer information. This manpage was written by Jelmer Vernooij. ldb-2.0.8/man/ldbsearch.1.xml0000660000000000000000000000546213573675413015626 0ustar rootroot00000000000000 ldbsearch 1 LDB System Administration tools 1.1 ldbsearch Search for records in a LDB database ldbsearch -h -s base|one|sub -b basedn -i -H LDB-URL expression attributes DESCRIPTION ldbsearch searches a LDB database for records matching the specified expression (see the ldapsearch(1) manpage for a description of the expression format). For each record, the specified attributes are printed. OPTIONS -h Show list of available options. -H <ldb-url> LDB URL to connect to. See ldb(3) for details. -s one|sub|base Search scope to use. One-level, subtree or base. -i Read search expressions from stdin. -b basedn Specify Base DN to use. ENVIRONMENT LDB_URL LDB URL to connect to (can be overridden by using the -H command-line option.) VERSION This man page is correct for version 1.1 of LDB. SEE ALSO ldb(3), ldbedit(1) AUTHOR ldb was written by Andrew Tridgell. If you wish to report a problem or make a suggestion then please see the web site for current contact and maintainer information. This manpage was written by Jelmer Vernooij. ldb-2.0.8/modules/asq.c0000660000000000000000000002235312406075657014637 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2005-2008 ** 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 . */ /* * Name: ldb * * Component: ldb attribute scoped query control module * * Description: this module searches all the objects pointed by * the DNs contained in the references attribute * * Author: Simo Sorce */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_module.h" struct asq_context { enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step; struct ldb_module *module; struct ldb_request *req; struct ldb_asq_control *asq_ctrl; const char * const *req_attrs; char *req_attribute; enum { ASQ_CTRL_SUCCESS = 0, ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX = 21, ASQ_CTRL_UNWILLING_TO_PERFORM = 53, ASQ_CTRL_AFFECTS_MULTIPLE_DSA = 71 } asq_ret; struct ldb_reply *base_res; struct ldb_request **reqs; unsigned int num_reqs; unsigned int cur_req; struct ldb_control **controls; }; static struct asq_context *asq_context_init(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct asq_context *ac; ldb = ldb_module_get_ctx(module); ac = talloc_zero(req, struct asq_context); if (ac == NULL) { ldb_oom(ldb); return NULL; } ac->module = module; ac->req = req; return ac; } static int asq_search_continue(struct asq_context *ac); static int asq_search_terminate(struct asq_context *ac) { struct ldb_asq_control *asq; unsigned int i; if (ac->controls) { for (i = 0; ac->controls[i]; i++) /* count em */ ; } else { i = 0; } ac->controls = talloc_realloc(ac, ac->controls, struct ldb_control *, i + 2); if (ac->controls == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ac->controls[i] = talloc(ac->controls, struct ldb_control); if (ac->controls[i] == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ac->controls[i]->oid = LDB_CONTROL_ASQ_OID; ac->controls[i]->critical = 0; asq = talloc_zero(ac->controls[i], struct ldb_asq_control); if (asq == NULL) return LDB_ERR_OPERATIONS_ERROR; asq->result = ac->asq_ret; ac->controls[i]->data = asq; ac->controls[i + 1] = NULL; return ldb_module_done(ac->req, ac->controls, NULL, LDB_SUCCESS); } static int asq_base_callback(struct ldb_request *req, struct ldb_reply *ares) { struct asq_context *ac; int ret; ac = talloc_get_type(req->context, struct asq_context); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: ac->base_res = talloc_move(ac, &ares); break; case LDB_REPLY_REFERRAL: /* ignore referrals */ talloc_free(ares); break; case LDB_REPLY_DONE: talloc_free(ares); /* next step */ ret = asq_search_continue(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } break; } return LDB_SUCCESS; } static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares) { struct asq_context *ac; int ret; ac = talloc_get_type(req->context, struct asq_context); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: /* pass the message up to the original callback as we * do not have to elaborate on it any further */ ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } talloc_free(ares); break; case LDB_REPLY_REFERRAL: /* ignore referrals */ talloc_free(ares); break; case LDB_REPLY_DONE: talloc_free(ares); ret = asq_search_continue(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } break; } return LDB_SUCCESS; } static int asq_build_first_request(struct asq_context *ac, struct ldb_request **base_req) { struct ldb_context *ldb; const char **base_attrs; int ret; ldb = ldb_module_get_ctx(ac->module); ac->req_attrs = ac->req->op.search.attrs; ac->req_attribute = talloc_strdup(ac, ac->asq_ctrl->source_attribute); if (ac->req_attribute == NULL) return LDB_ERR_OPERATIONS_ERROR; base_attrs = talloc_array(ac, const char *, 2); if (base_attrs == NULL) return LDB_ERR_OPERATIONS_ERROR; base_attrs[0] = talloc_strdup(base_attrs, ac->asq_ctrl->source_attribute); if (base_attrs[0] == NULL) return LDB_ERR_OPERATIONS_ERROR; base_attrs[1] = NULL; ret = ldb_build_search_req(base_req, ldb, ac, ac->req->op.search.base, LDB_SCOPE_BASE, NULL, (const char * const *)base_attrs, NULL, ac, asq_base_callback, ac->req); if (ret != LDB_SUCCESS) { return ret; } return LDB_SUCCESS; } static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated) { struct ldb_context *ldb; struct ldb_control **saved_controls; struct ldb_control *control; struct ldb_dn *dn; struct ldb_message_element *el; unsigned int i; int ret; if (ac->base_res == NULL) { return LDB_ERR_NO_SUCH_OBJECT; } ldb = ldb_module_get_ctx(ac->module); el = ldb_msg_find_element(ac->base_res->message, ac->req_attribute); /* no values found */ if (el == NULL) { ac->asq_ret = ASQ_CTRL_SUCCESS; *terminated = true; return asq_search_terminate(ac); } ac->num_reqs = el->num_values; ac->cur_req = 0; ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs); if (ac->reqs == NULL) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0; i < el->num_values; i++) { dn = ldb_dn_new(ac, ldb, (const char *)el->values[i].data); if ( ! ldb_dn_validate(dn)) { ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX; *terminated = true; return asq_search_terminate(ac); } ret = ldb_build_search_req_ex(&ac->reqs[i], ldb, ac, dn, LDB_SCOPE_BASE, ac->req->op.search.tree, ac->req_attrs, ac->req->controls, ac, asq_reqs_callback, ac->req); if (ret != LDB_SUCCESS) { return ret; } /* remove the ASQ control itself */ control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID); if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) { return LDB_ERR_OPERATIONS_ERROR; } } return LDB_SUCCESS; } static int asq_search_continue(struct asq_context *ac) { struct ldb_context *ldb; bool terminated = false; int ret; ldb = ldb_module_get_ctx(ac->module); switch (ac->step) { case ASQ_SEARCH_BASE: /* build up the requests call chain */ ret = asq_build_multiple_requests(ac, &terminated); if (ret != LDB_SUCCESS || terminated) { return ret; } ac->step = ASQ_SEARCH_MULTI; return ldb_request(ldb, ac->reqs[ac->cur_req]); case ASQ_SEARCH_MULTI: ac->cur_req++; if (ac->cur_req == ac->num_reqs) { /* done */ return asq_search_terminate(ac); } return ldb_request(ldb, ac->reqs[ac->cur_req]); } return LDB_ERR_OPERATIONS_ERROR; } static int asq_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct ldb_request *base_req; struct ldb_control *control; struct asq_context *ac; int ret; ldb = ldb_module_get_ctx(module); /* check if there's an ASQ control */ control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID); if (control == NULL) { /* not found go on */ return ldb_next_request(module, req); } ac = asq_context_init(module, req); if (!ac) { return LDB_ERR_OPERATIONS_ERROR; } /* check the search is well formed */ if (req->op.search.scope != LDB_SCOPE_BASE) { ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM; return asq_search_terminate(ac); } ac->asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control); if (!ac->asq_ctrl) { return LDB_ERR_PROTOCOL_ERROR; } ret = asq_build_first_request(ac, &base_req); if (ret != LDB_SUCCESS) { return ret; } ac->step = ASQ_SEARCH_BASE; return ldb_request(ldb, base_req); } static int asq_init(struct ldb_module *module) { struct ldb_context *ldb; int ret; ldb = ldb_module_get_ctx(module); ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!"); } return ldb_next_init(module); } static const struct ldb_module_ops ldb_asq_module_ops = { .name = "asq", .search = asq_search, .init_context = asq_init }; int ldb_asq_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_module(&ldb_asq_module_ops); } ldb-2.0.8/modules/paged_searches.c0000660000000000000000000002264413573675413017015 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2005-2008 Copyright (C) Andrew Bartlett 2009 ** 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 . */ /* * Name: paged_searches * * Component: ldb paged searches module * * Description: this module detects if the remote ldap server supports * paged results and use them to transparently access all objects * * Author: Simo Sorce */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_module.h" #define PS_DEFAULT_PAGE_SIZE 500 /* 500 objects per query seem to be a decent compromise * the default AD limit per request is 1000 entries */ struct private_data { bool paged_supported; }; struct ps_context { struct ldb_module *module; struct ldb_request *req; bool pending; char **saved_referrals; unsigned int num_referrals; struct ldb_request *down_req; }; static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct ldb_control *rep_control, *req_control; struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL; ldb = ldb_module_get_ctx(ac->module); rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID); if (rep_control) { paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control); } req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); if (req_control == NULL) { ldb_set_errstring(ldb, "paged_searches: control is missing"); return LDB_ERR_OPERATIONS_ERROR; } paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control); if (!rep_control || !paged_rep_control) { if (paged_req_control->cookie) { /* something wrong here - why give us a control back befre, but not one now? */ ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!"); return LDB_ERR_OPERATIONS_ERROR; } else { /* No cookie received yet, valid to just return the full data set */ /* we are done */ ac->pending = false; return LDB_SUCCESS; } } if (paged_rep_control->cookie_len == 0) { /* we are done */ ac->pending = false; return LDB_SUCCESS; } /* more processing required */ /* let's fill in the request control with the new cookie */ /* if there's a reply control we must find a request * control matching it */ if (paged_req_control->cookie) { talloc_free(paged_req_control->cookie); } paged_req_control->cookie = talloc_memdup(req_control, paged_rep_control->cookie, paged_rep_control->cookie_len); paged_req_control->cookie_len = paged_rep_control->cookie_len; ac->pending = true; return LDB_SUCCESS; } static int store_referral(struct ps_context *ac, char *referral) { ac->saved_referrals = talloc_realloc(ac, ac->saved_referrals, char *, ac->num_referrals + 2); if (!ac->saved_referrals) { return LDB_ERR_OPERATIONS_ERROR; } ac->saved_referrals[ac->num_referrals] = talloc_strdup(ac->saved_referrals, referral); if (!ac->saved_referrals[ac->num_referrals]) { return LDB_ERR_OPERATIONS_ERROR; } ac->num_referrals++; ac->saved_referrals[ac->num_referrals] = NULL; return LDB_SUCCESS; } static int send_referrals(struct ps_context *ac) { struct ldb_reply *ares; int ret; unsigned int i; for (i = 0; i < ac->num_referrals; i++) { ares = talloc_zero(ac->req, struct ldb_reply); if (!ares) { return LDB_ERR_OPERATIONS_ERROR; } ares->type = LDB_REPLY_REFERRAL; ares->referral = ac->saved_referrals[i]; ret = ldb_module_send_referral(ac->req, ares->referral); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ps_context *ac; int ret; ac = talloc_get_type(req->context, struct ps_context); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } break; case LDB_REPLY_REFERRAL: ret = store_referral(ac, ares->referral); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } break; case LDB_REPLY_DONE: ret = check_ps_continuation(ac, req, ares); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } if (ac->pending) { ret = ldb_next_request(ac->module, ac->down_req); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } } else { /* send referrals */ ret = send_referrals(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } /* send REPLY_DONE */ return ldb_module_done(ac->req, ares->controls, ares->response, LDB_SUCCESS); } break; } talloc_free(ares); return LDB_SUCCESS; } static int ps_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct private_data *private_data; struct ps_context *ac; struct ldb_paged_control *control; int ret; private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); ldb = ldb_module_get_ctx(module); /* check if paging is supported */ if (!private_data || !private_data->paged_supported) { /* do not touch this request paged controls not * supported or we * are just not setup yet */ return ldb_next_request(module, req); } ac = talloc_zero(req, struct ps_context); if (ac == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } ac->module = module; ac->req = req; ac->pending = false; ac->saved_referrals = NULL; ac->num_referrals = 0; ldb = ldb_module_get_ctx(ac->module); control = talloc(ac, struct ldb_paged_control); if (!control) { return LDB_ERR_OPERATIONS_ERROR; } control->size = PS_DEFAULT_PAGE_SIZE; control->cookie = NULL; control->cookie_len = 0; ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac, ac->req->op.search.base, ac->req->op.search.scope, ac->req->op.search.tree, ac->req->op.search.attrs, ac->req->controls, ac, ps_callback, ac->req); LDB_REQ_SET_LOCATION(ac->down_req); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID, true, control); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(ac->down_req, control); return ldb_next_request(ac->module, ac->down_req); } static int check_supported_paged(struct ldb_request *req, struct ldb_reply *ares) { struct private_data *data; data = talloc_get_type(req->context, struct private_data); if (!ares) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } switch (ares->type) { case LDB_REPLY_ENTRY: if (ldb_msg_check_string_attribute(ares->message, "supportedControl", LDB_CONTROL_PAGED_RESULTS_OID)) { data->paged_supported = true; } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: return ldb_request_done(req, LDB_SUCCESS); } talloc_free(ares); return LDB_SUCCESS; } static int ps_init(struct ldb_module *module) { struct ldb_context *ldb; static const char *attrs[] = { "supportedControl", NULL }; struct private_data *data; struct ldb_dn *base; int ret; struct ldb_request *req; ldb = ldb_module_get_ctx(module); data = talloc(module, struct private_data); if (data == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } data->paged_supported = false; ldb_module_set_private(module, data); base = ldb_dn_new(module, ldb, ""); if (base == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_build_search_req(&req, ldb, module, base, LDB_SCOPE_BASE, "(objectClass=*)", attrs, NULL, data, check_supported_paged, NULL); LDB_REQ_SET_LOCATION(req); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_next_request(module, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { return ret; } talloc_free(base); talloc_free(req); return ldb_next_init(module); } static const struct ldb_module_ops ldb_paged_searches_module_ops = { .name = "paged_searches", .search = ps_search, .init_context = ps_init }; int ldb_paged_searches_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_module(&ldb_paged_searches_module_ops); } ldb-2.0.8/modules/rdn_name.c0000660000000000000000000004002113020021120015567 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Bartlett 2005-2009 Copyright (C) Simo Sorce 2006-2008 ** 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 . */ /* * Name: rdn_name * * Component: ldb rdn name module * * Description: keep a consistent name attribute on objects manpulations * * Author: Andrew Bartlett * * Modifications: * - made the module async * Simo Sorce Mar 2006 */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_module.h" struct rename_context { struct ldb_module *module; struct ldb_request *req; struct ldb_reply *ares; }; static int rdn_name_add_callback(struct ldb_request *req, struct ldb_reply *ares) { struct rename_context *ac; ac = talloc_get_type(req->context, struct rename_context); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->type == LDB_REPLY_REFERRAL) { return ldb_module_send_referral(ac->req, ares->referral); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } return ldb_module_done(ac->req, ares->controls, ares->response, LDB_SUCCESS); } static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct ldb_request *down_req; struct rename_context *ac; struct ldb_message *msg; struct ldb_message_element *attribute; const struct ldb_schema_attribute *a; const char *rdn_name; const struct ldb_val *rdn_val_p; struct ldb_val rdn_val; unsigned int i; int ret; ldb = ldb_module_get_ctx(module); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.add.message->dn)) { return ldb_next_request(module, req); } ac = talloc_zero(req, struct rename_context); if (ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ac->module = module; ac->req = req; msg = ldb_msg_copy_shallow(req, req->op.add.message); if (msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } rdn_name = ldb_dn_get_rdn_name(msg->dn); if (rdn_name == NULL) { return LDB_ERR_OPERATIONS_ERROR; } rdn_val_p = ldb_dn_get_rdn_val(msg->dn); if (rdn_val_p == NULL) { return LDB_ERR_OPERATIONS_ERROR; } if (rdn_val_p->length == 0) { ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", ldb_dn_get_linearized(req->op.add.message->dn)); return LDB_ERR_INVALID_DN_SYNTAX; } rdn_val = ldb_val_dup(msg, rdn_val_p); /* Perhaps someone above us tried to set this? Then ignore it */ ldb_msg_remove_attr(msg, "name"); ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); if (ret != LDB_SUCCESS) { return ret; } a = ldb_schema_attribute_by_name(ldb, rdn_name); if (a == NULL) { return LDB_ERR_OPERATIONS_ERROR; } attribute = ldb_msg_find_element(msg, rdn_name); if (!attribute) { /* add entry with normalised RDN information if possible */ if (a->name != NULL && strcmp(a->name, "*") != 0) { ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL); } else { ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); } if (ret != LDB_SUCCESS) { return ret; } } else { /* normalise attribute name if possible */ if (a->name != NULL && strcmp(a->name, "*") != 0) { attribute->name = a->name; } /* normalise attribute value */ for (i = 0; i < attribute->num_values; i++) { bool matched; if (a->syntax->operator_fn) { ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, &rdn_val, &attribute->values[i], &matched); if (ret != LDB_SUCCESS) return ret; } else { matched = (a->syntax->comparison_fn(ldb, msg, &rdn_val, &attribute->values[i]) == 0); } if (matched) { /* overwrite so it matches in case */ attribute->values[i] = rdn_val; break; } } if (i == attribute->num_values) { char *rdn_errstring = talloc_asprintf(ac, "RDN mismatch on %s: %s (%.*s) should match one of:", ldb_dn_get_linearized(msg->dn), rdn_name, (int)rdn_val.length, (const char *)rdn_val.data); for (i = 0; i < attribute->num_values; i++) { rdn_errstring = talloc_asprintf_append( rdn_errstring, " (%.*s)", (int)attribute->values[i].length, (const char *)attribute->values[i].data); } ldb_set_errstring(ldb, rdn_errstring); /* Match AD's error here */ return LDB_ERR_INVALID_DN_SYNTAX; } } ret = ldb_build_add_req(&down_req, ldb, req, msg, req->controls, ac, rdn_name_add_callback, req); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(down_req, msg); /* go on with the call chain */ return ldb_next_request(module, down_req); } static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares) { struct rename_context *ac; ac = talloc_get_type(req->context, struct rename_context); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->type == LDB_REPLY_REFERRAL) { return ldb_module_send_referral(ac->req, ares->referral); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } /* the only supported reply right now is a LDB_REPLY_DONE */ if (ares->type != LDB_REPLY_DONE) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* send saved controls eventually */ return ldb_module_done(ac->req, ac->ares->controls, ac->ares->response, LDB_SUCCESS); } static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct rename_context *ac; struct ldb_request *mod_req; const char *rdn_name; const struct ldb_schema_attribute *a = NULL; const struct ldb_val *rdn_val_p; struct ldb_val rdn_val; struct ldb_message *msg; int ret; ac = talloc_get_type(req->context, struct rename_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { goto error; } if (ares->type == LDB_REPLY_REFERRAL) { return ldb_module_send_referral(ac->req, ares->referral); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } /* the only supported reply right now is a LDB_REPLY_DONE */ if (ares->type != LDB_REPLY_DONE) { goto error; } /* save reply for caller */ ac->ares = talloc_steal(ac, ares); msg = ldb_msg_new(ac); if (msg == NULL) { goto error; } msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); if (msg->dn == NULL) { goto error; } rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); if (rdn_name == NULL) { goto error; } a = ldb_schema_attribute_by_name(ldb, rdn_name); if (a == NULL) { goto error; } if (a->name != NULL && strcmp(a->name, "*") != 0) { rdn_name = a->name; } rdn_val_p = ldb_dn_get_rdn_val(msg->dn); if (rdn_val_p == NULL) { goto error; } if (rdn_val_p->length == 0) { ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", ldb_dn_get_linearized(req->op.rename.olddn)); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_NAMING_VIOLATION); } rdn_val = ldb_val_dup(msg, rdn_val_p); if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { goto error; } if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { goto error; } if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { goto error; } if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { goto error; } ret = ldb_build_mod_req(&mod_req, ldb, ac, msg, NULL, ac, rdn_modify_callback, req); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } talloc_steal(mod_req, msg); /* go on with the call chain */ return ldb_next_request(ac->module, mod_req); error: return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct rename_context *ac; struct ldb_request *down_req; int ret; ldb = ldb_module_get_ctx(module); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.rename.newdn)) { return ldb_next_request(module, req); } ac = talloc_zero(req, struct rename_context); if (ac == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ac->module = module; ac->req = req; ret = ldb_build_rename_req(&down_req, ldb, ac, req->op.rename.olddn, req->op.rename.newdn, req->controls, ac, rdn_rename_callback, req); if (ret != LDB_SUCCESS) { return ret; } /* rename first, modify "name" if rename is ok */ return ldb_next_request(module, down_req); } static int rdn_recalculate_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request); talloc_steal(up_req, req); return up_req->callback(up_req, ares); } static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; const struct ldb_val *rdn_val_p; struct ldb_message_element *e = NULL; struct ldb_control *recalculate_rdn_control = NULL; ldb = ldb_module_get_ctx(module); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.mod.message->dn)) { return ldb_next_request(module, req); } recalculate_rdn_control = ldb_request_get_control(req, LDB_CONTROL_RECALCULATE_RDN_OID); if (recalculate_rdn_control != NULL) { struct ldb_message *msg = NULL; const char *rdn_name = NULL; struct ldb_val rdn_val; const struct ldb_schema_attribute *a = NULL; struct ldb_request *mod_req = NULL; int ret; struct ldb_message_element *rdn_del = NULL; struct ldb_message_element *name_del = NULL; recalculate_rdn_control->critical = false; msg = ldb_msg_copy_shallow(req, req->op.mod.message); if (msg == NULL) { return ldb_module_oom(module); } /* * The caller must pass a dummy 'name' attribute * in order to bypass some high level checks. * * We just remove it and check nothing is left. */ ldb_msg_remove_attr(msg, "name"); if (msg->num_elements != 0) { return ldb_module_operr(module); } rdn_name = ldb_dn_get_rdn_name(msg->dn); if (rdn_name == NULL) { return ldb_module_oom(module); } a = ldb_schema_attribute_by_name(ldb, rdn_name); if (a == NULL) { return ldb_module_operr(module); } if (a->name != NULL && strcmp(a->name, "*") != 0) { rdn_name = a->name; } rdn_val_p = ldb_dn_get_rdn_val(msg->dn); if (rdn_val_p == NULL) { return ldb_module_oom(module); } rdn_val = ldb_val_dup(msg, rdn_val_p); if (rdn_val.length == 0) { return ldb_module_oom(module); } /* * This is a bit tricky: * * We want _DELETE elements (as "rdn_del" and "name_del" without * values) first, followed by _ADD (with the real names) * elements (with values). Then we fix up the "rdn_del" and * "name_del" attributes. */ ret = ldb_msg_add_empty(msg, "rdn_del", LDB_FLAG_MOD_DELETE, NULL); if (ret != 0) { return ldb_module_oom(module); } ret = ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_ADD, NULL); if (ret != 0) { return ldb_module_oom(module); } ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); if (ret != 0) { return ldb_module_oom(module); } ret = ldb_msg_add_empty(msg, "name_del", LDB_FLAG_MOD_DELETE, NULL); if (ret != 0) { return ldb_module_oom(module); } ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_ADD, NULL); if (ret != 0) { return ldb_module_oom(module); } ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); if (ret != 0) { return ldb_module_oom(module); } rdn_del = ldb_msg_find_element(msg, "rdn_del"); if (rdn_del == NULL) { return ldb_module_operr(module); } rdn_del->name = talloc_strdup(msg->elements, rdn_name); if (rdn_del->name == NULL) { return ldb_module_oom(module); } name_del = ldb_msg_find_element(msg, "name_del"); if (name_del == NULL) { return ldb_module_operr(module); } name_del->name = talloc_strdup(msg->elements, "name"); if (name_del->name == NULL) { return ldb_module_oom(module); } ret = ldb_build_mod_req(&mod_req, ldb, req, msg, NULL, req, rdn_recalculate_callback, req); if (ret != LDB_SUCCESS) { return ldb_module_done(req, NULL, NULL, ret); } talloc_steal(mod_req, msg); ret = ldb_request_add_control(mod_req, LDB_CONTROL_RECALCULATE_RDN_OID, false, NULL); if (ret != LDB_SUCCESS) { return ldb_module_done(req, NULL, NULL, ret); } ret = ldb_request_add_control(mod_req, LDB_CONTROL_PERMISSIVE_MODIFY_OID, false, NULL); if (ret != LDB_SUCCESS) { return ldb_module_done(req, NULL, NULL, ret); } /* go on with the call chain */ return ldb_next_request(module, mod_req); } rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); if (rdn_val_p == NULL) { return LDB_ERR_OPERATIONS_ERROR; } if (rdn_val_p->length == 0) { ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", ldb_dn_get_linearized(req->op.mod.message->dn)); return LDB_ERR_INVALID_DN_SYNTAX; } e = ldb_msg_find_element(req->op.mod.message, "distinguishedName"); if (e != NULL) { ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", ldb_dn_get_linearized(req->op.mod.message->dn)); if (e->flags == LDB_FLAG_MOD_REPLACE) { return LDB_ERR_CONSTRAINT_VIOLATION; } else { return LDB_ERR_UNWILLING_TO_PERFORM; } } if (ldb_msg_find_element(req->op.mod.message, "name")) { ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", ldb_dn_get_linearized(req->op.mod.message->dn)); return LDB_ERR_NOT_ALLOWED_ON_RDN; } if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); return LDB_ERR_NOT_ALLOWED_ON_RDN; } /* All OK, they kept their fingers out of the special attributes */ return ldb_next_request(module, req); } static int rdn_name_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; const char *rdn_name; const struct ldb_val *rdn_val_p; ldb = ldb_module_get_ctx(module); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.search.base)) { return ldb_next_request(module, req); } rdn_name = ldb_dn_get_rdn_name(req->op.search.base); rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base); if ((rdn_name != NULL) && (rdn_val_p == NULL)) { return LDB_ERR_OPERATIONS_ERROR; } if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) { ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", ldb_dn_get_linearized(req->op.search.base)); return LDB_ERR_INVALID_DN_SYNTAX; } return ldb_next_request(module, req); } static const struct ldb_module_ops ldb_rdn_name_module_ops = { .name = "rdn_name", .add = rdn_name_add, .modify = rdn_name_modify, .rename = rdn_name_rename, .search = rdn_name_search }; int ldb_rdn_name_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_module(&ldb_rdn_name_module_ops); } ldb-2.0.8/modules/skel.c0000660000000000000000000000674212406075657015015 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2004 ** 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 . */ /* * Name: ldb * * Component: ldb skel module * * Description: example module * * Author: Simo Sorce */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_module.h" struct private_data { char *some_private_data; }; /* search */ static int skel_search(struct ldb_module *module, struct ldb_request *req) { return ldb_next_request(module, req); } /* add */ static int skel_add(struct ldb_module *module, struct ldb_request *req){ return ldb_next_request(module, req); } /* modify */ static int skel_modify(struct ldb_module *module, struct ldb_request *req) { return ldb_next_request(module, req); } /* delete */ static int skel_delete(struct ldb_module *module, struct ldb_request *req) { return ldb_next_request(module, req); } /* rename */ static int skel_rename(struct ldb_module *module, struct ldb_request *req) { return ldb_next_request(module, req); } /* start a transaction */ static int skel_start_trans(struct ldb_module *module) { return ldb_next_start_trans(module); } /* end a transaction */ static int skel_end_trans(struct ldb_module *module) { return ldb_next_end_trans(module); } /* delete a transaction */ static int skel_del_trans(struct ldb_module *module) { return ldb_next_del_trans(module); } static int skel_destructor(struct ldb_module *ctx) { struct private_data *data; data = talloc_get_type(ldb_module_get_private(ctx), struct private_data); /* put your clean-up functions here */ if (data->some_private_data) talloc_free(data->some_private_data); return 0; } static int skel_request(struct ldb_module *module, struct ldb_request *req) { return ldb_next_request(module, req); } static int skel_init(struct ldb_module *module) { struct ldb_context *ldb; struct private_data *data; ldb = ldb_module_get_ctx(module); data = talloc(module, struct private_data); if (data == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } data->some_private_data = NULL; ldb_module_set_private(module, data); talloc_set_destructor (module, skel_destructor); return ldb_next_init(module); } static const struct ldb_module_ops ldb_skel_module_ops = { .name = "skel", .init_context = skel_init, .search = skel_search, .add = skel_add, .modify = skel_modify, .del = skel_delete, .rename = skel_rename, .request = skel_request, .start_transaction = skel_start_trans, .end_transaction = skel_end_trans, .del_transaction = skel_del_trans, }; int ldb_skel_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_module(&ldb_skel_module_ops); } ldb-2.0.8/modules/sort.c0000660000000000000000000002341012702766507015035 0ustar rootroot00000000000000/* ldb database library Copyright (C) Simo Sorce 2005-2008 ** 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 . */ /* * Name: ldb * * Component: ldb server side sort control module * * Description: this module sorts the results of a search * * Author: Simo Sorce */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb_module.h" struct opaque { struct ldb_context *ldb; const struct ldb_attrib_handler *h; const char *attribute; int reverse; int result; }; struct sort_context { struct ldb_module *module; const char *attributeName; const char *orderingRule; int reverse; struct ldb_request *req; struct ldb_message **msgs; char **referrals; unsigned int num_msgs; unsigned int num_refs; const char *extra_sort_key; const struct ldb_schema_attribute *a; int sort_result; }; static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result, const char *desc) { struct ldb_control **controls; struct ldb_sort_resp_control *resp; unsigned int i; if (*ctrls) { controls = *ctrls; for (i = 0; controls[i]; i++); controls = talloc_realloc(mem_ctx, controls, struct ldb_control *, i + 2); } else { i = 0; controls = talloc_array(mem_ctx, struct ldb_control *, 2); } if (! controls ) return LDB_ERR_OPERATIONS_ERROR; *ctrls = controls; controls[i+1] = NULL; controls[i] = talloc(controls, struct ldb_control); if (! controls[i] ) return LDB_ERR_OPERATIONS_ERROR; controls[i]->oid = LDB_CONTROL_SORT_RESP_OID; controls[i]->critical = 0; resp = talloc(controls[i], struct ldb_sort_resp_control); if (! resp ) return LDB_ERR_OPERATIONS_ERROR; resp->result = result; resp->attr_desc = talloc_strdup(resp, desc); if (! resp->attr_desc ) return LDB_ERR_OPERATIONS_ERROR; controls[i]->data = resp; return LDB_SUCCESS; } static int sort_compare(struct ldb_message **msg1, struct ldb_message **msg2, void *opaque) { struct sort_context *ac = talloc_get_type(opaque, struct sort_context); struct ldb_message_element *el1, *el2; struct ldb_context *ldb; ldb = ldb_module_get_ctx(ac->module); if (ac->sort_result != 0) { /* an error occurred previously, * let's exit the sorting by returning always 0 */ return 0; } el1 = ldb_msg_find_element(*msg1, ac->attributeName); el2 = ldb_msg_find_element(*msg2, ac->attributeName); if (!el1 && el2) { return 1; } if (el1 && !el2) { return -1; } if (!el1 && !el2) { return 0; } if (ac->reverse) return ac->a->syntax->comparison_fn(ldb, ac, &el2->values[0], &el1->values[0]); return ac->a->syntax->comparison_fn(ldb, ac, &el1->values[0], &el2->values[0]); } static int server_sort_results(struct sort_context *ac) { struct ldb_context *ldb; struct ldb_reply *ares; unsigned int i; int ret; ldb = ldb_module_get_ctx(ac->module); ac->a = ldb_schema_attribute_by_name(ldb, ac->attributeName); ac->sort_result = 0; LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare); if (ac->sort_result != LDB_SUCCESS) { return ac->sort_result; } for (i = 0; i < ac->num_msgs; i++) { ares = talloc_zero(ac, struct ldb_reply); if (!ares) { return LDB_ERR_OPERATIONS_ERROR; } ares->type = LDB_REPLY_ENTRY; ares->message = talloc_move(ares, &ac->msgs[i]); if (ac->extra_sort_key) { ldb_msg_remove_attr(ares->message, ac->extra_sort_key); } ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); if (ret != LDB_SUCCESS) { return ret; } } for (i = 0; i < ac->num_refs; i++) { ares = talloc_zero(ac, struct ldb_reply); if (!ares) { return LDB_ERR_OPERATIONS_ERROR; } ares->type = LDB_REPLY_REFERRAL; ares->referral = talloc_move(ares, &ac->referrals[i]); ret = ldb_module_send_referral(ac->req, ares->referral); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; } static int server_sort_search_callback(struct ldb_request *req, struct ldb_reply *ares) { struct sort_context *ac; struct ldb_context *ldb; int ret; ac = talloc_get_type(req->context, struct sort_context); ldb = ldb_module_get_ctx(ac->module); if (!ares) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ac->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: ac->msgs = talloc_realloc(ac, ac->msgs, struct ldb_message *, ac->num_msgs + 2); if (! ac->msgs) { talloc_free(ares); ldb_oom(ldb); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } ac->msgs[ac->num_msgs] = talloc_steal(ac->msgs, ares->message); ac->num_msgs++; ac->msgs[ac->num_msgs] = NULL; break; case LDB_REPLY_REFERRAL: ac->referrals = talloc_realloc(ac, ac->referrals, char *, ac->num_refs + 2); if (! ac->referrals) { talloc_free(ares); ldb_oom(ldb); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } ac->referrals[ac->num_refs] = talloc_steal(ac->referrals, ares->referral); ac->num_refs++; ac->referrals[ac->num_refs] = NULL; break; case LDB_REPLY_DONE: ret = server_sort_results(ac); return ldb_module_done(ac->req, ares->controls, ares->response, ret); } talloc_free(ares); return LDB_SUCCESS; } static int server_sort_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_control *control; struct ldb_server_sort_control **sort_ctrls; struct ldb_control **saved_controls; struct ldb_request *down_req; struct sort_context *ac; struct ldb_context *ldb; int ret; const char * const *attrs; size_t n_attrs, i; const char *sort_attr; ldb = ldb_module_get_ctx(module); /* check if there's a server sort control */ control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID); if (control == NULL) { /* not found go on */ return ldb_next_request(module, req); } ac = talloc_zero(req, struct sort_context); if (ac == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } ac->module = module; ac->req = req; sort_ctrls = talloc_get_type(control->data, struct ldb_server_sort_control *); if (!sort_ctrls) { return LDB_ERR_PROTOCOL_ERROR; } /* FIXME: we do not support more than one attribute for sorting right now */ /* FIXME: we need to check if the attribute type exist or return an error */ if (sort_ctrls[1] != NULL) { if (control->critical) { struct ldb_control **controls = NULL; /* callback immediately */ ret = build_response(req, &controls, LDB_ERR_UNWILLING_TO_PERFORM, "sort control is not complete yet"); if (ret != LDB_SUCCESS) { return ldb_module_done(req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } return ldb_module_done(req, controls, NULL, ret); } else { /* just pass the call down and don't do any sorting */ return ldb_next_request(module, req); } } control->critical = 0; /* We are asked to sort on an attribute, and if that attribute is not already in the search attributes we need to add it (and later remove it on the return journey). */ sort_attr = sort_ctrls[0]->attributeName; if (req->op.search.attrs == NULL) { /* This means all non-operational attributes, which means there's nothing to add. */ attrs = NULL; } else { n_attrs = 0; while (req->op.search.attrs[n_attrs] != NULL) { if (sort_attr && strcmp(req->op.search.attrs[n_attrs], sort_attr) == 0) { sort_attr = NULL; } n_attrs++; } if (sort_attr == NULL) { attrs = req->op.search.attrs; } else { const char **tmp = talloc_array(ac, const char *, n_attrs + 2); for (i = 0; i < n_attrs; i++) { tmp[i] = req->op.search.attrs[i]; } ac->extra_sort_key = sort_attr; tmp[n_attrs] = sort_attr; tmp[n_attrs + 1] = NULL; attrs = tmp; } } ac->attributeName = sort_ctrls[0]->attributeName; ac->orderingRule = sort_ctrls[0]->orderingRule; ac->reverse = sort_ctrls[0]->reverse; ret = ldb_build_search_req_ex(&down_req, ldb, ac, req->op.search.base, req->op.search.scope, req->op.search.tree, attrs, req->controls, ac, server_sort_search_callback, req); if (ret != LDB_SUCCESS) { return ret; } /* save it locally and remove it from the list */ /* we do not need to replace them later as we * are keeping the original req intact */ if (!ldb_save_controls(control, down_req, &saved_controls)) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_next_request(module, down_req); } static int server_sort_init(struct ldb_module *module) { struct ldb_context *ldb; int ret; ldb = ldb_module_get_ctx(module); ret = ldb_mod_register_control(module, LDB_CONTROL_SERVER_SORT_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_WARNING, "server_sort:" "Unable to register control with rootdse!"); } return ldb_next_init(module); } static const struct ldb_module_ops ldb_server_sort_module_ops = { .name = "server_sort", .search = server_sort_search, .init_context = server_sort_init }; int ldb_server_sort_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_module(&ldb_server_sort_module_ops); } ldb-2.0.8/nssldb/README.txt0000660000000000000000000000215512406075657015220 0ustar rootroot00000000000000 This test code requires a tdb that is configured for to use the asq module. You can do that adding the following record to a tdb: dn: @MODULES @LIST: asq Other modules can be used as well (like rdn_name for example) The uidNumber 0 and the gidNumber 0 are considered invalid. The user records should contain the followin attributes: uid (required) the user name userPassword (optional) the user password (if not present "LDB" is returned in the password field) uidNumber (required) the user uid gidNumber (required) the user primary gid gecos (optional) the GECOS homeDirectory (required) the home directory loginShell (required) the login shell memberOf (required) all the groups the user is member of should be reported here using their DNs. The primary group as well. The group accounts should contain the following attributes: cn (required) the group name uesrPassword (optional) the group password (if not present "LDB" is returned in the password field) gidNumber (required) the group gid member (optional) the DNs of the member users, also the ones that have this group as primary SSS ldb-2.0.8/nssldb/ldb-grp.c0000660000000000000000000002064412406075657015220 0ustar rootroot00000000000000/* LDB nsswitch module Copyright (C) Simo Sorce 2006 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 Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "ldb-nss.h" extern struct _ldb_nss_context *_ldb_nss_ctx; const char *_ldb_nss_gr_attrs[] = { "cn", "userPassword", "gidNumber", NULL }; const char *_ldb_nss_mem_attrs[] = { "uid", NULL }; #define _NSS_LDB_ENOMEM(amem) \ do { \ if ( ! amem) { \ errno = ENOMEM; \ talloc_free(memctx); \ return NSS_STATUS_UNAVAIL; \ } \ } while(0) /* This setgrent, getgrent, endgrent is not very efficient */ NSS_STATUS _nss_ldb_setgrent(void) { int ret; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } _ldb_nss_ctx->gr_cur = 0; if (_ldb_nss_ctx->gr_res != NULL) { talloc_free(_ldb_nss_ctx->gr_res); _ldb_nss_ctx->gr_res = NULL; } ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &_ldb_nss_ctx->gr_res, _ldb_nss_ctx->base, LDB_SCOPE_SUBTREE, _ldb_nss_gr_attrs, _LDB_NSS_GRENT_FILTER); if (ret != LDB_SUCCESS) { return NSS_STATUS_UNAVAIL; } return NSS_STATUS_SUCCESS; } NSS_STATUS _nss_ldb_endgrent(void) { int ret; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } _ldb_nss_ctx->gr_cur = 0; if (_ldb_nss_ctx->gr_res) { talloc_free(_ldb_nss_ctx->gr_res); _ldb_nss_ctx->gr_res = NULL; } return NSS_STATUS_SUCCESS; } NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop) { int ret; struct ldb_result *res; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } *errnop = 0; if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) { /* already returned all entries */ return NSS_STATUS_NOTFOUND; } res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result); if ( ! res) { errno = *errnop = ENOMEM; _ldb_nss_ctx->gr_cur++; /* skip this entry */ return NSS_STATUS_UNAVAIL; } ret = _ldb_nss_group_request(&res, _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn, _ldb_nss_mem_attrs, "member"); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno; talloc_free(res); _ldb_nss_ctx->gr_cur++; /* skip this entry */ return ret; } ret = _ldb_nss_fill_group(result_buf, buffer, buflen, errnop, _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur], res); talloc_free(res); if (ret != NSS_STATUS_SUCCESS) { if (ret != NSS_STATUS_TRYAGAIN) { _ldb_nss_ctx->gr_cur++; /* skip this entry */ } return ret; } /* this entry is ok, increment counter to nex entry */ _ldb_nss_ctx->gr_cur++; return NSS_STATUS_SUCCESS; } NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop) { int ret; char *filter; TALLOC_CTX *ctx; struct ldb_result *gr_res; struct ldb_result *mem_res; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } ctx = talloc_new(_ldb_nss_ctx->ldb); if ( ! ctx) { *errnop = errno = ENOMEM; return NSS_STATUS_UNAVAIL; } /* build the filter for this uid */ filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name); if (filter == NULL) { /* this is a fatal error */ *errnop = errno = ENOMEM; ret = NSS_STATUS_UNAVAIL; goto done; } /* search the entry */ ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &gr_res, _ldb_nss_ctx->base, LDB_SCOPE_SUBTREE, _ldb_nss_gr_attrs, filter); if (ret != LDB_SUCCESS) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } talloc_steal(ctx, gr_res); /* if none found return */ if (gr_res->count == 0) { *errnop = errno = ENOENT; ret = NSS_STATUS_NOTFOUND; goto done; } if (gr_res->count != 1) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } mem_res = talloc_zero(ctx, struct ldb_result); if ( ! mem_res) { errno = *errnop = ENOMEM; ret = NSS_STATUS_UNAVAIL; goto done; } ret = _ldb_nss_group_request(&mem_res, gr_res->msgs[0]->dn, _ldb_nss_mem_attrs, "member"); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno; goto done; } ret = _ldb_nss_fill_group(result_buf, buffer, buflen, errnop, gr_res->msgs[0], mem_res); if (ret != NSS_STATUS_SUCCESS) { goto done; } ret = NSS_STATUS_SUCCESS; done: talloc_free(ctx); return ret; } NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop) { int ret; char *filter; TALLOC_CTX *ctx; struct ldb_result *gr_res; struct ldb_result *mem_res; if (gid == 0) { /* we don't serve root gid by policy */ *errnop = errno = ENOENT; return NSS_STATUS_NOTFOUND; } ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } ctx = talloc_new(_ldb_nss_ctx->ldb); if ( ! ctx) { *errnop = errno = ENOMEM; return NSS_STATUS_UNAVAIL; } /* build the filter for this uid */ filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid); if (filter == NULL) { /* this is a fatal error */ *errnop = errno = ENOMEM; ret = NSS_STATUS_UNAVAIL; goto done; } /* search the entry */ ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &gr_res, _ldb_nss_ctx->base, LDB_SCOPE_SUBTREE, _ldb_nss_gr_attrs, filter); if (ret != LDB_SUCCESS) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } talloc_steal(ctx, gr_res); /* if none found return */ if (gr_res->count == 0) { *errnop = errno = ENOENT; ret = NSS_STATUS_NOTFOUND; goto done; } if (gr_res->count != 1) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } mem_res = talloc_zero(ctx, struct ldb_result); if ( ! mem_res) { errno = *errnop = ENOMEM; ret = NSS_STATUS_UNAVAIL; goto done; } ret = _ldb_nss_group_request(&mem_res, gr_res->msgs[0]->dn, _ldb_nss_mem_attrs, "member"); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno; goto done; } ret = _ldb_nss_fill_group(result_buf, buffer, buflen, errnop, gr_res->msgs[0], mem_res); if (ret != NSS_STATUS_SUCCESS) { goto done; } ret = NSS_STATUS_SUCCESS; done: talloc_free(ctx); return ret; } NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop) { int ret; char *filter; const char * attrs[] = { "uidNumber", "gidNumber", NULL }; struct ldb_result *uid_res; struct ldb_result *mem_res; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result); if ( ! mem_res) { errno = *errnop = ENOMEM; return NSS_STATUS_UNAVAIL; } /* build the filter for this name */ filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user); if (filter == NULL) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } /* search the entry */ ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &uid_res, _ldb_nss_ctx->base, LDB_SCOPE_SUBTREE, attrs, filter); if (ret != LDB_SUCCESS) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } talloc_steal(mem_res, uid_res); /* if none found return */ if (uid_res->count == 0) { *errnop = errno = ENOENT; ret = NSS_STATUS_NOTFOUND; goto done; } if (uid_res->count != 1) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } ret = _ldb_nss_group_request(&mem_res, uid_res->msgs[0]->dn, attrs, "memberOf"); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno; goto done; } ret = _ldb_nss_fill_initgr(group, limit, start, size, groups, errnop, mem_res); if (ret != NSS_STATUS_SUCCESS) { goto done; } ret = NSS_STATUS_SUCCESS; done: talloc_free(mem_res); return ret; } ldb-2.0.8/nssldb/ldb-nss.c0000660000000000000000000002144412406075657015232 0ustar rootroot00000000000000/* LDB nsswitch module Copyright (C) Simo Sorce 2006 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 Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "ldb-nss.h" struct _ldb_nss_context *_ldb_nss_ctx = NULL; NSS_STATUS _ldb_nss_init(void) { int ret; pid_t mypid = getpid(); if (_ldb_nss_ctx != NULL) { if (_ldb_nss_ctx->pid == mypid) { /* already initialized */ return NSS_STATUS_SUCCESS; } else { /* we are in a forked child now, reinitialize */ talloc_free(_ldb_nss_ctx); _ldb_nss_ctx = NULL; } } _ldb_nss_ctx = talloc_named(NULL, 0, "_ldb_nss_ctx(%u)", mypid); if (_ldb_nss_ctx == NULL) { return NSS_STATUS_UNAVAIL; } _ldb_nss_ctx->pid = mypid; _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx, NULL); if (_ldb_nss_ctx->ldb == NULL) { goto failed; } ret = ldb_connect(_ldb_nss_ctx->ldb, _LDB_NSS_URL, LDB_FLG_RDONLY, NULL); if (ret != LDB_SUCCESS) { goto failed; } _ldb_nss_ctx->base = ldb_dn_new(_ldb_nss_ctx, _ldb_nss_ctx->ldb, _LDB_NSS_BASEDN); if ( ! ldb_dn_validate(_ldb_nss_ctx->base)) { goto failed; } _ldb_nss_ctx->pw_cur = 0; _ldb_nss_ctx->pw_res = NULL; _ldb_nss_ctx->gr_cur = 0; _ldb_nss_ctx->gr_res = NULL; return NSS_STATUS_SUCCESS; failed: /* talloc_free(_ldb_nss_ctx); */ _ldb_nss_ctx = NULL; return NSS_STATUS_UNAVAIL; } NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, char *buffer, int buflen, int *errnop, struct ldb_message *msg) { int len; int bufpos; const char *tmp; bufpos = 0; /* get username */ tmp = ldb_msg_find_attr_as_string(msg, "uid", NULL); if (tmp == NULL) { /* this is a fatal error */ *errnop = errno = ENOENT; return NSS_STATUS_UNAVAIL; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->pw_name = &buffer[bufpos]; bufpos += len; /* get userPassword */ tmp = ldb_msg_find_attr_as_string(msg, "userPassword", NULL); if (tmp == NULL) { tmp = "LDB"; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->pw_passwd = &buffer[bufpos]; bufpos += len; /* this backend never serves an uid 0 user */ result->pw_uid = ldb_msg_find_attr_as_int(msg, "uidNumber", 0); if (result->pw_uid == 0) { /* this is a fatal error */ *errnop = errno = ENOENT; return NSS_STATUS_UNAVAIL; } result->pw_gid = ldb_msg_find_attr_as_int(msg, "gidNumber", 0); if (result->pw_gid == 0) { /* this is a fatal error */ *errnop = errno = ENOENT; return NSS_STATUS_UNAVAIL; } /* get gecos */ tmp = ldb_msg_find_attr_as_string(msg, "gecos", NULL); if (tmp == NULL) { tmp = ""; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->pw_gecos = &buffer[bufpos]; bufpos += len; /* get homeDirectory */ tmp = ldb_msg_find_attr_as_string(msg, "homeDirectory", NULL); if (tmp == NULL) { tmp = ""; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->pw_dir = &buffer[bufpos]; bufpos += len; /* get shell */ tmp = ldb_msg_find_attr_as_string(msg, "loginShell", NULL); if (tmp == NULL) { tmp = ""; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->pw_shell = &buffer[bufpos]; bufpos += len; return NSS_STATUS_SUCCESS; } NSS_STATUS _ldb_nss_fill_group(struct group *result, char *buffer, int buflen, int *errnop, struct ldb_message *group, struct ldb_result *members) { const char *tmp; size_t len; size_t bufpos; size_t lsize; unsigned int i; bufpos = 0; /* get group name */ tmp = ldb_msg_find_attr_as_string(group, "cn", NULL); if (tmp == NULL) { /* this is a fatal error */ *errnop = errno = ENOENT; return NSS_STATUS_UNAVAIL; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->gr_name = &buffer[bufpos]; bufpos += len; /* get userPassword */ tmp = ldb_msg_find_attr_as_string(group, "userPassword", NULL); if (tmp == NULL) { tmp = "LDB"; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->gr_passwd = &buffer[bufpos]; bufpos += len; result->gr_gid = ldb_msg_find_attr_as_int(group, "gidNumber", 0); if (result->gr_gid == 0) { /* this is a fatal error */ *errnop = errno = ENOENT; return NSS_STATUS_UNAVAIL; } /* check if there is enough memory for the list of pointers */ lsize = (members->count + 1) * sizeof(char *); /* align buffer on pointer boundary */ bufpos += (sizeof(char*) - ((unsigned long)(buffer) % sizeof(char*))); if ((buflen - bufpos) < lsize) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } result->gr_mem = (char **)&buffer[bufpos]; bufpos += lsize; for (i = 0; i < members->count; i++) { tmp = ldb_msg_find_attr_as_string(members->msgs[i], "uid", NULL); if (tmp == NULL) { /* this is a fatal error */ *errnop = errno = ENOENT; return NSS_STATUS_UNAVAIL; } len = strlen(tmp)+1; if (bufpos + len > buflen) { /* buffer too small */ *errnop = errno = EAGAIN; return NSS_STATUS_TRYAGAIN; } memcpy(&buffer[bufpos], tmp, len); result->gr_mem[i] = &buffer[bufpos]; bufpos += len; } result->gr_mem[i] = NULL; return NSS_STATUS_SUCCESS; } NSS_STATUS _ldb_nss_fill_initgr(gid_t group, long int limit, long int *start, long int *size, gid_t **groups, int *errnop, struct ldb_result *grlist) { NSS_STATUS ret; unsigned int i; for (i = 0; i < grlist->count; i++) { if (limit && (*start > limit)) { /* TODO: warn no all groups were reported */ *errnop = 0; ret = NSS_STATUS_SUCCESS; goto done; } if (*start == *size) { /* buffer full, enlarge it */ long int gs; gid_t *gm; gs = (*size) + 32; if (limit && (gs > limit)) { gs = limit; } gm = (gid_t *)realloc((*groups), gs * sizeof(gid_t)); if ( ! gm) { *errnop = ENOMEM; ret = NSS_STATUS_UNAVAIL; goto done; } *groups = gm; *size = gs; } (*groups)[*start] = ldb_msg_find_attr_as_int(grlist->msgs[i], "gidNumber", 0); if ((*groups)[*start] == 0 || (*groups)[*start] == group) { /* skip root group or primary group */ continue; } (*start)++; } *errnop = 0; ret = NSS_STATUS_SUCCESS; done: return ret; } #define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) NSS_STATUS _ldb_nss_group_request(struct ldb_result **_res, struct ldb_dn *group_dn, const char * const *attrs, const char *mattr) { struct ldb_control **ctrls; struct ldb_control *ctrl; struct ldb_asq_control *asqc; struct ldb_request *req; int ret; struct ldb_result *res = *_res; ctrls = talloc_array(res, struct ldb_control *, 2); _LDB_NSS_ALLOC_CHECK(ctrls); ctrl = talloc(ctrls, struct ldb_control); _LDB_NSS_ALLOC_CHECK(ctrl); asqc = talloc(ctrl, struct ldb_asq_control); _LDB_NSS_ALLOC_CHECK(asqc); asqc->source_attribute = talloc_strdup(asqc, mattr); _LDB_NSS_ALLOC_CHECK(asqc->source_attribute); asqc->request = 1; asqc->src_attr_len = strlen(asqc->source_attribute); ctrl->oid = LDB_CONTROL_ASQ_OID; ctrl->critical = 1; ctrl->data = asqc; ctrls[0] = ctrl; ctrls[1] = NULL; ret = ldb_build_search_req( &req, _ldb_nss_ctx->ldb, res, group_dn, LDB_SCOPE_BASE, "(objectClass=*)", attrs, ctrls, res, ldb_search_default_callback); if (ret != LDB_SUCCESS) { errno = ENOENT; return NSS_STATUS_UNAVAIL; } ldb_set_timeout(_ldb_nss_ctx->ldb, req, 0); ret = ldb_request(_ldb_nss_ctx->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } else { talloc_free(req); return NSS_STATUS_UNAVAIL; } talloc_free(req); return NSS_STATUS_SUCCESS; } ldb-2.0.8/nssldb/ldb-nss.h0000660000000000000000000000452312406075657015236 0ustar rootroot00000000000000/* LDB nsswitch module Copyright (C) Simo Sorce 2006 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 Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _LDB_NSS #define _LDB_NSS #include "includes.h" #include "ldb/include/includes.h" #include #include #include #define _LDB_NSS_URL "etc/users.ldb" #define _LDB_NSS_BASEDN "CN=Users,CN=System" #define _LDB_NSS_PWENT_FILTER "(&(objectClass=posixAccount)(!(uidNumber=0))(!(gidNumber=0)))" #define _LDB_NSS_PWUID_FILTER "(&(objectClass=posixAccount)(uidNumber=%d)(!(gidNumber=0)))" #define _LDB_NSS_PWNAM_FILTER "(&(objectClass=posixAccount)(uid=%s)(!(uidNumber=0))(!(gidNumber=0)))" #define _LDB_NSS_GRENT_FILTER "(&(objectClass=posixGroup)(!(gidNumber=0)))" #define _LDB_NSS_GRGID_FILTER "(&(objectClass=posixGroup)(gidNumber=%d)))" #define _LDB_NSS_GRNAM_FILTER "(&(objectClass=posixGroup)(cn=%s)(!(gidNumber=0)))" typedef enum nss_status NSS_STATUS; struct _ldb_nss_context { pid_t pid; struct ldb_context *ldb; struct ldb_dn *base; int pw_cur; struct ldb_result *pw_res; int gr_cur; struct ldb_result *gr_res; }; NSS_STATUS _ldb_nss_init(void); NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, char *buffer, int buflen, int *errnop, struct ldb_message *msg); NSS_STATUS _ldb_nss_fill_group(struct group *result, char *buffer, int buflen, int *errnop, struct ldb_message *group, struct ldb_result *members); NSS_STATUS _ldb_nss_fill_initgr(gid_t group, long int limit, long int *start, long int *size, gid_t **groups, int *errnop, struct ldb_result *grlist); NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, struct ldb_dn *group_dn, const char * const *attrs, const char *mattr); #endif /* _LDB_NSS */ ldb-2.0.8/nssldb/ldb-pwd.c0000660000000000000000000001154412406075657015221 0ustar rootroot00000000000000/* LDB nsswitch module Copyright (C) Simo Sorce 2006 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 Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "ldb-nss.h" extern struct _ldb_nss_context *_ldb_nss_ctx; const char *_ldb_nss_pw_attrs[] = { "uid", "userPassword", "uidNumber", "gidNumber", "gecos", "homeDirectory", "loginShell", NULL }; NSS_STATUS _nss_ldb_setpwent(void) { int ret; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } _ldb_nss_ctx->pw_cur = 0; if (_ldb_nss_ctx->pw_res != NULL) { talloc_free(_ldb_nss_ctx->pw_res); _ldb_nss_ctx->pw_res = NULL; } ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &_ldb_nss_ctx->pw_res, _ldb_nss_ctx->base, LDB_SCOPE_SUBTREE, _ldb_nss_pw_attrs, _LDB_NSS_PWENT_FILTER); if (ret != LDB_SUCCESS) { return NSS_STATUS_UNAVAIL; } return NSS_STATUS_SUCCESS; } NSS_STATUS _nss_ldb_endpwent(void) { int ret; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } _ldb_nss_ctx->pw_cur = 0; if (_ldb_nss_ctx->pw_res) { talloc_free(_ldb_nss_ctx->pw_res); _ldb_nss_ctx->pw_res = NULL; } return NSS_STATUS_SUCCESS; } NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf, char *buffer, int buflen, int *errnop) { int ret; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } *errnop = 0; if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) { /* already returned all entries */ return NSS_STATUS_NOTFOUND; } ret = _ldb_nss_fill_passwd(result_buf, buffer, buflen, errnop, _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]); if (ret != NSS_STATUS_SUCCESS) { return ret; } _ldb_nss_ctx->pw_cur++; return NSS_STATUS_SUCCESS; } NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) { int ret; char *filter; struct ldb_result *res; if (uid == 0) { /* we don't serve root uid by policy */ *errnop = errno = ENOENT; return NSS_STATUS_NOTFOUND; } ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } /* build the filter for this uid */ filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid); if (filter == NULL) { /* this is a fatal error */ *errnop = errno = ENOMEM; ret = NSS_STATUS_UNAVAIL; goto done; } /* search the entry */ ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &res, _ldb_nss_ctx->base, LDB_SCOPE_SUBTREE, _ldb_nss_pw_attrs, filter); if (ret != LDB_SUCCESS) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } /* if none found return */ if (res->count == 0) { *errnop = errno = ENOENT; ret = NSS_STATUS_NOTFOUND; goto done; } if (res->count != 1) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } /* fill in the passwd struct */ ret = _ldb_nss_fill_passwd(result_buf, buffer, buflen, errnop, res->msgs[0]); done: talloc_free(filter); talloc_free(res); return ret; } NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) { int ret; char *filter; struct ldb_result *res; ret = _ldb_nss_init(); if (ret != NSS_STATUS_SUCCESS) { return ret; } /* build the filter for this name */ filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name); if (filter == NULL) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } /* search the entry */ ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &res, _ldb_nss_ctx->base, LDB_SCOPE_SUBTREE, _ldb_nss_pw_attrs, filter); if (ret != LDB_SUCCESS) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } /* if none found return */ if (res->count == 0) { *errnop = errno = ENOENT; ret = NSS_STATUS_NOTFOUND; goto done; } if (res->count != 1) { /* this is a fatal error */ *errnop = errno = ENOENT; ret = NSS_STATUS_UNAVAIL; goto done; } /* fill in the passwd struct */ ret = _ldb_nss_fill_passwd(result_buf, buffer, buflen, errnop, res->msgs[0]); done: talloc_free(filter); talloc_free(res); return ret; } ldb-2.0.8/pyldb-util.pc.in0000660000000000000000000000053413100601766015236 0ustar rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ modulesdir=@LDB_MODULESDIR@ Name: pyldb-util@PYTHON_SO_ABI_FLAG@ Description: Python bindings for LDB Version: @PACKAGE_VERSION@ Requires: ldb Libs: @LIB_RPATH@ -L${libdir} -lpyldb-util@PYTHON_LIBNAME_SO_ABI_FLAG@ Cflags: -I${includedir} URL: http://ldb.samba.org/ ldb-2.0.8/pyldb.c0000660000000000000000000034402113573675413013516 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python interface to ldb. Copyright (C) 2005,2006 Tim Potter Copyright (C) 2006 Simo Sorce Copyright (C) 2007-2010 Jelmer Vernooij Copyright (C) 2009-2010 Matthias Dieter Wallnöfer Copyright (C) 2009-2011 Andrew Tridgell Copyright (C) 2009-2011 Andrew Bartlett ** 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 . */ #include #include "ldb_private.h" #include "ldb_handlers.h" #include "pyldb.h" #include "dlinklist.h" /* discard signature of 'func' in favour of 'target_sig' */ #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func struct py_ldb_search_iterator_reply; typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; PyLdbObject *ldb; struct { struct ldb_request *req; struct py_ldb_search_iterator_reply *next; struct py_ldb_search_iterator_reply *result; PyObject *exception; } state; } PyLdbSearchIteratorObject; struct py_ldb_search_iterator_reply { struct py_ldb_search_iterator_reply *prev, *next; PyLdbSearchIteratorObject *py_iter; PyObject *obj; }; void initldb(void); static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg); static PyObject *PyExc_LdbError; static PyTypeObject PyLdbControl; static PyTypeObject PyLdbResult; static PyTypeObject PyLdbSearchIterator; static PyTypeObject PyLdbMessage; #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage) static PyTypeObject PyLdbModule; static PyTypeObject PyLdbDn; #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn) static PyTypeObject PyLdb; #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb) static PyTypeObject PyLdbMessageElement; #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement) static PyTypeObject PyLdbTree; static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx); static PyObject *PyLdbModule_FromModule(struct ldb_module *mod); static struct ldb_message_element *PyObject_AsMessageElement( TALLOC_CTX *mem_ctx, PyObject *set_obj, unsigned int flags, const char *attr_name); static PyTypeObject PyLdbBytesType; #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #define PYARG_STR_UNI "es" static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size) { PyObject* result = NULL; PyObject* args = NULL; args = Py_BuildValue("(y#)", msg, size); result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL); Py_DECREF(args); return result; } #else #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize #define PYARG_STR_UNI "et" #endif static PyObject *richcmp(int cmp_val, int op) { int ret; switch (op) { case Py_LT: ret = cmp_val < 0; break; case Py_LE: ret = cmp_val <= 0; break; case Py_EQ: ret = cmp_val == 0; break; case Py_NE: ret = cmp_val != 0; break; case Py_GT: ret = cmp_val > 0; break; case Py_GE: ret = cmp_val >= 0; break; default: Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } return PyBool_FromLong(ret); } static PyObject *py_ldb_control_str(PyLdbControlObject *self) { if (self->data != NULL) { char* control = ldb_control_to_string(self->mem_ctx, self->data); if (control == NULL) { PyErr_NoMemory(); return NULL; } return PyUnicode_FromString(control); } else { return PyUnicode_FromString("ldb control"); } } static void py_ldb_control_dealloc(PyLdbControlObject *self) { if (self->mem_ctx != NULL) { talloc_free(self->mem_ctx); } self->data = NULL; Py_TYPE(self)->tp_free(self); } /* Create a text (rather than bytes) interface for a LDB result object */ static PyObject *wrap_text(const char *type, PyObject *wrapped) { PyObject *mod, *cls, *constructor, *inst; mod = PyImport_ImportModule("_ldb_text"); if (mod == NULL) return NULL; cls = PyObject_GetAttrString(mod, type); Py_DECREF(mod); if (cls == NULL) { Py_DECREF(mod); return NULL; } constructor = PyObject_GetAttrString(cls, "_wrap"); Py_DECREF(cls); if (constructor == NULL) { return NULL; } inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped); Py_DECREF(constructor); return inst; } static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromString(self->data->oid); } static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(self->data->critical); } static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) { if (PyObject_IsTrue(value)) { self->data->critical = true; } else { self->data->critical = false; } return 0; } static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { char *data = NULL; const char * const kwnames[] = { "ldb", "data", NULL }; struct ldb_control *parsed_controls; PyLdbControlObject *ret; PyObject *py_ldb; TALLOC_CTX *mem_ctx; struct ldb_context *ldb_ctx; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s", discard_const_p(char *, kwnames), &PyLdb, &py_ldb, &data)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data); if (!parsed_controls) { talloc_free(mem_ctx); PyErr_SetString(PyExc_ValueError, "unable to parse control string"); return NULL; } ret = PyObject_New(PyLdbControlObject, type); if (ret == NULL) { PyErr_NoMemory(); talloc_free(mem_ctx); return NULL; } ret->mem_ctx = mem_ctx; ret->data = talloc_move(mem_ctx, &parsed_controls); if (ret->data == NULL) { Py_DECREF(ret); PyErr_NoMemory(); talloc_free(mem_ctx); return NULL; } return (PyObject *)ret; } static PyGetSetDef py_ldb_control_getset[] = { { .name = discard_const_p(char, "oid"), .get = (getter)py_ldb_control_get_oid, }, { .name = discard_const_p(char, "critical"), .get = (getter)py_ldb_control_get_critical, .set = (setter)py_ldb_control_set_critical, }, { .name = NULL }, }; static PyTypeObject PyLdbControl = { .tp_name = "ldb.control", .tp_dealloc = (destructor)py_ldb_control_dealloc, .tp_getattro = PyObject_GenericGetAttr, .tp_basicsize = sizeof(PyLdbControlObject), .tp_getset = py_ldb_control_getset, .tp_doc = "LDB control.", .tp_str = (reprfunc)py_ldb_control_str, .tp_new = py_ldb_control_new, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, }; static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) { if (ret == LDB_ERR_PYTHON_EXCEPTION) return; /* Python exception should already be set, just keep that */ PyErr_SetObject(error, Py_BuildValue(discard_const_p(char, "(i,s)"), ret, ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); } static PyObject *py_ldb_bytes_str(PyBytesObject *self) { char *msg = NULL; Py_ssize_t size; int result = 0; if (!PyBytes_Check(self)) { PyErr_Format(PyExc_TypeError,"Unexpected type"); return NULL; } result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size); if (result != 0) { PyErr_Format(PyExc_TypeError, "Failed to extract bytes"); return NULL; } return PyUnicode_FromStringAndSize(msg, size); } static PyTypeObject PyLdbBytesType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "ldb.bytes", .tp_doc = "str/bytes (with custom str)", .tp_str = (reprfunc)py_ldb_bytes_str, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, }; static PyObject *PyObject_FromLdbValue(const struct ldb_val *val) { return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length); } static PyObject *PyStr_FromLdbValue(const struct ldb_val *val) { return PyUnicode_FromStringAndSize((const char *)val->data, val->length); } /** * Create a Python object from a ldb_result. * * @param result LDB result to convert * @return Python object with converted result (a list object) */ static PyObject *PyLdbControl_FromControl(struct ldb_control *control) { TALLOC_CTX *ctl_ctx = talloc_new(NULL); PyLdbControlObject *ctrl; if (ctl_ctx == NULL) { PyErr_NoMemory(); return NULL; } ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0); if (ctrl == NULL) { talloc_free(ctl_ctx); PyErr_NoMemory(); return NULL; } ctrl->mem_ctx = ctl_ctx; ctrl->data = talloc_steal(ctrl->mem_ctx, control); if (ctrl->data == NULL) { Py_DECREF(ctrl); PyErr_NoMemory(); return NULL; } return (PyObject*) ctrl; } /** * Create a Python object from a ldb_result. * * @param result LDB result to convert * @return Python object with converted result (a list object) */ static PyObject *PyLdbResult_FromResult(struct ldb_result *result) { PyLdbResultObject *ret; PyObject *list, *controls, *referals; Py_ssize_t i; if (result == NULL) { Py_RETURN_NONE; } ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0); if (ret == NULL) { PyErr_NoMemory(); return NULL; } list = PyList_New(result->count); if (list == NULL) { PyErr_NoMemory(); Py_DECREF(ret); return NULL; } for (i = 0; i < result->count; i++) { PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i])); } ret->mem_ctx = talloc_new(NULL); if (ret->mem_ctx == NULL) { Py_DECREF(list); Py_DECREF(ret); PyErr_NoMemory(); return NULL; } ret->msgs = list; if (result->controls) { i = 0; while (result->controls[i]) { i++; } controls = PyList_New(i); if (controls == NULL) { Py_DECREF(ret); PyErr_NoMemory(); return NULL; } for (i=0; result->controls[i]; i++) { PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]); if (ctrl == NULL) { Py_DECREF(ret); Py_DECREF(controls); PyErr_NoMemory(); return NULL; } PyList_SetItem(controls, i, ctrl); } } else { /* * No controls so we keep an empty list */ controls = PyList_New(0); if (controls == NULL) { Py_DECREF(ret); PyErr_NoMemory(); return NULL; } } ret->controls = controls; i = 0; while (result->refs && result->refs[i]) { i++; } referals = PyList_New(i); if (referals == NULL) { Py_DECREF(ret); PyErr_NoMemory(); return NULL; } for (i = 0;result->refs && result->refs[i]; i++) { PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i])); } ret->referals = referals; return (PyObject *)ret; } /** * Create a LDB Result from a Python object. * If conversion fails, NULL will be returned and a Python exception set. * * Note: the result object only includes the messages at the moment; extended * result, controls and referrals are ignored. * * @param mem_ctx Memory context in which to allocate the LDB Result * @param obj Python object to convert * @return a ldb_result, or NULL if the conversion failed */ static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, PyObject *obj) { struct ldb_result *res; Py_ssize_t i; if (obj == Py_None) return NULL; res = talloc_zero(mem_ctx, struct ldb_result); res->count = PyList_Size(obj); res->msgs = talloc_array(res, struct ldb_message *, res->count); for (i = 0; i < res->count; i++) { PyObject *item = PyList_GetItem(obj, i); res->msgs[i] = pyldb_Message_AsMessage(item); } return res; } static PyObject *py_ldb_dn_validate(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(ldb_dn_validate(self->dn)); } static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(ldb_dn_is_valid(self->dn)); } static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(ldb_dn_is_special(self->dn)); } static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(ldb_dn_is_null(self->dn)); } static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromString(ldb_dn_get_casefold(self->dn)); } static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self) { return PyUnicode_FromString(ldb_dn_get_linearized(self->dn)); } static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromString(ldb_dn_canonical_string(self->dn, self->dn)); } static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn)); } static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs) { const char * const kwnames[] = { "mode", NULL }; int mode = 1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", discard_const_p(char *, kwnames), &mode)) return NULL; return PyUnicode_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode)); } static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args) { char *name; const struct ldb_val *val; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; val = ldb_dn_get_extended_component(self->dn, name); if (val == NULL) { Py_RETURN_NONE; } return PyBytes_FromStringAndSize((const char *)val->data, val->length); } static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args) { char *name; int err; uint8_t *value = NULL; Py_ssize_t size = 0; if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size)) return NULL; if (value == NULL) { err = ldb_dn_set_extended_component(self->dn, name, NULL); } else { struct ldb_val val; val.data = (uint8_t *)value; val.length = size; err = ldb_dn_set_extended_component(self->dn, name, &val); } if (err != LDB_SUCCESS) { PyErr_SetString(PyExc_TypeError, "Failed to set extended component"); return NULL; } Py_RETURN_NONE; } static PyObject *py_ldb_dn_repr(PyLdbDnObject *self) { PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn)); PyObject *repr, *result; if (str == NULL) return NULL; repr = PyObject_Repr(str); if (repr == NULL) { Py_DECREF(str); return NULL; } result = PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr)); Py_DECREF(str); Py_DECREF(repr); return result; } static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args) { char *name; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; return PyBool_FromLong(ldb_dn_check_special(self->dn, name)); } static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op) { int ret; if (!pyldb_Dn_Check(dn2)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2)); return richcmp(ret, op); } static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self); struct ldb_dn *parent; PyLdbDnObject *py_ret; TALLOC_CTX *mem_ctx = talloc_new(NULL); parent = ldb_dn_get_parent(mem_ctx, dn); if (parent == NULL) { talloc_free(mem_ctx); Py_RETURN_NONE; } py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); if (py_ret == NULL) { PyErr_NoMemory(); talloc_free(mem_ctx); return NULL; } py_ret->mem_ctx = mem_ctx; py_ret->dn = parent; return (PyObject *)py_ret; } static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args) { PyObject *py_other; struct ldb_dn *dn, *other; if (!PyArg_ParseTuple(args, "O", &py_other)) return NULL; dn = pyldb_Dn_AsDn((PyObject *)self); if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other)) return NULL; return PyBool_FromLong(ldb_dn_add_child(dn, other)); } static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args) { PyObject *py_other; struct ldb_dn *other, *dn; if (!PyArg_ParseTuple(args, "O", &py_other)) return NULL; dn = pyldb_Dn_AsDn((PyObject *)self); if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other)) return NULL; return PyBool_FromLong(ldb_dn_add_base(dn, other)); } static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args) { struct ldb_dn *dn; int i; if (!PyArg_ParseTuple(args, "i", &i)) return NULL; dn = pyldb_Dn_AsDn((PyObject *)self); return PyBool_FromLong(ldb_dn_remove_base_components(dn, i)); } static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args) { PyObject *py_base; struct ldb_dn *dn, *base; if (!PyArg_ParseTuple(args, "O", &py_base)) return NULL; dn = pyldb_Dn_AsDn((PyObject *)self); if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base)) return NULL; return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0); } static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args) { struct ldb_dn *dn; const char *name; unsigned int num = 0; if (!PyArg_ParseTuple(args, "I", &num)) return NULL; dn = pyldb_Dn_AsDn((PyObject *)self); name = ldb_dn_get_component_name(dn, num); if (name == NULL) { Py_RETURN_NONE; } return PyUnicode_FromString(name); } static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args) { struct ldb_dn *dn; const struct ldb_val *val; unsigned int num = 0; if (!PyArg_ParseTuple(args, "I", &num)) return NULL; dn = pyldb_Dn_AsDn((PyObject *)self); val = ldb_dn_get_component_val(dn, num); if (val == NULL) { Py_RETURN_NONE; } return PyStr_FromLdbValue(val); } static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args) { unsigned int num = 0; char *name = NULL, *value = NULL; struct ldb_val val = { NULL, }; int err; Py_ssize_t size = 0; if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size)) return NULL; val.data = (unsigned char*) value; val.length = size; err = ldb_dn_set_component(self->dn, num, name, val); if (err != LDB_SUCCESS) { PyErr_SetString(PyExc_TypeError, "Failed to set component"); return NULL; } Py_RETURN_NONE; } static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_dn *dn; const char *name; dn = pyldb_Dn_AsDn((PyObject *)self); name = ldb_dn_get_rdn_name(dn); if (name == NULL) { Py_RETURN_NONE; } return PyUnicode_FromString(name); } static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_dn *dn; const struct ldb_val *val; dn = pyldb_Dn_AsDn((PyObject *)self); val = ldb_dn_get_rdn_val(dn); if (val == NULL) { Py_RETURN_NONE; } return PyStr_FromLdbValue(val); } static PyMethodDef py_ldb_dn_methods[] = { { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, "S.validate() -> bool\n" "Validate DN is correct." }, { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS, "S.is_valid() -> bool\n" }, { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS, "S.is_special() -> bool\n" "Check whether this is a special LDB DN." }, { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS, "Check whether this is a null DN." }, { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS, NULL }, { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_dn_get_linearized), METH_NOARGS, NULL }, { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS, "S.canonical_str() -> string\n" "Canonical version of this DN (like a posix path)." }, { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS, "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"}, { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS, "S.canonical_ex_str() -> string\n" "Canonical version of this DN (like a posix path, with terminating newline)." }, { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_dn_extended_str), METH_VARARGS | METH_KEYWORDS, "S.extended_str(mode=1) -> string\n" "Extended version of this DN" }, { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, "S.parent() -> dn\n" "Get the parent for this DN." }, { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, "S.add_child(dn) -> None\n" "Add a child DN to this DN." }, { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS, "S.add_base(dn) -> None\n" "Add a base DN to this DN." }, { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS, "S.remove_base_components(int) -> bool\n" "Remove a number of DN components from the base of this DN." }, { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS, "S.check_special(name) -> bool\n\n" "Check if name is a special DN name"}, { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS, "S.get_extended_component(name) -> string\n\n" "returns a DN extended component as a binary string"}, { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS, "S.set_extended_component(name, value) -> None\n\n" "set a DN extended component as a binary string"}, { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS, "S.get_component_name(num) -> string\n" "get the attribute name of the specified component" }, { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS, "S.get_component_value(num) -> string\n" "get the attribute value of the specified component as a binary string" }, { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS, "S.get_component_value(num, name, value) -> None\n" "set the attribute name and value of the specified component" }, { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS, "S.get_rdn_name() -> string\n" "get the RDN attribute name" }, { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS, "S.get_rdn_value() -> string\n" "get the RDN attribute value as a binary string" }, { NULL } }; static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self) { return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self)); } /* copy a DN as a python object */ static PyObject *py_ldb_dn_copy(struct ldb_dn *dn) { PyLdbDnObject *py_ret; py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); if (py_ret == NULL) { PyErr_NoMemory(); return NULL; } py_ret->mem_ctx = talloc_new(NULL); py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); return (PyObject *)py_ret; } static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other) { struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self), *other; PyLdbDnObject *py_ret; if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other)) return NULL; py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); if (py_ret == NULL) { PyErr_NoMemory(); return NULL; } py_ret->mem_ctx = talloc_new(NULL); py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); ldb_dn_add_base(py_ret->dn, other); return (PyObject *)py_ret; } static PySequenceMethods py_ldb_dn_seq = { .sq_length = (lenfunc)py_ldb_dn_len, .sq_concat = (binaryfunc)py_ldb_dn_concat, }; static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { struct ldb_dn *ret = NULL; char *str = NULL; PyObject *py_ldb = NULL; struct ldb_context *ldb_ctx = NULL; TALLOC_CTX *mem_ctx = NULL; PyLdbDnObject *py_ret = NULL; const char * const kwnames[] = { "ldb", "dn", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI, discard_const_p(char *, kwnames), &py_ldb, "utf8", &str)) goto out; if (!PyLdb_Check(py_ldb)) { PyErr_SetString(PyExc_TypeError, "Expected Ldb"); goto out; } ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); goto out; } ret = ldb_dn_new(mem_ctx, ldb_ctx, str); if (!ldb_dn_validate(ret)) { talloc_free(mem_ctx); PyErr_SetString(PyExc_ValueError, "unable to parse dn string"); goto out; } py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0); if (py_ret == NULL) { talloc_free(mem_ctx); PyErr_NoMemory(); goto out; } py_ret->mem_ctx = mem_ctx; py_ret->dn = ret; out: if (str != NULL) { PyMem_Free(discard_const_p(char, str)); } return (PyObject *)py_ret; } static void py_ldb_dn_dealloc(PyLdbDnObject *self) { talloc_free(self->mem_ctx); PyObject_Del(self); } static PyTypeObject PyLdbDn = { .tp_name = "ldb.Dn", .tp_methods = py_ldb_dn_methods, .tp_str = (reprfunc)py_ldb_dn_get_linearized, .tp_repr = (reprfunc)py_ldb_dn_repr, .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp, .tp_as_sequence = &py_ldb_dn_seq, .tp_doc = "A LDB distinguished name.", .tp_new = py_ldb_dn_new, .tp_dealloc = (destructor)py_ldb_dn_dealloc, .tp_basicsize = sizeof(PyLdbDnObject), .tp_flags = Py_TPFLAGS_DEFAULT, }; /* Debug */ static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) { PyObject *fn = (PyObject *)context; PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyUnicode_FromFormatV(fmt, ap)); } static PyObject *py_ldb_debug_func; static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args) { PyObject *cb; struct ldb_context *ldb_ctx; if (!PyArg_ParseTuple(args, "O", &cb)) return NULL; if (py_ldb_debug_func != NULL) { Py_DECREF(py_ldb_debug_func); } Py_INCREF(cb); /* FIXME: DECREF cb when exiting program */ py_ldb_debug_func = cb; ldb_ctx = pyldb_Ldb_AsLdbContext(self); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(ldb_ctx, py_ldb_debug, cb), ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args) { unsigned int perms; if (!PyArg_ParseTuple(args, "I", &perms)) return NULL; ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms); Py_RETURN_NONE; } static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args) { char *modules_dir; if (!PyArg_ParseTuple(args, "s", &modules_dir)) return NULL; ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir); Py_RETURN_NONE; } static PyObject *py_ldb_transaction_start(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); int ldb_err; ldb_err = ldb_transaction_start(ldb_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_transaction_commit(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); int ldb_err; ldb_err = ldb_transaction_commit(ldb_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); int ldb_err; ldb_err = ldb_transaction_prepare_commit(ldb_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_transaction_cancel(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); int ldb_err; ldb_err = ldb_transaction_cancel(ldb_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); int ldb_err; ldb_err = ldb_setup_wellknown_attributes(ldb_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_repr(PyLdbObject *self) { return PyUnicode_FromString(""); } static PyObject *py_ldb_get_root_basedn(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self)); if (dn == NULL) Py_RETURN_NONE; return py_ldb_dn_copy(dn); } static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self)); if (dn == NULL) Py_RETURN_NONE; return py_ldb_dn_copy(dn); } static PyObject *py_ldb_get_config_basedn(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self)); if (dn == NULL) Py_RETURN_NONE; return py_ldb_dn_copy(dn); } static PyObject *py_ldb_get_default_basedn(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self)); if (dn == NULL) Py_RETURN_NONE; return py_ldb_dn_copy(dn); } static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list, const char *paramname) { const char **ret; Py_ssize_t i; if (!PyList_Check(list)) { PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); return NULL; } ret = talloc_array(NULL, const char *, PyList_Size(list)+1); if (ret == NULL) { PyErr_NoMemory(); return NULL; } for (i = 0; i < PyList_Size(list); i++) { const char *str = NULL; Py_ssize_t size; PyObject *item = PyList_GetItem(list, i); if (!PyUnicode_Check(item)) { PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); talloc_free(ret); return NULL; } str = PyUnicode_AsUTF8AndSize(item, &size); if (str == NULL) { talloc_free(ret); return NULL; } ret[i] = talloc_strndup(ret, str, size); } ret[i] = NULL; return ret; } static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs) { const char * const kwnames[] = { "url", "flags", "options", NULL }; char *url = NULL; PyObject *py_options = Py_None; const char **options; unsigned int flags = 0; int ret; struct ldb_context *ldb; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__", discard_const_p(char *, kwnames), &url, &flags, &py_options)) return -1; ldb = pyldb_Ldb_AsLdbContext(self); if (py_options == Py_None) { options = NULL; } else { options = PyList_AsStrList(ldb, py_options, "options"); if (options == NULL) return -1; } if (url != NULL) { ret = ldb_connect(ldb, url, flags, options); if (ret != LDB_SUCCESS) { PyErr_SetLdbError(PyExc_LdbError, ret, ldb); return -1; } } else { ldb_set_flags(ldb, flags); } talloc_free(options); return 0; } static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyLdbObject *ret; struct ldb_context *ldb; ret = (PyLdbObject *)type->tp_alloc(type, 0); if (ret == NULL) { PyErr_NoMemory(); return NULL; } ret->mem_ctx = talloc_new(NULL); ldb = ldb_init(ret->mem_ctx, NULL); if (ldb == NULL) { PyErr_NoMemory(); return NULL; } ret->ldb_ctx = ldb; return (PyObject *)ret; } static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs) { char *url = NULL; unsigned int flags = 0; PyObject *py_options = Py_None; int ret; const char **options; const char * const kwnames[] = { "url", "flags", "options", NULL }; struct ldb_context *ldb_ctx; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO", discard_const_p(char *, kwnames), &url, &flags, &py_options)) return NULL; if (py_options == Py_None) { options = NULL; } else { options = PyList_AsStrList(NULL, py_options, "options"); if (options == NULL) return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(self); ret = ldb_connect(ldb_ctx, url, flags, options); talloc_free(options); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_msg; PyObject *py_controls = Py_None; struct ldb_context *ldb_ctx; struct ldb_request *req; struct ldb_control **parsed_controls; struct ldb_message *msg; int ret; TALLOC_CTX *mem_ctx; bool validate=true; const char * const kwnames[] = { "message", "controls", "validate", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob", discard_const_p(char *, kwnames), &py_msg, &py_controls, &validate)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(self); if (py_controls == Py_None) { parsed_controls = NULL; } else { const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); if (controls == NULL) { talloc_free(mem_ctx); return NULL; } parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); talloc_free(controls); } if (!PyLdbMessage_Check(py_msg)) { PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); talloc_free(mem_ctx); return NULL; } msg = pyldb_Message_AsMessage(py_msg); if (validate) { ret = ldb_msg_sanity_check(ldb_ctx, msg); if (ret != LDB_SUCCESS) { PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); talloc_free(mem_ctx); return NULL; } } ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) { PyErr_SetString(PyExc_TypeError, "failed to build request"); talloc_free(mem_ctx); return NULL; } /* do request and autostart a transaction */ /* Then let's LDB handle the message error in case of pb as they are meaningful */ ret = ldb_transaction_start(ldb_ctx); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } ret = ldb_request(ldb_ctx, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret == LDB_SUCCESS) { ret = ldb_transaction_commit(ldb_ctx); } else { ldb_transaction_cancel(ldb_ctx); } talloc_free(mem_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); Py_RETURN_NONE; } /** * Obtain a ldb message from a Python Dictionary object. * * @param mem_ctx Memory context * @param py_obj Python Dictionary object * @param ldb_ctx LDB context * @param mod_flags Flags to be set on every message element * @return ldb_message on success or NULL on failure */ static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx, PyObject *py_obj, struct ldb_context *ldb_ctx, unsigned int mod_flags) { struct ldb_message *msg; unsigned int msg_pos = 0; Py_ssize_t dict_pos = 0; PyObject *key, *value; struct ldb_message_element *msg_el; PyObject *dn_value = PyDict_GetItemString(py_obj, "dn"); msg = ldb_msg_new(mem_ctx); if (msg == NULL) { PyErr_NoMemory(); return NULL; } msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj)); if (dn_value) { if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { PyErr_SetString(PyExc_TypeError, "unable to import dn object"); return NULL; } if (msg->dn == NULL) { PyErr_SetString(PyExc_TypeError, "dn set but not found"); return NULL; } } else { PyErr_SetString(PyExc_TypeError, "no dn set"); return NULL; } while (PyDict_Next(py_obj, &dict_pos, &key, &value)) { const char *key_str = PyUnicode_AsUTF8(key); if (ldb_attr_cmp(key_str, "dn") != 0) { msg_el = PyObject_AsMessageElement(msg->elements, value, mod_flags, key_str); if (msg_el == NULL) { PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str); return NULL; } memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el)); msg_pos++; } } msg->num_elements = msg_pos; return msg; } static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_obj; int ret; struct ldb_context *ldb_ctx; struct ldb_request *req; struct ldb_message *msg = NULL; PyObject *py_controls = Py_None; TALLOC_CTX *mem_ctx; struct ldb_control **parsed_controls; const char * const kwnames[] = { "message", "controls", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", discard_const_p(char *, kwnames), &py_obj, &py_controls)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(self); if (py_controls == Py_None) { parsed_controls = NULL; } else { const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); if (controls == NULL) { talloc_free(mem_ctx); return NULL; } parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); talloc_free(controls); } if (PyLdbMessage_Check(py_obj)) { msg = pyldb_Message_AsMessage(py_obj); } else if (PyDict_Check(py_obj)) { msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD); } else { PyErr_SetString(PyExc_TypeError, "Dictionary or LdbMessage object expected!"); } if (!msg) { /* we should have a PyErr already set */ talloc_free(mem_ctx); return NULL; } ret = ldb_msg_sanity_check(ldb_ctx, msg); if (ret != LDB_SUCCESS) { PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); talloc_free(mem_ctx); return NULL; } ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) { PyErr_SetString(PyExc_TypeError, "failed to build request"); talloc_free(mem_ctx); return NULL; } /* do request and autostart a transaction */ /* Then let's LDB handle the message error in case of pb as they are meaningful */ ret = ldb_transaction_start(ldb_ctx); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } ret = ldb_request(ldb_ctx, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret == LDB_SUCCESS) { ret = ldb_transaction_commit(ldb_ctx); } else { ldb_transaction_cancel(ldb_ctx); } talloc_free(mem_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_dn; struct ldb_dn *dn; int ret; struct ldb_context *ldb_ctx; struct ldb_request *req; PyObject *py_controls = Py_None; TALLOC_CTX *mem_ctx; struct ldb_control **parsed_controls; const char * const kwnames[] = { "dn", "controls", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", discard_const_p(char *, kwnames), &py_dn, &py_controls)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(self); if (py_controls == Py_None) { parsed_controls = NULL; } else { const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); if (controls == NULL) { talloc_free(mem_ctx); return NULL; } parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); talloc_free(controls); } if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) { talloc_free(mem_ctx); return NULL; } ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) { PyErr_SetString(PyExc_TypeError, "failed to build request"); talloc_free(mem_ctx); return NULL; } /* do request and autostart a transaction */ /* Then let's LDB handle the message error in case of pb as they are meaningful */ ret = ldb_transaction_start(ldb_ctx); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } ret = ldb_request(ldb_ctx, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret == LDB_SUCCESS) { ret = ldb_transaction_commit(ldb_ctx); } else { ldb_transaction_cancel(ldb_ctx); } talloc_free(mem_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_dn1, *py_dn2; struct ldb_dn *dn1, *dn2; int ret; TALLOC_CTX *mem_ctx; PyObject *py_controls = Py_None; struct ldb_control **parsed_controls; struct ldb_context *ldb_ctx; struct ldb_request *req; const char * const kwnames[] = { "dn1", "dn2", "controls", NULL }; ldb_ctx = pyldb_Ldb_AsLdbContext(self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", discard_const_p(char *, kwnames), &py_dn1, &py_dn2, &py_controls)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } if (py_controls == Py_None) { parsed_controls = NULL; } else { const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); if (controls == NULL) { talloc_free(mem_ctx); return NULL; } parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); talloc_free(controls); } if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) { talloc_free(mem_ctx); return NULL; } if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) { talloc_free(mem_ctx); return NULL; } ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) { PyErr_SetString(PyExc_TypeError, "failed to build request"); talloc_free(mem_ctx); return NULL; } /* do request and autostart a transaction */ /* Then let's LDB handle the message error in case of pb as they are meaningful */ ret = ldb_transaction_start(ldb_ctx); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } ret = ldb_request(ldb_ctx, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret == LDB_SUCCESS) { ret = ldb_transaction_commit(ldb_ctx); } else { ldb_transaction_cancel(ldb_ctx); } talloc_free(mem_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); Py_RETURN_NONE; } static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args) { char *name; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name); Py_RETURN_NONE; } static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args) { char *attribute, *syntax; unsigned int flags; int ret; struct ldb_context *ldb_ctx; if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax)) return NULL; ldb_ctx = pyldb_Ldb_AsLdbContext(self); ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); Py_RETURN_NONE; } static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif) { if (ldif == NULL) { Py_RETURN_NONE; } else { /* We don't want this attached to the 'ldb' any more */ PyObject *obj = PyLdbMessage_FromMessage(ldif->msg); PyObject *result = Py_BuildValue(discard_const_p(char, "(iO)"), ldif->changetype, obj); Py_CLEAR(obj); return result; } } static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args) { int changetype; PyObject *py_msg; struct ldb_ldif ldif; PyObject *ret; char *string; TALLOC_CTX *mem_ctx; if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype)) return NULL; if (!PyLdbMessage_Check(py_msg)) { PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg"); return NULL; } ldif.msg = pyldb_Message_AsMessage(py_msg); ldif.changetype = changetype; mem_ctx = talloc_new(NULL); string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif); if (!string) { PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF"); return NULL; } ret = PyUnicode_FromString(string); talloc_free(mem_ctx); return ret; } static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args) { PyObject *list, *ret; struct ldb_ldif *ldif; const char *s; struct ldb_dn *last_dn = NULL; TALLOC_CTX *mem_ctx; if (!PyArg_ParseTuple(args, "s", &s)) return NULL; mem_ctx = talloc_new(NULL); if (!mem_ctx) { Py_RETURN_NONE; } list = PyList_New(0); while (s && *s != '\0') { ldif = ldb_ldif_read_string(self->ldb_ctx, &s); talloc_steal(mem_ctx, ldif); if (ldif) { int res = 0; PyObject *py_ldif = ldb_ldif_to_pyobject(ldif); if (py_ldif == NULL) { Py_CLEAR(list); PyErr_BadArgument(); talloc_free(mem_ctx); return NULL; } res = PyList_Append(list, py_ldif); Py_CLEAR(py_ldif); if (res == -1) { Py_CLEAR(list); talloc_free(mem_ctx); return NULL; } last_dn = ldif->msg->dn; } else { const char *last_dn_str = NULL; const char *err_string = NULL; if (last_dn == NULL) { PyErr_SetString(PyExc_ValueError, "unable to parse LDIF " "string at first chunk"); Py_CLEAR(list); talloc_free(mem_ctx); return NULL; } last_dn_str = ldb_dn_get_linearized(last_dn); err_string = talloc_asprintf(mem_ctx, "unable to parse ldif " "string AFTER %s", last_dn_str); PyErr_SetString(PyExc_ValueError, err_string); talloc_free(mem_ctx); Py_CLEAR(list); return NULL; } } talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */ ret = PyObject_GetIter(list); Py_DECREF(list); return ret; } static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) { int ldb_ret; PyObject *py_msg_old; PyObject *py_msg_new; struct ldb_message *diff; struct ldb_context *ldb; PyObject *py_ret; if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new)) return NULL; if (!PyLdbMessage_Check(py_msg_old)) { PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message"); return NULL; } if (!PyLdbMessage_Check(py_msg_new)) { PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message"); return NULL; } ldb = pyldb_Ldb_AsLdbContext(self); ldb_ret = ldb_msg_difference(ldb, ldb, pyldb_Message_AsMessage(py_msg_old), pyldb_Message_AsMessage(py_msg_new), &diff); if (ldb_ret != LDB_SUCCESS) { PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); return NULL; } py_ret = PyLdbMessage_FromMessage(diff); talloc_unlink(ldb, diff); return py_ret; } static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args) { const struct ldb_schema_attribute *a; struct ldb_val old_val; struct ldb_val new_val; TALLOC_CTX *mem_ctx; PyObject *ret; char *element_name; PyObject *val; Py_ssize_t size; int result; if (!PyArg_ParseTuple(args, "sO", &element_name, &val)) return NULL; result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size); old_val.length = size; if (result != 0) { PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String"); return NULL; } a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name); if (a == NULL) { Py_RETURN_NONE; } mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) { talloc_free(mem_ctx); Py_RETURN_NONE; } ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length); talloc_free(mem_ctx); return ret; } static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_base = Py_None; int scope = LDB_SCOPE_DEFAULT; char *expr = NULL; PyObject *py_attrs = Py_None; PyObject *py_controls = Py_None; const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL }; int ret; struct ldb_result *res; struct ldb_request *req; const char **attrs; struct ldb_context *ldb_ctx; struct ldb_control **parsed_controls; struct ldb_dn *base; PyObject *py_ret; TALLOC_CTX *mem_ctx; /* type "int" rather than "enum" for "scope" is intentional */ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO", discard_const_p(char *, kwnames), &py_base, &scope, &expr, &py_attrs, &py_controls)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(self); if (py_attrs == Py_None) { attrs = NULL; } else { attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs"); if (attrs == NULL) { talloc_free(mem_ctx); return NULL; } } if (py_base == Py_None) { base = ldb_get_default_basedn(ldb_ctx); } else { if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) { talloc_free(mem_ctx); return NULL; } } if (py_controls == Py_None) { parsed_controls = NULL; } else { const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); if (controls == NULL) { talloc_free(mem_ctx); return NULL; } parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); talloc_free(controls); } res = talloc_zero(mem_ctx, struct ldb_result); if (res == NULL) { PyErr_NoMemory(); talloc_free(mem_ctx); return NULL; } ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx, base, scope, expr, attrs, parsed_controls, res, ldb_search_default_callback, NULL); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } talloc_steal(req, attrs); ret = ldb_request(ldb_ctx, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } py_ret = PyLdbResult_FromResult(res); talloc_free(mem_ctx); return py_ret; } static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply) { if (reply->py_iter != NULL) { DLIST_REMOVE(reply->py_iter->state.next, reply); if (reply->py_iter->state.result == reply) { reply->py_iter->state.result = NULL; } reply->py_iter = NULL; } if (reply->obj != NULL) { Py_DECREF(reply->obj); reply->obj = NULL; } return 0; } static int py_ldb_search_iterator_callback(struct ldb_request *req, struct ldb_reply *ares) { PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context; struct ldb_result result = { .msgs = NULL }; struct py_ldb_search_iterator_reply *reply = NULL; if (ares == NULL) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { int ret = ares->error; TALLOC_FREE(ares); return ldb_request_done(req, ret); } reply = talloc_zero(py_iter->mem_ctx, struct py_ldb_search_iterator_reply); if (reply == NULL) { TALLOC_FREE(ares); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } reply->py_iter = py_iter; talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor); switch (ares->type) { case LDB_REPLY_ENTRY: reply->obj = PyLdbMessage_FromMessage(ares->message); if (reply->obj == NULL) { TALLOC_FREE(ares); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } DLIST_ADD_END(py_iter->state.next, reply); TALLOC_FREE(ares); return LDB_SUCCESS; case LDB_REPLY_REFERRAL: reply->obj = PyUnicode_FromString(ares->referral); if (reply->obj == NULL) { TALLOC_FREE(ares); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } DLIST_ADD_END(py_iter->state.next, reply); TALLOC_FREE(ares); return LDB_SUCCESS; case LDB_REPLY_DONE: result = (struct ldb_result) { .controls = ares->controls }; reply->obj = PyLdbResult_FromResult(&result); if (reply->obj == NULL) { TALLOC_FREE(ares); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } py_iter->state.result = reply; TALLOC_FREE(ares); return ldb_request_done(req, LDB_SUCCESS); } TALLOC_FREE(ares); return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_base = Py_None; int scope = LDB_SCOPE_DEFAULT; int timeout = 0; char *expr = NULL; PyObject *py_attrs = Py_None; PyObject *py_controls = Py_None; const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL }; int ret; const char **attrs; struct ldb_context *ldb_ctx; struct ldb_control **parsed_controls; struct ldb_dn *base; PyLdbSearchIteratorObject *py_iter; /* type "int" rather than "enum" for "scope" is intentional */ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi", discard_const_p(char *, kwnames), &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout)) return NULL; py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0); if (py_iter == NULL) { PyErr_NoMemory(); return NULL; } py_iter->ldb = self; Py_INCREF(self); ZERO_STRUCT(py_iter->state); py_iter->mem_ctx = talloc_new(NULL); if (py_iter->mem_ctx == NULL) { Py_DECREF(py_iter); PyErr_NoMemory(); return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(self); if (py_attrs == Py_None) { attrs = NULL; } else { attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs"); if (attrs == NULL) { Py_DECREF(py_iter); PyErr_NoMemory(); return NULL; } } if (py_base == Py_None) { base = ldb_get_default_basedn(ldb_ctx); } else { if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) { Py_DECREF(py_iter); PyErr_NoMemory(); return NULL; } } if (py_controls == Py_None) { parsed_controls = NULL; } else { const char **controls = NULL; controls = PyList_AsStrList(py_iter->mem_ctx, py_controls, "controls"); if (controls == NULL) { Py_DECREF(py_iter); PyErr_NoMemory(); return NULL; } parsed_controls = ldb_parse_control_strings(ldb_ctx, py_iter->mem_ctx, controls); if (controls[0] != NULL && parsed_controls == NULL) { Py_DECREF(py_iter); PyErr_NoMemory(); return NULL; } talloc_free(controls); } ret = ldb_build_search_req(&py_iter->state.req, ldb_ctx, py_iter->mem_ctx, base, scope, expr, attrs, parsed_controls, py_iter, py_ldb_search_iterator_callback, NULL); if (ret != LDB_SUCCESS) { Py_DECREF(py_iter); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout); ret = ldb_request(ldb_ctx, py_iter->state.req); if (ret != LDB_SUCCESS) { Py_DECREF(py_iter); PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return NULL; } return (PyObject *)py_iter; } static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args) { char *name; void *data; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name); if (data == NULL) Py_RETURN_NONE; /* FIXME: More interpretation */ Py_RETURN_TRUE; } static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args) { char *name; PyObject *data; if (!PyArg_ParseTuple(args, "sO", &name, &data)) return NULL; /* FIXME: More interpretation */ ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data); Py_RETURN_NONE; } static PyObject *py_ldb_modules(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); PyObject *ret = PyList_New(0); struct ldb_module *mod; if (ret == NULL) { return PyErr_NoMemory(); } for (mod = ldb->modules; mod; mod = mod->next) { PyObject *item = PyLdbModule_FromModule(mod); int res = 0; if (item == NULL) { PyErr_SetString(PyExc_RuntimeError, "Failed to load LdbModule"); Py_CLEAR(ret); return NULL; } res = PyList_Append(ret, item); Py_CLEAR(item); if (res == -1) { Py_CLEAR(ret); return NULL; } } return ret; } static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args) { struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); int type, ret; uint64_t value; if (!PyArg_ParseTuple(args, "i", &type)) return NULL; /* FIXME: More interpretation */ ret = ldb_sequence_number(ldb, type, &value); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); return PyLong_FromLongLong(value); } static const struct ldb_dn_extended_syntax test_dn_syntax = { .name = "TEST", .read_fn = ldb_handler_copy, .write_clear_fn = ldb_handler_copy, .write_hex_fn = ldb_handler_copy, }; static PyObject *py_ldb_register_test_extensions(PyLdbObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); int ret; ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); Py_RETURN_NONE; } static PyMethodDef py_ldb_methods[] = { { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, "S.set_debug(callback) -> None\n" "Set callback for LDB debug messages.\n" "The callback should accept a debug level and debug text." }, { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, "S.set_create_perms(mode) -> None\n" "Set mode to use when creating new LDB files." }, { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS, "S.set_modules_dir(path) -> None\n" "Set path LDB should search for modules" }, { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, "S.transaction_start() -> None\n" "Start a new transaction." }, { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS, "S.transaction_prepare_commit() -> None\n" "prepare to commit a new transaction (2-stage commit)." }, { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, "S.transaction_commit() -> None\n" "commit a new transaction." }, { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, "S.transaction_cancel() -> None\n" "cancel a new transaction." }, { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, NULL }, { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS, NULL }, { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS, NULL }, { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS, NULL }, { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS, NULL }, { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect), METH_VARARGS|METH_KEYWORDS, "S.connect(url, flags=0, options=None) -> None\n" "Connect to a LDB URL." }, { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify), METH_VARARGS|METH_KEYWORDS, "S.modify(message, controls=None, validate=False) -> None\n" "Modify an entry." }, { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add), METH_VARARGS|METH_KEYWORDS, "S.add(message, controls=None) -> None\n" "Add an entry." }, { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete), METH_VARARGS|METH_KEYWORDS, "S.delete(dn, controls=None) -> None\n" "Remove an entry." }, { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename), METH_VARARGS|METH_KEYWORDS, "S.rename(old_dn, new_dn, controls=None) -> None\n" "Rename an entry." }, { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search), METH_VARARGS|METH_KEYWORDS, "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n" "Search in a database.\n" "\n" ":param base: Optional base DN to search\n" ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" ":param expression: Optional search expression\n" ":param attrs: Attributes to return (defaults to all)\n" ":param controls: Optional list of controls\n" ":return: ldb.Result object\n" }, { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search_iterator), METH_VARARGS|METH_KEYWORDS, "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n" "Search in a database.\n" "\n" ":param base: Optional base DN to search\n" ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" ":param expression: Optional search expression\n" ":param attrs: Attributes to return (defaults to all)\n" ":param controls: Optional list of controls\n" ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n" ":return: ldb.SearchIterator object that provides results when they arrive\n" }, { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS, NULL }, { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS, NULL }, { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS, NULL }, { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS, "S.parse_ldif(ldif) -> iter(messages)\n" "Parse a string formatted using LDIF." }, { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS, "S.write_ldif(message, changetype) -> ldif\n" "Print the message as a string formatted using LDIF." }, { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS, "S.msg_diff(Message) -> Message\n" "Return an LDB Message of the difference between two Message objects." }, { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS, "S.get_opaque(name) -> value\n" "Get an opaque value set on this LDB connection. \n" ":note: The returned value may not be useful in Python." }, { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS, "S.set_opaque(name, value) -> None\n" "Set an opaque value on this LDB connection. \n" ":note: Passing incorrect values may cause crashes." }, { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS, "S.modules() -> list\n" "Return the list of modules on this LDB connection " }, { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS, "S.sequence_number(type) -> value\n" "Return the value of the sequence according to the requested type" }, { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS, "S._register_test_extensions() -> None\n" "Register internal extensions used in testing" }, { NULL }, }; static PyObject *PyLdbModule_FromModule(struct ldb_module *mod) { PyLdbModuleObject *ret; ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0); if (ret == NULL) { PyErr_NoMemory(); return NULL; } ret->mem_ctx = talloc_new(NULL); ret->mod = talloc_reference(ret->mem_ctx, mod); return (PyObject *)ret; } static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure) { struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules; if (mod == NULL) { Py_RETURN_NONE; } return PyLdbModule_FromModule(mod); } static PyGetSetDef py_ldb_getset[] = { { .name = discard_const_p(char, "firstmodule"), .get = (getter)py_ldb_get_firstmodule, }, { .name = NULL }, }; static int py_ldb_contains(PyLdbObject *self, PyObject *obj) { struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); struct ldb_dn *dn; struct ldb_result *result; unsigned int count; int ret; if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) { return -1; } ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL); if (ret != LDB_SUCCESS) { PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); return -1; } count = result->count; talloc_free(result); if (count > 1) { PyErr_Format(PyExc_RuntimeError, "Searching for [%s] dn gave %u results!", ldb_dn_get_linearized(dn), count); return -1; } return count; } static PySequenceMethods py_ldb_seq = { .sq_contains = (objobjproc)py_ldb_contains, }; static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx) { PyLdbObject *ret; ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0); if (ret == NULL) { PyErr_NoMemory(); return NULL; } ret->mem_ctx = talloc_new(NULL); ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx); return (PyObject *)ret; } static void py_ldb_dealloc(PyLdbObject *self) { talloc_free(self->mem_ctx); Py_TYPE(self)->tp_free(self); } static PyTypeObject PyLdb = { .tp_name = "ldb.Ldb", .tp_methods = py_ldb_methods, .tp_repr = (reprfunc)py_ldb_repr, .tp_new = py_ldb_new, .tp_init = (initproc)py_ldb_init, .tp_dealloc = (destructor)py_ldb_dealloc, .tp_getset = py_ldb_getset, .tp_getattro = PyObject_GenericGetAttr, .tp_basicsize = sizeof(PyLdbObject), .tp_doc = "Connection to a LDB database.", .tp_as_sequence = &py_ldb_seq, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, }; static void py_ldb_result_dealloc(PyLdbResultObject *self) { talloc_free(self->mem_ctx); Py_DECREF(self->msgs); Py_DECREF(self->referals); Py_DECREF(self->controls); Py_TYPE(self)->tp_free(self); } static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure) { Py_INCREF(self->msgs); return self->msgs; } static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure) { Py_INCREF(self->controls); return self->controls; } static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure) { Py_INCREF(self->referals); return self->referals; } static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure) { Py_ssize_t size; if (self->msgs == NULL) { PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context"); return NULL; } size = PyList_Size(self->msgs); return PyInt_FromLong(size); } static PyGetSetDef py_ldb_result_getset[] = { { .name = discard_const_p(char, "controls"), .get = (getter)py_ldb_result_get_controls, }, { .name = discard_const_p(char, "msgs"), .get = (getter)py_ldb_result_get_msgs, }, { .name = discard_const_p(char, "referals"), .get = (getter)py_ldb_result_get_referals, }, { .name = discard_const_p(char, "count"), .get = (getter)py_ldb_result_get_count, }, { .name = NULL }, }; static PyObject *py_ldb_result_iter(PyLdbResultObject *self) { return PyObject_GetIter(self->msgs); } static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self) { return PySequence_Size(self->msgs); } static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx) { return PySequence_GetItem(self->msgs, idx); } static PySequenceMethods py_ldb_result_seq = { .sq_length = (lenfunc)py_ldb_result_len, .sq_item = (ssizeargfunc)py_ldb_result_find, }; static PyObject *py_ldb_result_repr(PyLdbObject *self) { return PyUnicode_FromString(""); } static PyTypeObject PyLdbResult = { .tp_name = "ldb.Result", .tp_repr = (reprfunc)py_ldb_result_repr, .tp_dealloc = (destructor)py_ldb_result_dealloc, .tp_iter = (getiterfunc)py_ldb_result_iter, .tp_getset = py_ldb_result_getset, .tp_getattro = PyObject_GenericGetAttr, .tp_basicsize = sizeof(PyLdbResultObject), .tp_as_sequence = &py_ldb_result_seq, .tp_doc = "LDB result.", .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, }; static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self) { Py_XDECREF(self->state.exception); TALLOC_FREE(self->mem_ctx); ZERO_STRUCT(self->state); Py_DECREF(self->ldb); Py_TYPE(self)->tp_free(self); } static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self) { PyObject *py_ret = NULL; if (self->state.req == NULL) { PyErr_SetString(PyExc_RuntimeError, "ldb.SearchIterator request already finished"); return NULL; } /* * TODO: do we want a non-blocking mode? * In future we may add an optional 'nonblocking' * argument to search_iterator(). * * For now we keep it simple and wait for at * least one reply. */ while (self->state.next == NULL) { int ret; if (self->state.result != NULL) { /* * We (already) got a final result from the server. * * We stop the iteration and let * py_ldb_search_iterator_result() will deliver * the result details. */ TALLOC_FREE(self->state.req); PyErr_SetNone(PyExc_StopIteration); return NULL; } ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE); if (ret != LDB_SUCCESS) { struct ldb_context *ldb_ctx; TALLOC_FREE(self->state.req); ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb); /* * We stop the iteration and let * py_ldb_search_iterator_result() will deliver * the exception. */ self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"), ret, ldb_errstring(ldb_ctx)); PyErr_SetNone(PyExc_StopIteration); return NULL; } } py_ret = self->state.next->obj; self->state.next->obj = NULL; /* no TALLOC_FREE() as self->state.next is a list */ talloc_free(self->state.next); return py_ret; } static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *py_ret = NULL; if (self->state.req != NULL) { PyErr_SetString(PyExc_RuntimeError, "ldb.SearchIterator request running"); return NULL; } if (self->state.next != NULL) { PyErr_SetString(PyExc_RuntimeError, "ldb.SearchIterator not fully consumed."); return NULL; } if (self->state.exception != NULL) { PyErr_SetObject(PyExc_LdbError, self->state.exception); self->state.exception = NULL; return NULL; } if (self->state.result == NULL) { PyErr_SetString(PyExc_RuntimeError, "ldb.SearchIterator result already consumed"); return NULL; } py_ret = self->state.result->obj; self->state.result->obj = NULL; TALLOC_FREE(self->state.result); return py_ret; } static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self, PyObject *Py_UNUSED(ignored)) { if (self->state.req == NULL) { PyErr_SetString(PyExc_RuntimeError, "ldb.SearchIterator request already finished"); return NULL; } Py_XDECREF(self->state.exception); TALLOC_FREE(self->mem_ctx); ZERO_STRUCT(self->state); Py_RETURN_NONE; } static PyMethodDef py_ldb_search_iterator_methods[] = { { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS, "S.result() -> ldb.Result (without msgs and referrals)\n" }, { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS, "S.abandon()\n" }, { NULL } }; static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self) { return PyUnicode_FromString(""); } static PyTypeObject PyLdbSearchIterator = { .tp_name = "ldb.SearchIterator", .tp_repr = (reprfunc)py_ldb_search_iterator_repr, .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc, .tp_iter = PyObject_SelfIter, .tp_iternext = (iternextfunc)py_ldb_search_iterator_next, .tp_methods = py_ldb_search_iterator_methods, .tp_basicsize = sizeof(PyLdbSearchIteratorObject), .tp_doc = "LDB search_iterator.", .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, }; static PyObject *py_ldb_module_repr(PyLdbModuleObject *self) { return PyUnicode_FromFormat("", pyldb_Module_AsModule(self)->ops->name); } static PyObject *py_ldb_module_str(PyLdbModuleObject *self) { return PyUnicode_FromString(pyldb_Module_AsModule(self)->ops->name); } static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self, PyObject *Py_UNUSED(ignored)) { pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self)); Py_RETURN_NONE; } static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self, PyObject *Py_UNUSED(ignored)) { pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self)); Py_RETURN_NONE; } static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self, PyObject *Py_UNUSED(ignored)) { pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self)); Py_RETURN_NONE; } static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs) { PyObject *py_base, *py_tree, *py_attrs, *py_ret; int ret, scope; struct ldb_request *req; const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL }; struct ldb_module *mod; const char * const*attrs; /* type "int" rather than "enum" for "scope" is intentional */ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO", discard_const_p(char *, kwnames), &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs)) return NULL; mod = self->mod; if (py_attrs == Py_None) { attrs = NULL; } else { attrs = PyList_AsStrList(NULL, py_attrs, "attrs"); if (attrs == NULL) return NULL; } ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), scope, NULL /* expr */, attrs, NULL /* controls */, NULL, NULL, NULL); talloc_steal(req, attrs); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); req->op.search.res = NULL; ret = mod->ops->search(mod, req); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); py_ret = PyLdbResult_FromResult(req->op.search.res); talloc_free(req); return py_ret; } static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args) { struct ldb_request *req; PyObject *py_message; int ret; struct ldb_module *mod; if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message)) return NULL; req = talloc_zero(NULL, struct ldb_request); req->operation = LDB_ADD; req->op.add.message = pyldb_Message_AsMessage(py_message); mod = pyldb_Module_AsModule(self); ret = mod->ops->add(mod, req); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); Py_RETURN_NONE; } static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) { int ret; struct ldb_request *req; PyObject *py_message; struct ldb_module *mod; if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message)) return NULL; req = talloc_zero(NULL, struct ldb_request); req->operation = LDB_MODIFY; req->op.mod.message = pyldb_Message_AsMessage(py_message); mod = pyldb_Module_AsModule(self); ret = mod->ops->modify(mod, req); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); Py_RETURN_NONE; } static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) { int ret; struct ldb_request *req; PyObject *py_dn; if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn)) return NULL; req = talloc_zero(NULL, struct ldb_request); req->operation = LDB_DELETE; req->op.del.dn = pyldb_Dn_AsDn(py_dn); ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); Py_RETURN_NONE; } static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args) { int ret; struct ldb_request *req; PyObject *py_dn1, *py_dn2; if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2)) return NULL; req = talloc_zero(NULL, struct ldb_request); req->operation = LDB_RENAME; req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1); req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2); ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); Py_RETURN_NONE; } static PyMethodDef py_ldb_module_methods[] = { { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search), METH_VARARGS|METH_KEYWORDS, NULL }, { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL }, { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL }, { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL }, { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL }, { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL }, { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL }, { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL }, { NULL }, }; static void py_ldb_module_dealloc(PyLdbModuleObject *self) { talloc_free(self->mem_ctx); PyObject_Del(self); } static PyTypeObject PyLdbModule = { .tp_name = "ldb.LdbModule", .tp_methods = py_ldb_module_methods, .tp_repr = (reprfunc)py_ldb_module_repr, .tp_str = (reprfunc)py_ldb_module_str, .tp_basicsize = sizeof(PyLdbModuleObject), .tp_dealloc = (destructor)py_ldb_module_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = "LDB module (extension)", }; /** * Create a ldb_message_element from a Python object. * * This will accept any sequence objects that contains strings, or * a string object. * * A reference to set_obj will be borrowed. * * @param mem_ctx Memory context * @param set_obj Python object to convert * @param flags ldb_message_element flags to set * @param attr_name Name of the attribute * @return New ldb_message_element, allocated as child of mem_ctx */ static struct ldb_message_element *PyObject_AsMessageElement( TALLOC_CTX *mem_ctx, PyObject *set_obj, unsigned int flags, const char *attr_name) { struct ldb_message_element *me; const char *msg = NULL; Py_ssize_t size; int result; if (pyldb_MessageElement_Check(set_obj)) { PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj; /* We have to talloc_reference() the memory context, not the pointer * which may not actually be it's own context */ if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) { return pyldb_MessageElement_AsMessageElement(set_obj); } return NULL; } me = talloc(mem_ctx, struct ldb_message_element); if (me == NULL) { PyErr_NoMemory(); return NULL; } me->name = talloc_strdup(me, attr_name); me->flags = flags; if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) { me->num_values = 1; me->values = talloc_array(me, struct ldb_val, me->num_values); if (PyBytes_Check(set_obj)) { char *_msg = NULL; result = PyBytes_AsStringAndSize(set_obj, &_msg, &size); if (result != 0) { talloc_free(me); return NULL; } msg = _msg; } else { msg = PyUnicode_AsUTF8AndSize(set_obj, &size); if (msg == NULL) { talloc_free(me); return NULL; } } me->values[0].data = talloc_memdup(me, (const uint8_t *)msg, size+1); me->values[0].length = size; } else if (PySequence_Check(set_obj)) { Py_ssize_t i; me->num_values = PySequence_Size(set_obj); me->values = talloc_array(me, struct ldb_val, me->num_values); for (i = 0; i < me->num_values; i++) { PyObject *obj = PySequence_GetItem(set_obj, i); if (PyBytes_Check(obj)) { char *_msg = NULL; result = PyBytes_AsStringAndSize(obj, &_msg, &size); if (result != 0) { talloc_free(me); return NULL; } msg = _msg; } else if (PyUnicode_Check(obj)) { msg = PyUnicode_AsUTF8AndSize(obj, &size); if (msg == NULL) { talloc_free(me); return NULL; } } else { PyErr_Format(PyExc_TypeError, "Expected string as element %zd in list", i); talloc_free(me); return NULL; } me->values[i].data = talloc_memdup(me, (const uint8_t *)msg, size+1); me->values[i].length = size; } } else { PyErr_Format(PyExc_TypeError, "String or List type expected for '%s' attribute", attr_name); talloc_free(me); me = NULL; } return me; } static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, struct ldb_message_element *me) { Py_ssize_t i; PyObject *result; /* Python << 2.5 doesn't have PySet_New and PySet_Add. */ result = PyList_New(me->num_values); for (i = 0; i < me->num_values; i++) { PyList_SetItem(result, i, PyObject_FromLdbValue(&me->values[i])); } return result; } static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args) { unsigned int i; if (!PyArg_ParseTuple(args, "I", &i)) return NULL; if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values) Py_RETURN_NONE; return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i])); } static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args) { struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); return PyInt_FromLong(el->flags); } static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args) { unsigned int flags; struct ldb_message_element *el; if (!PyArg_ParseTuple(args, "I", &flags)) return NULL; el = pyldb_MessageElement_AsMessageElement(self); el->flags = flags; Py_RETURN_NONE; } static PyMethodDef py_ldb_msg_element_methods[] = { { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL }, { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL }, { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL }, { NULL }, }; static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self) { return pyldb_MessageElement_AsMessageElement(self)->num_values; } static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx) { struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); if (idx < 0 || idx >= el->num_values) { PyErr_SetString(PyExc_IndexError, "Out of range"); return NULL; } return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length); } static PySequenceMethods py_ldb_msg_element_seq = { .sq_length = (lenfunc)py_ldb_msg_element_len, .sq_item = (ssizeargfunc)py_ldb_msg_element_find, }; static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op) { int ret; if (!pyldb_MessageElement_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self), pyldb_MessageElement_AsMessageElement(other)); return richcmp(ret, op); } static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self) { PyObject *el = ldb_msg_element_to_set(NULL, pyldb_MessageElement_AsMessageElement(self)); PyObject *ret = PyObject_GetIter(el); Py_DECREF(el); return ret; } static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx) { PyLdbMessageElementObject *ret; ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement); if (ret == NULL) { PyErr_NoMemory(); return NULL; } ret->mem_ctx = talloc_new(NULL); if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) { PyErr_NoMemory(); return NULL; } ret->el = el; return (PyObject *)ret; } static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *py_elements = NULL; struct ldb_message_element *el; unsigned int flags = 0; char *name = NULL; const char * const kwnames[] = { "elements", "flags", "name", NULL }; PyLdbMessageElementObject *ret; TALLOC_CTX *mem_ctx; const char *msg = NULL; Py_ssize_t size; int result; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs", discard_const_p(char *, kwnames), &py_elements, &flags, &name)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } el = talloc_zero(mem_ctx, struct ldb_message_element); if (el == NULL) { PyErr_NoMemory(); talloc_free(mem_ctx); return NULL; } if (py_elements != NULL) { Py_ssize_t i; if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) { char *_msg = NULL; el->num_values = 1; el->values = talloc_array(el, struct ldb_val, 1); if (el->values == NULL) { talloc_free(mem_ctx); PyErr_NoMemory(); return NULL; } if (PyBytes_Check(py_elements)) { result = PyBytes_AsStringAndSize(py_elements, &_msg, &size); msg = _msg; } else { msg = PyUnicode_AsUTF8AndSize(py_elements, &size); result = (msg == NULL) ? -1 : 0; } if (result != 0) { talloc_free(mem_ctx); return NULL; } el->values[0].data = talloc_memdup(el->values, (const uint8_t *)msg, size + 1); el->values[0].length = size; } else if (PySequence_Check(py_elements)) { el->num_values = PySequence_Size(py_elements); el->values = talloc_array(el, struct ldb_val, el->num_values); if (el->values == NULL) { talloc_free(mem_ctx); PyErr_NoMemory(); return NULL; } for (i = 0; i < el->num_values; i++) { PyObject *item = PySequence_GetItem(py_elements, i); if (item == NULL) { talloc_free(mem_ctx); return NULL; } if (PyBytes_Check(item)) { char *_msg = NULL; result = PyBytes_AsStringAndSize(item, &_msg, &size); msg = _msg; } else if (PyUnicode_Check(item)) { msg = PyUnicode_AsUTF8AndSize(item, &size); result = (msg == NULL) ? -1 : 0; } else { PyErr_Format(PyExc_TypeError, "Expected string as element %zd in list", i); result = -1; } if (result != 0) { talloc_free(mem_ctx); return NULL; } el->values[i].data = talloc_memdup(el, (const uint8_t *)msg, size+1); el->values[i].length = size; } } else { PyErr_SetString(PyExc_TypeError, "Expected string or list"); talloc_free(mem_ctx); return NULL; } } el->flags = flags; el->name = talloc_strdup(el, name); ret = PyObject_New(PyLdbMessageElementObject, type); if (ret == NULL) { talloc_free(mem_ctx); return NULL; } ret->mem_ctx = mem_ctx; ret->el = el; return (PyObject *)ret; } static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self) { char *element_str = NULL; Py_ssize_t i; struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); PyObject *ret, *repr; for (i = 0; i < el->num_values; i++) { PyObject *o = py_ldb_msg_element_find(self, i); repr = PyObject_Repr(o); if (element_str == NULL) element_str = talloc_strdup(NULL, PyUnicode_AsUTF8(repr)); else element_str = talloc_asprintf_append(element_str, ",%s", PyUnicode_AsUTF8(repr)); Py_DECREF(repr); } if (element_str != NULL) { ret = PyUnicode_FromFormat("MessageElement([%s])", element_str); talloc_free(element_str); } else { ret = PyUnicode_FromString("MessageElement([])"); } return ret; } static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self) { struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); if (el->num_values == 1) return PyUnicode_FromStringAndSize((char *)el->values[0].data, el->values[0].length); else Py_RETURN_NONE; } static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self) { talloc_free(self->mem_ctx); PyObject_Del(self); } static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure) { return wrap_text("MessageElementTextWrapper", self); } static PyGetSetDef py_ldb_msg_element_getset[] = { { .name = discard_const_p(char, "text"), .get = (getter)py_ldb_msg_element_get_text, }, { .name = NULL } }; static PyTypeObject PyLdbMessageElement = { .tp_name = "ldb.MessageElement", .tp_basicsize = sizeof(PyLdbMessageElementObject), .tp_dealloc = (destructor)py_ldb_msg_element_dealloc, .tp_repr = (reprfunc)py_ldb_msg_element_repr, .tp_str = (reprfunc)py_ldb_msg_element_str, .tp_methods = py_ldb_msg_element_methods, .tp_getset = py_ldb_msg_element_getset, .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp, .tp_iter = (getiterfunc)py_ldb_msg_element_iter, .tp_as_sequence = &py_ldb_msg_element_seq, .tp_new = py_ldb_msg_element_new, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = "An element of a Message", }; static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args) { PyObject *py_ldb; PyObject *py_dict; PyObject *py_ret; struct ldb_message *msg; struct ldb_context *ldb_ctx; unsigned int mod_flags = LDB_FLAG_MOD_REPLACE; if (!PyArg_ParseTuple(args, "O!O!|I", &PyLdb, &py_ldb, &PyDict_Type, &py_dict, &mod_flags)) { return NULL; } if (!PyLdb_Check(py_ldb)) { PyErr_SetString(PyExc_TypeError, "Expected Ldb"); return NULL; } /* mask only flags we are going to use */ mod_flags = LDB_FLAG_MOD_TYPE(mod_flags); if (!mod_flags) { PyErr_SetString(PyExc_ValueError, "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE" " expected as mod_flag value"); return NULL; } ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags); if (!msg) { return NULL; } py_ret = PyLdbMessage_FromMessage(msg); talloc_unlink(ldb_ctx, msg); return py_ret; } static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args) { char *name; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; ldb_msg_remove_attr(self->msg, name); Py_RETURN_NONE; } static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_message *msg = pyldb_Message_AsMessage(self); Py_ssize_t i, j = 0; PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); if (msg->dn != NULL) { PyList_SetItem(obj, j, PyUnicode_FromString("dn")); j++; } for (i = 0; i < msg->num_elements; i++) { PyList_SetItem(obj, j, PyUnicode_FromString(msg->elements[i].name)); j++; } return obj; } static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name) { struct ldb_message_element *el; const char *name; struct ldb_message *msg = pyldb_Message_AsMessage(self); name = PyUnicode_AsUTF8(py_name); if (name == NULL) { PyErr_SetNone(PyExc_TypeError); return NULL; } if (!ldb_attr_cmp(name, "dn")) return pyldb_Dn_FromDn(msg->dn); el = ldb_msg_find_element(msg, name); if (el == NULL) { return NULL; } return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); } static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) { PyObject *ret = py_ldb_msg_getitem_helper(self, py_name); if (ret == NULL) { PyErr_SetString(PyExc_KeyError, "No such element"); return NULL; } return ret; } static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs) { PyObject *def = NULL; const char *kwnames[] = { "name", "default", "idx", NULL }; const char *name = NULL; int idx = -1; struct ldb_message *msg = pyldb_Message_AsMessage(self); struct ldb_message_element *el; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg", discard_const_p(char *, kwnames), &name, &def, &idx)) { return NULL; } if (strcasecmp(name, "dn") == 0) { return pyldb_Dn_FromDn(msg->dn); } el = ldb_msg_find_element(msg, name); if (el == NULL || (idx != -1 && el->num_values <= idx)) { if (def != NULL) { Py_INCREF(def); return def; } Py_RETURN_NONE; } if (idx == -1) { return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); } return PyObject_FromLdbValue(&el->values[idx]); } static PyObject *py_ldb_msg_items(PyLdbMessageObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_message *msg = pyldb_Message_AsMessage(self); Py_ssize_t i, j = 0; PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); if (l == NULL) { return PyErr_NoMemory(); } if (msg->dn != NULL) { PyObject *value = NULL; PyObject *obj = pyldb_Dn_FromDn(msg->dn); int res = 0; value = Py_BuildValue("(sO)", "dn", obj); Py_CLEAR(obj); if (value == NULL) { Py_CLEAR(l); return NULL; } res = PyList_SetItem(l, 0, value); if (res == -1) { Py_CLEAR(l); return NULL; } j++; } for (i = 0; i < msg->num_elements; i++, j++) { PyObject *value = NULL; PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); int res = 0; Py_CLEAR(py_el); value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); if (value == NULL ) { Py_CLEAR(l); return NULL; } res = PyList_SetItem(l, 0, value); if (res == -1) { Py_CLEAR(l); return NULL; } } return l; } static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self, PyObject *Py_UNUSED(ignored)) { struct ldb_message *msg = pyldb_Message_AsMessage(self); Py_ssize_t i = 0; PyObject *l = PyList_New(msg->num_elements); for (i = 0; i < msg->num_elements; i++) { PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)); } return l; } static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args) { struct ldb_message *msg = pyldb_Message_AsMessage(self); PyLdbMessageElementObject *py_element; int i, ret; struct ldb_message_element *el; struct ldb_message_element *el_new; if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element)) return NULL; el = py_element->el; if (el == NULL) { PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object"); return NULL; } if (el->name == NULL) { PyErr_SetString(PyExc_ValueError, "The element has no name"); return NULL; } ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); /* now deep copy all attribute values */ el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values); if (el_new->values == NULL) { PyErr_NoMemory(); return NULL; } el_new->num_values = el->num_values; for (i = 0; i < el->num_values; i++) { el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]); if (el_new->values[i].data == NULL && el->values[i].length != 0) { PyErr_NoMemory(); return NULL; } } Py_RETURN_NONE; } static PyMethodDef py_ldb_msg_methods[] = { { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS, "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" "Class method to create ldb.Message object from Dictionary.\n" "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, "S.keys() -> list\n\n" "Return sequence of all attribute names." }, { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, "S.remove(name)\n\n" "Remove all entries for attributes with the specified name."}, { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get), METH_VARARGS | METH_KEYWORDS, "msg.get(name,default=None,idx=None) -> string\n" "idx is the index into the values array\n" "if idx is None, then a list is returned\n" "if idx is not None, then the element with that index is returned\n" "if you pass the special name 'dn' then the DN object is returned\n"}, { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL }, { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL }, { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, "S.add(element)\n\n" "Add an element to this message." }, { NULL }, }; static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self) { PyObject *list, *iter; list = py_ldb_msg_keys(self, NULL); iter = PyObject_GetIter(list); Py_DECREF(list); return iter; } static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value) { const char *attr_name; attr_name = PyUnicode_AsUTF8(name); if (attr_name == NULL) { PyErr_SetNone(PyExc_TypeError); return -1; } if (value == NULL) { /* delitem */ ldb_msg_remove_attr(self->msg, attr_name); } else { int ret; struct ldb_message_element *el = PyObject_AsMessageElement(self->msg, value, 0, attr_name); if (el == NULL) { return -1; } ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name); ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags); if (ret != LDB_SUCCESS) { PyErr_SetLdbError(PyExc_LdbError, ret, NULL); return -1; } } return 0; } static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self) { return pyldb_Message_AsMessage(self)->num_elements; } static PyMappingMethods py_ldb_msg_mapping = { .mp_length = (lenfunc)py_ldb_msg_length, .mp_subscript = (binaryfunc)py_ldb_msg_getitem, .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem, }; static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { const char * const kwnames[] = { "dn", NULL }; struct ldb_message *ret; TALLOC_CTX *mem_ctx; PyObject *pydn = NULL; PyLdbMessageObject *py_ret; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &pydn)) return NULL; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } ret = ldb_msg_new(mem_ctx); if (ret == NULL) { talloc_free(mem_ctx); PyErr_NoMemory(); return NULL; } if (pydn != NULL) { struct ldb_dn *dn; if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) { talloc_free(mem_ctx); return NULL; } ret->dn = talloc_reference(ret, dn); } py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0); if (py_ret == NULL) { PyErr_NoMemory(); talloc_free(mem_ctx); return NULL; } py_ret->mem_ctx = mem_ctx; py_ret->msg = ret; return (PyObject *)py_ret; } static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg) { PyLdbMessageObject *ret; ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0); if (ret == NULL) { PyErr_NoMemory(); return NULL; } ret->mem_ctx = talloc_new(NULL); ret->msg = talloc_reference(ret->mem_ctx, msg); return (PyObject *)ret; } static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure) { struct ldb_message *msg = pyldb_Message_AsMessage(self); return pyldb_Dn_FromDn(msg->dn); } static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure) { struct ldb_message *msg = pyldb_Message_AsMessage(self); if (!pyldb_Dn_Check(value)) { PyErr_SetString(PyExc_TypeError, "expected dn"); return -1; } msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value)); return 0; } static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure) { return wrap_text("MessageTextWrapper", self); } static PyGetSetDef py_ldb_msg_getset[] = { { .name = discard_const_p(char, "dn"), .get = (getter)py_ldb_msg_get_dn, .set = (setter)py_ldb_msg_set_dn, }, { .name = discard_const_p(char, "text"), .get = (getter)py_ldb_msg_get_text, }, { .name = NULL }, }; static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self) { PyObject *dict = PyDict_New(), *ret, *repr; if (PyDict_Update(dict, (PyObject *)self) != 0) return NULL; repr = PyObject_Repr(dict); if (repr == NULL) { Py_DECREF(dict); return NULL; } ret = PyUnicode_FromFormat("Message(%s)", PyUnicode_AsUTF8(repr)); Py_DECREF(repr); Py_DECREF(dict); return ret; } static void py_ldb_msg_dealloc(PyLdbMessageObject *self) { talloc_free(self->mem_ctx); PyObject_Del(self); } static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1, PyLdbMessageObject *py_msg2, int op) { struct ldb_message *msg1, *msg2; unsigned int i; int ret; if (!PyLdbMessage_Check(py_msg2)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } msg1 = pyldb_Message_AsMessage(py_msg1), msg2 = pyldb_Message_AsMessage(py_msg2); if ((msg1->dn != NULL) || (msg2->dn != NULL)) { ret = ldb_dn_compare(msg1->dn, msg2->dn); if (ret != 0) { return richcmp(ret, op); } } ret = msg1->num_elements - msg2->num_elements; if (ret != 0) { return richcmp(ret, op); } for (i = 0; i < msg1->num_elements; i++) { ret = ldb_msg_element_compare_name(&msg1->elements[i], &msg2->elements[i]); if (ret != 0) { return richcmp(ret, op); } ret = ldb_msg_element_compare(&msg1->elements[i], &msg2->elements[i]); if (ret != 0) { return richcmp(ret, op); } } return richcmp(0, op); } static PyTypeObject PyLdbMessage = { .tp_name = "ldb.Message", .tp_methods = py_ldb_msg_methods, .tp_getset = py_ldb_msg_getset, .tp_as_mapping = &py_ldb_msg_mapping, .tp_basicsize = sizeof(PyLdbMessageObject), .tp_dealloc = (destructor)py_ldb_msg_dealloc, .tp_new = py_ldb_msg_new, .tp_repr = (reprfunc)py_ldb_msg_repr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_iter = (getiterfunc)py_ldb_msg_iter, .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp, .tp_doc = "A LDB Message", }; static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree) { PyLdbTreeObject *ret; ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0); if (ret == NULL) { PyErr_NoMemory(); return NULL; } ret->mem_ctx = talloc_new(NULL); ret->tree = talloc_reference(ret->mem_ctx, tree); return (PyObject *)ret; } static void py_ldb_tree_dealloc(PyLdbTreeObject *self) { talloc_free(self->mem_ctx); PyObject_Del(self); } static PyTypeObject PyLdbTree = { .tp_name = "ldb.Tree", .tp_basicsize = sizeof(PyLdbTreeObject), .tp_dealloc = (destructor)py_ldb_tree_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = "A search tree", }; /* Ldb_module */ static int py_module_search(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result, *py_base, *py_attrs, *py_tree; py_base = pyldb_Dn_FromDn(req->op.search.base); if (py_base == NULL) return LDB_ERR_OPERATIONS_ERROR; py_tree = PyLdbTree_FromTree(req->op.search.tree); if (py_tree == NULL) return LDB_ERR_OPERATIONS_ERROR; if (req->op.search.attrs == NULL) { py_attrs = Py_None; } else { int i, len; for (len = 0; req->op.search.attrs[len]; len++); py_attrs = PyList_New(len); for (i = 0; i < len; i++) PyList_SetItem(py_attrs, i, PyUnicode_FromString(req->op.search.attrs[i])); } py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"), discard_const_p(char, "OiOO"), py_base, req->op.search.scope, py_tree, py_attrs); Py_DECREF(py_attrs); Py_DECREF(py_tree); Py_DECREF(py_base); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } req->op.search.res = PyLdbResult_AsResult(NULL, py_result); if (req->op.search.res == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_add(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result, *py_msg; py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message)); if (py_msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"), discard_const_p(char, "O"), py_msg); Py_DECREF(py_msg); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_modify(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result, *py_msg; py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message)); if (py_msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"), discard_const_p(char, "O"), py_msg); Py_DECREF(py_msg); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_del(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result, *py_dn; py_dn = pyldb_Dn_FromDn(req->op.del.dn); if (py_dn == NULL) return LDB_ERR_OPERATIONS_ERROR; py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"), discard_const_p(char, "O"), py_dn); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_rename(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result, *py_olddn, *py_newdn; py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn); if (py_olddn == NULL) return LDB_ERR_OPERATIONS_ERROR; py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn); if (py_newdn == NULL) return LDB_ERR_OPERATIONS_ERROR; py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"), discard_const_p(char, "OO"), py_olddn, py_newdn); Py_DECREF(py_olddn); Py_DECREF(py_newdn); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_request(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result; py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"), discard_const_p(char, "")); Py_XDECREF(py_result); return LDB_ERR_OPERATIONS_ERROR; } static int py_module_extended(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result; py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"), discard_const_p(char, "")); Py_XDECREF(py_result); return LDB_ERR_OPERATIONS_ERROR; } static int py_module_start_transaction(struct ldb_module *mod) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result; py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"), discard_const_p(char, "")); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_end_transaction(struct ldb_module *mod) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result; py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"), discard_const_p(char, "")); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_del_transaction(struct ldb_module *mod) { PyObject *py_ldb = (PyObject *)mod->private_data; PyObject *py_result; py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"), discard_const_p(char, "")); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } Py_DECREF(py_result); return LDB_SUCCESS; } static int py_module_destructor(struct ldb_module *mod) { Py_DECREF((PyObject *)mod->private_data); return 0; } static int py_module_init(struct ldb_module *mod) { PyObject *py_class = (PyObject *)mod->ops->private_data; PyObject *py_result, *py_next, *py_ldb; py_ldb = PyLdb_FromLdbContext(mod->ldb); if (py_ldb == NULL) return LDB_ERR_OPERATIONS_ERROR; py_next = PyLdbModule_FromModule(mod->next); if (py_next == NULL) return LDB_ERR_OPERATIONS_ERROR; py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"), py_ldb, py_next); if (py_result == NULL) { return LDB_ERR_PYTHON_EXCEPTION; } mod->private_data = py_result; talloc_set_destructor(mod, py_module_destructor); return ldb_next_init(mod); } static PyObject *py_register_module(PyObject *module, PyObject *args) { int ret; struct ldb_module_ops *ops; PyObject *input; PyObject *tmp; if (!PyArg_ParseTuple(args, "O", &input)) return NULL; ops = talloc_zero(NULL, struct ldb_module_ops); if (ops == NULL) { PyErr_NoMemory(); return NULL; } tmp = PyObject_GetAttrString(input, discard_const_p(char, "name")); ops->name = talloc_strdup(ops, PyUnicode_AsUTF8(tmp)); Py_XDECREF(tmp); Py_INCREF(input); ops->private_data = input; ops->init_context = py_module_init; ops->search = py_module_search; ops->add = py_module_add; ops->modify = py_module_modify; ops->del = py_module_del; ops->rename = py_module_rename; ops->request = py_module_request; ops->extended = py_module_extended; ops->start_transaction = py_module_start_transaction; ops->end_transaction = py_module_end_transaction; ops->del_transaction = py_module_del_transaction; ret = ldb_register_module(ops); if (ret != LDB_SUCCESS) { TALLOC_FREE(ops); } PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); Py_RETURN_NONE; } static PyObject *py_timestring(PyObject *module, PyObject *args) { /* most times "time_t" is a signed integer type with 32 or 64 bit: * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */ long int t_val; char *tresult; PyObject *ret; if (!PyArg_ParseTuple(args, "l", &t_val)) return NULL; tresult = ldb_timestring(NULL, (time_t) t_val); ret = PyUnicode_FromString(tresult); talloc_free(tresult); return ret; } static PyObject *py_string_to_time(PyObject *module, PyObject *args) { char *str; if (!PyArg_ParseTuple(args, "s", &str)) return NULL; return PyInt_FromLong(ldb_string_to_time(str)); } static PyObject *py_valid_attr_name(PyObject *self, PyObject *args) { char *name; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; return PyBool_FromLong(ldb_valid_attr_name(name)); } /* encode a string using RFC2254 rules */ static PyObject *py_binary_encode(PyObject *self, PyObject *args) { char *str, *encoded; Py_ssize_t size = 0; struct ldb_val val; PyObject *ret; if (!PyArg_ParseTuple(args, "s#", &str, &size)) return NULL; val.data = (uint8_t *)str; val.length = size; encoded = ldb_binary_encode(NULL, val); if (encoded == NULL) { PyErr_SetString(PyExc_TypeError, "unable to encode binary string"); return NULL; } ret = PyUnicode_FromString(encoded); talloc_free(encoded); return ret; } /* decode a string using RFC2254 rules */ static PyObject *py_binary_decode(PyObject *self, PyObject *args) { char *str; struct ldb_val val; PyObject *ret; if (!PyArg_ParseTuple(args, "s", &str)) return NULL; val = ldb_binary_decode(NULL, str); if (val.data == NULL) { PyErr_SetString(PyExc_TypeError, "unable to decode binary string"); return NULL; } ret = PyBytes_FromStringAndSize((const char*)val.data, val.length); talloc_free(val.data); return ret; } static PyMethodDef py_ldb_global_methods[] = { { "register_module", py_register_module, METH_VARARGS, "S.register_module(module) -> None\n\n" "Register a LDB module."}, { "timestring", py_timestring, METH_VARARGS, "S.timestring(int) -> string\n\n" "Generate a LDAP time string from a UNIX timestamp" }, { "string_to_time", py_string_to_time, METH_VARARGS, "S.string_to_time(string) -> int\n\n" "Parse a LDAP time string into a UNIX timestamp." }, { "valid_attr_name", py_valid_attr_name, METH_VARARGS, "S.valid_attr_name(name) -> bool\n\nn" "Check whether the supplied name is a valid attribute name." }, { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new), METH_VARARGS|METH_KEYWORDS, "S.open() -> Ldb\n\n" "Open a new LDB context." }, { "binary_encode", py_binary_encode, METH_VARARGS, "S.binary_encode(string) -> string\n\n" "Perform a RFC2254 binary encoding on a string" }, { "binary_decode", py_binary_decode, METH_VARARGS, "S.binary_decode(string) -> string\n\n" "Perform a RFC2254 binary decode on a string" }, { NULL } }; #define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server." #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, .m_name = "ldb", .m_doc = MODULE_DOC, .m_size = -1, .m_methods = py_ldb_global_methods, }; #endif static PyObject* module_init(void) { PyObject *m; PyLdbBytesType.tp_base = &PyBytes_Type; if (PyType_Ready(&PyLdbBytesType) < 0) { return NULL; } if (PyType_Ready(&PyLdbDn) < 0) return NULL; if (PyType_Ready(&PyLdbMessage) < 0) return NULL; if (PyType_Ready(&PyLdbMessageElement) < 0) return NULL; if (PyType_Ready(&PyLdb) < 0) return NULL; if (PyType_Ready(&PyLdbModule) < 0) return NULL; if (PyType_Ready(&PyLdbTree) < 0) return NULL; if (PyType_Ready(&PyLdbResult) < 0) return NULL; if (PyType_Ready(&PyLdbSearchIterator) < 0) return NULL; if (PyType_Ready(&PyLdbControl) < 0) return NULL; #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); #else m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC); #endif if (m == NULL) return NULL; #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val) ADD_LDB_INT(SEQ_HIGHEST_SEQ); ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP); ADD_LDB_INT(SEQ_NEXT); ADD_LDB_INT(SCOPE_DEFAULT); ADD_LDB_INT(SCOPE_BASE); ADD_LDB_INT(SCOPE_ONELEVEL); ADD_LDB_INT(SCOPE_SUBTREE); ADD_LDB_INT(CHANGETYPE_NONE); ADD_LDB_INT(CHANGETYPE_ADD); ADD_LDB_INT(CHANGETYPE_DELETE); ADD_LDB_INT(CHANGETYPE_MODIFY); ADD_LDB_INT(FLAG_MOD_ADD); ADD_LDB_INT(FLAG_MOD_REPLACE); ADD_LDB_INT(FLAG_MOD_DELETE); ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF); ADD_LDB_INT(ATTR_FLAG_HIDDEN); ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX); ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE); ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF); ADD_LDB_INT(SUCCESS); ADD_LDB_INT(ERR_OPERATIONS_ERROR); ADD_LDB_INT(ERR_PROTOCOL_ERROR); ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED); ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED); ADD_LDB_INT(ERR_COMPARE_FALSE); ADD_LDB_INT(ERR_COMPARE_TRUE); ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED); ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED); ADD_LDB_INT(ERR_REFERRAL); ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED); ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION); ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED); ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS); ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE); ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE); ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING); ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION); ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS); ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX); ADD_LDB_INT(ERR_NO_SUCH_OBJECT); ADD_LDB_INT(ERR_ALIAS_PROBLEM); ADD_LDB_INT(ERR_INVALID_DN_SYNTAX); ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM); ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION); ADD_LDB_INT(ERR_INVALID_CREDENTIALS); ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS); ADD_LDB_INT(ERR_BUSY); ADD_LDB_INT(ERR_UNAVAILABLE); ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM); ADD_LDB_INT(ERR_LOOP_DETECT); ADD_LDB_INT(ERR_NAMING_VIOLATION); ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION); ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF); ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN); ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS); ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED); ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS); ADD_LDB_INT(ERR_OTHER); ADD_LDB_INT(FLG_RDONLY); 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); ADD_LDB_INT(PACKING_FORMAT); ADD_LDB_INT(PACKING_FORMAT_V2); /* Historical misspelling */ PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM); PyModule_AddStringConstant(m, "__docformat__", "restructuredText"); PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL); PyModule_AddObject(m, "LdbError", PyExc_LdbError); Py_INCREF(&PyLdb); Py_INCREF(&PyLdbDn); Py_INCREF(&PyLdbModule); Py_INCREF(&PyLdbMessage); Py_INCREF(&PyLdbMessageElement); Py_INCREF(&PyLdbTree); Py_INCREF(&PyLdbResult); Py_INCREF(&PyLdbControl); PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb); PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn); PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage); PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement); PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule); PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree); PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl); PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val) ADD_LDB_STRING(SYNTAX_DN); ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING); ADD_LDB_STRING(SYNTAX_INTEGER); ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER); ADD_LDB_STRING(SYNTAX_BOOLEAN); ADD_LDB_STRING(SYNTAX_OCTET_STRING); ADD_LDB_STRING(SYNTAX_UTC_TIME); ADD_LDB_STRING(OID_COMPARATOR_AND); ADD_LDB_STRING(OID_COMPARATOR_OR); return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit_ldb(void); PyMODINIT_FUNC PyInit_ldb(void) { return module_init(); } #else void initldb(void); void initldb(void) { module_init(); } #endif ldb-2.0.8/pyldb.h0000660000000000000000000000563213552036070013510 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python interface to ldb. Copyright (C) 2007-2008 Jelmer Vernooij ** 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 . */ #ifndef _PYLDB_H_ #define _PYLDB_H_ #include typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct ldb_context *ldb_ctx; } PyLdbObject; #define pyldb_Ldb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct ldb_dn *dn; } PyLdbDnObject; PyObject *pyldb_Dn_FromDn(struct ldb_dn *); bool pyldb_Object_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn); #define pyldb_Dn_AsDn(pyobj) ((PyLdbDnObject *)pyobj)->dn typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct ldb_message *msg; } PyLdbMessageObject; #define pyldb_Message_AsMessage(pyobj) ((PyLdbMessageObject *)pyobj)->msg typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct ldb_module *mod; } PyLdbModuleObject; #define pyldb_Module_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod /* * NOTE: el (and so the return value of * pyldb_MessageElement_AsMessageElement()) may not be a valid talloc * context, it could be part of an array */ typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct ldb_message_element *el; } PyLdbMessageElementObject; #define pyldb_MessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct ldb_parse_tree *tree; } PyLdbTreeObject; #define pyldb_Tree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; PyObject *msgs; PyObject *referals; PyObject *controls; } PyLdbResultObject; typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct ldb_control *data; } PyLdbControlObject; #define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) do { \ if (ret != LDB_SUCCESS) { \ PyErr_SetLdbError(err, ret, ldb); \ return NULL; \ } \ } while(0) /* Picked out of thin air. To do this properly, we should probably have some part of the * errors in LDB be allocated to bindings ? */ #define LDB_ERR_PYTHON_EXCEPTION 142 #endif /* _PYLDB_H_ */ ldb-2.0.8/pyldb_util.c0000660000000000000000000000541213573675413014551 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python interface to ldb - utility functions. Copyright (C) 2007-2010 Jelmer Vernooij ** 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 . */ #include #include "ldb.h" #include "pyldb.h" static PyObject *ldb_module = NULL; /** * Find out PyTypeObject in ldb module for a given typename */ static PyTypeObject * PyLdb_GetPyType(const char *typename) { PyObject *py_obj = NULL; if (ldb_module == NULL) { ldb_module = PyImport_ImportModule("ldb"); if (ldb_module == NULL) { return NULL; } } py_obj = PyObject_GetAttrString(ldb_module, typename); return (PyTypeObject*)py_obj; } /** * Obtain a ldb DN from a Python object. * * @param mem_ctx Memory context * @param object Python object * @param ldb_ctx LDB context * @return Whether or not the conversion succeeded */ bool pyldb_Object_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn) { struct ldb_dn *odn; PyTypeObject *PyLdb_Dn_Type; if (ldb_ctx != NULL && (PyUnicode_Check(object))) { odn = ldb_dn_new(mem_ctx, ldb_ctx, PyUnicode_AsUTF8(object)); *dn = odn; return true; } if (ldb_ctx != NULL && PyBytes_Check(object)) { odn = ldb_dn_new(mem_ctx, ldb_ctx, PyBytes_AsString(object)); *dn = odn; return true; } PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); if (PyLdb_Dn_Type == NULL) { return false; } if (PyObject_TypeCheck(object, PyLdb_Dn_Type)) { *dn = pyldb_Dn_AsDn(object); return true; } PyErr_SetString(PyExc_TypeError, "Expected DN"); return false; } PyObject *pyldb_Dn_FromDn(struct ldb_dn *dn) { PyLdbDnObject *py_ret; PyTypeObject *PyLdb_Dn_Type; if (dn == NULL) { Py_RETURN_NONE; } PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); if (PyLdb_Dn_Type == NULL) { return NULL; } py_ret = (PyLdbDnObject *)PyLdb_Dn_Type->tp_alloc(PyLdb_Dn_Type, 0); if (py_ret == NULL) { PyErr_NoMemory(); return NULL; } py_ret->mem_ctx = talloc_new(NULL); py_ret->dn = talloc_reference(py_ret->mem_ctx, dn); return (PyObject *)py_ret; } ldb-2.0.8/tests/guidindexpackv1.ldb0000660000000000000000000472000013573675413017152 0ustar rootroot00000000000000TDB file m&'Ð1 Ÿ}ö ùþ:@¾»pÁTÏÅØÅ„Ç@É込ˀÂdÈ,ÄÀΔÀ<½PÍÊìÊl¼Ä¿\Ã´Æ ÎüfæþÙT"ëwLð½™&DN=@INDEX:@IDXONE:DC=SAMBA,DC=ORGg&@INDEX:@IDXONE:DC=SAMBA,DC=ORG@IDXVERSION3@IDX 0123456789abcdef0123456789abcdf00123456789abcdf10123456789abcdf20123456789abcdf30123456789abcdf40123456789abcdf50123456789abcdf60123456789abcdf70123456789abcdf8l¸{#-(á™&GUID=0123456789abcdf8g&OU=GUIDPFTEST9,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf8name GUIDPFTEST9ou GUIDPFTEST9ÐÄ0i5©‹#™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST8,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST8,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf7ܸ{sFÃÄ™&GUID=0123456789abcdf7g&OU=GUIDPFTEST8,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf7name GUIDPFTEST8ou GUIDPFTEST8ÐÄ0iuø±™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST7,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST7,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf6ܸ{Ã_^¨™&GUID=0123456789abcdf6g&OU=GUIDPFTEST7,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf6name GUIDPFTEST7ou GUIDPFTEST7ÐÄ0iµsd@™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST6,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST6,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf5ܸ{yù‹™&GUID=0123456789abcdf5g&OU=GUIDPFTEST6,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf5name GUIDPFTEST6ou GUIDPFTEST6ИÌ("ÛwLð½fæþÙDN=@INDEX:@IDXONE:DC=SAMBA,DC=ORGg@Ä0iõC•™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST9,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST9,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf8df50123456789abcdf60123456789abcdf7ܸ{c’”o™&GUID=0123456789abcdf4g&OU=GUIDPFTEST5,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf4name GUIDPFTEST5ou GUIDPFTEST5ÐÄ0i5>=]™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST4,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST4,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf3ܸ{³«/S™&GUID=0123456789abcdf3g&OU=GUIDPFTEST4,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf3name GUIDPFTEST4ou GUIDPFTEST4ÐÄ0iu£©ë™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST3,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST3,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf2ܸ{ÅÊ6™&GUID=0123456789abcdf2g&OU=GUIDPFTEST3,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf2name GUIDPFTEST3ou GUIDPFTEST3ÐÈ0iõØÐΙ&DN=@INDEX:@IDXDN:OU=GUIDPFTEST5,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST5,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf4df10123456789abcdf20123456789abcdf3àÄ0iµz™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST2,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST2,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf1ܸ{SÞe™&GUID=0123456789abcdf1g&OU=GUIDPFTEST2,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf1name GUIDPFTEST2ou GUIDPFTEST2ÐÄ0iõm‚™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST1,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST1,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf0ܸ{£÷þ™&GUID=0123456789abcdf0g&OU=GUIDPFTEST1,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf0name GUIDPFTEST1ou GUIDPFTEST1ÐÄ0i5Óî–™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST0,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST0,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdefܜϠ"kwLð½fæþÙDN=@INDEX:@IDXONE:DC=SAMBA,DC=ORGg&@INDEX:@IDXONE:DC=SAMBA,DC=ORG@IDXVERSION3@IDX 0123456789abcdef0123456789abcdf0¸¸{àÉÅ™&GUID=0123456789abcdefg&OU=GUIDPFTEST0,DC=SAMBA,DC=ORGobjectUUID0123456789abcdefname GUIDPFTEST0ou GUIDPFTEST0Ј[«d˜„™&DN=@INDEXLISTg&@INDEXLIST@IDX_DN_GUIDGUID@IDXGUID objectUUID@IDXONE1 | Rä¯W™&DN=@BASEINFOg&@BASEINFOwhenChanged20190521021228.0ZsequenceNumber13”0d[δ™&DN=@ATTRIBUTESg&@ATTRIBUTESHìœL +ä¯WfæþÙDN=@BASEINFOg&@BASEINFOsequenceNumber1dèÏ =]™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST4,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST4,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf3ܸ{³«/S™&GUID=0123456789abcdf3g&OU=GUIDPFTEST4,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf3name GUIDPFTEST4ou GUIDPFTEST4ÐÄ0iu£©ë™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST3,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST3,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf2ܸ{ÅÊ6™&GUID=0123456789abcdf2g&OU=GUIDPFTEST3,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf2name GUIDPFTEST3ou GUIDPFTEST3ÐÈ0iõØÐΙ&DN=@INDEX:@IDXDN:OU=GUIDPFTEST5,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST5,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf4df10123456789abcdf20123456789abcdf3àÄ0iµz™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST2,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST2,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf1ܸ{SÞe™&GUID=0123456789abcdf1g&OU=GUIDPFTEST2,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf1name GUIDPFTEST2ou GUIDPFTEST2ÐÄ0iõm‚™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST1,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST1,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdf0ܸ{£÷þ™&GUID=0123456789abcdf0g&OU=GUIDPFTEST1,DC=SAMBA,DC=ORGobjectUUID0123456789abcdf0name GUIDPFTEST1ou GUIDPFTEST1ÐÄ0i5Óî–™&DN=@INDEX:@IDXDN:OU=GUIDPFTEST0,DC=SAMBA,DC=ORGg&@INDEX:@IDXDN:OU=GUIDPFTEST0,DC=SAMBA,DC=ORG@IDXVERSION3@IDX0123456789abcdefܜϠ"kwLð½fæþÙDN=@INDEX:@IDXONE:DC=SAMBA,DC=ORGg&@INDEX:@IDXONE:DC=SAMBA,DC=ORG@IDXVERSION3@IDX 0123456789abcdef0123456789abcdf0¸¸{àÉÅ™&GUID=0123456789abcdefg&OU=GUIDPFTEST0,DC=SAMBA,DC=ORGobjectUUID0123456789abcdefname GUIDPFTEST0ou GUIDPFTEST0Ј[«d˜„™&DN=@INDEXLISTg&@INDEXLIST@IDX_DN_GUIDGUID@IDXGUID objectUUID@IDXONE1 | Rä¯W™&DN=@BASEINFOg&@BASEINFOwhenChanged20190521021228.0ZsequenceNumber12”0d[δ™&DN=@ATTRIBUTESg&@ATTRIBUTESHìœL +ä¯WfæþÙDN=@BASEINFOg&@BASEINFOsequenceNumber1dÐldb-2.0.8/tests/init.ldif0000660000000000000000000000171512406075657015203 0ustar rootroot00000000000000dn: o=University of Michigan,c=TEST objectclass: organization objectclass: domainRelatedObject l: Ann Arbor, Michigan st: Michigan o: University of Michigan o: UMICH o: UM o: U-M o: U of M description: The University of Michigan at Ann Arbor postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 09 $ US telephonenumber: +1 313 764-1817 associateddomain: example.com # there was an empty "seeAlso" here dn: ou=People,o=University of Michigan,c=TEST objectclass: organizationalUnit objectclass: extensibleObject ou: People uidNumber: 0 gidNumber: 0 dn: ou=Ldb Test,ou=People,o=University of Michigan,c=TEST objectclass: organizationalUnit objectclass: extensibleObject ou: People ou: Ldb Test uidNumber: 0 gidNumber: 0 dn: ou=LdbTspace,ou=People,o=University of Michigan,c=TEST objectclass: organizationalUnit objectclass: extensibleObject ou: People ou: LdbTspace description: test white space removal in comparisons uidNumber: 0 gidNumber: 0 ldb-2.0.8/tests/init_slapd.sh0000770000000000000000000000151212406075657016057 0ustar rootroot00000000000000#!/bin/sh if [ -z "$LDBDIR" ]; then LDBDIR=`dirname $0`/.. export LDBDIR fi rm -rf tests/tmp/db mkdir -p tests/tmp/db if [ -f tests/tmp/slapd.pid ]; then kill `cat tests/tmp/slapd.pid` sleep 1 fi if [ -f tests/tmp/slapd.pid ]; then kill -9 `cat tests/tmp/slapd.pid` rm -f tests/tmp/slapd.pid fi # we don't consider a slapadd failure as a test suite failure, as it # has nothing to do with ldb MODCONF=tests/tmp/modules.conf rm -f $MODCONF touch $MODCONF || exit 1 slaptest -u -f $LDBDIR/tests/slapd.conf > /dev/null 2>&1 || { echo "enabling sladp modules" cat > $MODCONF < 2019 * * 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 . * */ /* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. */ #include #include #include #include #include #include "../include/ldb.h" #include "../include/ldb_module.h" struct ldbtest_ctx { struct tevent_context *ev; struct ldb_context *ldb; }; /* * NOTE WELL: * * This test checks the current behaviour of the function, however * this is not in a public ABI and many of the tested behaviours are * not ideal. If the behaviour is deliberatly improved, this test * should be updated without worry to the new better behaviour. * * In particular the test is particularly to ensure the current * behaviour is memory-safe. */ static int 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); *state = test_ctx; return 0; } static int teardown(void **state) { talloc_free(*state); return 0; } /* * Test against a record with only one attribute, matching the one in * the list */ static void test_filter_attrs_one_attr_matched(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"foo", NULL}; uint8_t value[] = "The value.......end"; struct ldb_val value_1 = { .data = value, .length = (sizeof(value)) }; struct ldb_message_element element_1 = { .name = "foo", .num_values = 1, .values = &value_1 }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 1, .elements = &element_1, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); /* * assert the ldb_filter_attrs does not read or modify * filtered_msg.dn in this case */ assert_null(filtered_msg->dn); assert_int_equal(filtered_msg->num_elements, 1); assert_string_equal(filtered_msg->elements[0].name, "foo"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_int_equal(filtered_msg->elements[0].values[0].length, sizeof(value)); assert_memory_equal(filtered_msg->elements[0].values[0].data, value, sizeof(value)); } /* * Test against a record with only one attribute, matching the one of * the multiple attributes in the list */ static void test_filter_attrs_one_attr_matched_of_many(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"foo", "bar", "baz", NULL}; uint8_t value[] = "The value.......end"; struct ldb_val value_1 = { .data = value, .length = (sizeof(value)) }; struct ldb_message_element element_1 = { .name = "foo", .num_values = 1, .values = &value_1 }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 1, .elements = &element_1, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); /* * assert the ldb_filter_attrs does not read or modify * filtered_msg.dn in this case */ assert_null(filtered_msg->dn); assert_int_equal(filtered_msg->num_elements, 1); assert_string_equal(filtered_msg->elements[0].name, "foo"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_int_equal(filtered_msg->elements[0].values[0].length, sizeof(value)); assert_memory_equal(filtered_msg->elements[0].values[0].data, value, sizeof(value)); } /* * Test against a record with only one attribute, matching both * attributes in the list */ static void test_filter_attrs_two_attr_matched_attrs(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); /* deliberatly the other order */ const char *attrs[] = {"bar", "foo", NULL}; uint8_t value1[] = "The value.......end"; uint8_t value2[] = "The value..MUST.end"; struct ldb_val value_1 = { .data = value1, .length = (sizeof(value1)) }; struct ldb_val value_2 = { .data = value2, .length = (sizeof(value2)) }; /* foo and bar are the other order to in attrs */ struct ldb_message_element elements[] = { { .name = "foo", .num_values = 1, .values = &value_1 }, { .name = "bar", .num_values = 1, .values = &value_2 } }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 2, .elements = elements, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); assert_int_equal(filtered_msg->num_elements, 2); /* * assert the ldb_filter_attrs does not read or modify * filtered_msg.dn in this case */ assert_null(filtered_msg->dn); /* Assert that DB order is preserved */ assert_string_equal(filtered_msg->elements[0].name, "foo"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_int_equal(filtered_msg->elements[0].values[0].length, sizeof(value1)); assert_memory_equal(filtered_msg->elements[0].values[0].data, value1, sizeof(value1)); assert_string_equal(filtered_msg->elements[1].name, "bar"); assert_int_equal(filtered_msg->elements[1].num_values, 1); assert_int_equal(filtered_msg->elements[1].values[0].length, sizeof(value2)); assert_memory_equal(filtered_msg->elements[1].values[0].data, value2, sizeof(value2)); } /* * Test against a record with two attributes, only of which is in * the list */ static void test_filter_attrs_two_attr_matched_one_attr(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); /* deliberatly the other order */ const char *attrs[] = {"bar", NULL}; uint8_t value1[] = "The value.......end"; uint8_t value2[] = "The value..MUST.end"; struct ldb_val value_1 = { .data = value1, .length = (sizeof(value1)) }; struct ldb_val value_2 = { .data = value2, .length = (sizeof(value2)) }; /* foo and bar are the other order to in attrs */ struct ldb_message_element elements[] = { { .name = "foo", .num_values = 1, .values = &value_1 }, { .name = "bar", .num_values = 1, .values = &value_2 } }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 2, .elements = elements, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); assert_int_equal(filtered_msg->num_elements, 1); /* * assert the ldb_filter_attrs does not read or modify * filtered_msg.dn in this case */ assert_null(filtered_msg->dn); /* Assert that DB order is preserved */ assert_string_equal(filtered_msg->elements[0].name, "bar"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_int_equal(filtered_msg->elements[0].values[0].length, sizeof(value2)); assert_memory_equal(filtered_msg->elements[0].values[0].data, value2, sizeof(value2)); } /* * Test against a record with two attributes, both matching the one * specified attribute in the list (a corrupt record) */ static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); /* deliberatly the other order */ const char *attrs[] = {"bar", NULL}; uint8_t value1[] = "The value.......end"; uint8_t value2[] = "The value..MUST.end"; struct ldb_val value_1 = { .data = value1, .length = (sizeof(value1)) }; struct ldb_val value_2 = { .data = value2, .length = (sizeof(value2)) }; /* foo and bar are the other order to in attrs */ struct ldb_message_element elements[] = { { .name = "bar", .num_values = 1, .values = &value_1 }, { .name = "bar", .num_values = 1, .values = &value_2 } }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 2, .elements = elements, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); /* This should fail the pidgenhole test */ assert_int_equal(ret, -1); assert_null(filtered_msg->elements); } /* * Test against a record with two attributes, both matching the one * specified attribute in the list (a corrupt record) */ static void test_filter_attrs_two_dup_attr_matched_dup(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"bar", "bar", NULL}; uint8_t value1[] = "The value.......end"; uint8_t value2[] = "The value..MUST.end"; struct ldb_val value_1 = { .data = value1, .length = (sizeof(value1)) }; struct ldb_val value_2 = { .data = value2, .length = (sizeof(value2)) }; /* foo and bar are the other order to in attrs */ struct ldb_message_element elements[] = { { .name = "bar", .num_values = 1, .values = &value_1 }, { .name = "bar", .num_values = 1, .values = &value_2 } }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 2, .elements = elements, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); /* This does not fail the pidgenhole test */ assert_int_equal(ret, LDB_SUCCESS); assert_int_equal(filtered_msg->num_elements, 2); /* Assert that DB order is preserved */ assert_string_equal(filtered_msg->elements[0].name, "bar"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_int_equal(filtered_msg->elements[0].values[0].length, sizeof(value1)); assert_memory_equal(filtered_msg->elements[0].values[0].data, value1, sizeof(value1)); assert_string_equal(filtered_msg->elements[1].name, "bar"); assert_int_equal(filtered_msg->elements[1].num_values, 1); assert_int_equal(filtered_msg->elements[1].values[0].length, sizeof(value2)); assert_memory_equal(filtered_msg->elements[1].values[0].data, value2, sizeof(value2)); } /* * Test against a record with two attributes, both matching one of the * specified attributes in the list (a corrupt record) */ static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"bar", "foo", NULL}; uint8_t value1[] = "The value.......end"; uint8_t value2[] = "The value..MUST.end"; struct ldb_val value_1 = { .data = value1, .length = (sizeof(value1)) }; struct ldb_val value_2 = { .data = value2, .length = (sizeof(value2)) }; /* foo and bar are the other order to in attrs */ struct ldb_message_element elements[] = { { .name = "bar", .num_values = 1, .values = &value_1 }, { .name = "bar", .num_values = 1, .values = &value_2 } }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 2, .elements = elements, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); /* This does not fail the pidgenhole test */ assert_int_equal(ret, LDB_SUCCESS); assert_int_equal(filtered_msg->num_elements, 2); /* Assert that DB order is preserved */ assert_string_equal(filtered_msg->elements[0].name, "bar"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_int_equal(filtered_msg->elements[0].values[0].length, sizeof(value1)); assert_memory_equal(filtered_msg->elements[0].values[0].data, value1, sizeof(value1)); assert_string_equal(filtered_msg->elements[1].name, "bar"); assert_int_equal(filtered_msg->elements[1].num_values, 1); assert_int_equal(filtered_msg->elements[1].values[0].length, sizeof(value2)); assert_memory_equal(filtered_msg->elements[1].values[0].data, value2, sizeof(value2)); } /* * Test against a record with two attributes against * (but not the * other named attribute) (a corrupt record) */ static void test_filter_attrs_two_dup_attr_matched_star(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"*", "foo", NULL}; uint8_t value1[] = "The value.......end"; uint8_t value2[] = "The value..MUST.end"; struct ldb_val value_1 = { .data = value1, .length = (sizeof(value1)) }; struct ldb_val value_2 = { .data = value2, .length = (sizeof(value2)) }; /* foo and bar are the other order to in attrs */ struct ldb_message_element elements[] = { { .name = "bar", .num_values = 1, .values = &value_1 }, { .name = "bar", .num_values = 1, .values = &value_2 } }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 2, .elements = elements, }; assert_non_null(in.dn); /* Needed as * implies distinguishedName */ filtered_msg->dn = in.dn; ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); /* This does not fail the pidgenhole test */ assert_int_equal(ret, LDB_SUCCESS); assert_int_equal(filtered_msg->num_elements, 3); /* Assert that DB order is preserved */ assert_string_equal(filtered_msg->elements[0].name, "bar"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_int_equal(filtered_msg->elements[0].values[0].length, sizeof(value1)); assert_memory_equal(filtered_msg->elements[0].values[0].data, value1, sizeof(value1)); assert_string_equal(filtered_msg->elements[1].name, "bar"); assert_int_equal(filtered_msg->elements[1].num_values, 1); assert_int_equal(filtered_msg->elements[1].values[0].length, sizeof(value2)); assert_memory_equal(filtered_msg->elements[1].values[0].data, value2, sizeof(value2)); /* * assert the ldb_filter_attrs does not modify filtered_msg.dn * in this case */ assert_ptr_equal(filtered_msg->dn, in.dn); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "distinguishedName", NULL), ldb_dn_get_linearized(in.dn)); } /* * Test against a record with only one attribute, matching the * in * the list */ static void test_filter_attrs_one_attr_matched_star(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"*", NULL}; uint8_t value[] = "The value.......end"; struct ldb_val value_1 = { .data = value, .length = (sizeof(value)) }; struct ldb_message_element element_1 = { .name = "foo", .num_values = 1, .values = &value_1 }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 1, .elements = &element_1, }; assert_non_null(in.dn); /* Needed as * implies distinguishedName */ filtered_msg->dn = in.dn; ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); assert_int_equal(filtered_msg->num_elements, 2); /* * assert the ldb_filter_attrs does not modify filtered_msg.dn * in this case */ assert_ptr_equal(filtered_msg->dn, in.dn); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "distinguishedName", NULL), ldb_dn_get_linearized(in.dn)); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "foo", NULL), value); } /* * Test against a record with two attributes, matching the * in * the list */ static void test_filter_attrs_two_attr_matched_star(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"*", NULL}; uint8_t value1[] = "The value.......end"; uint8_t value2[] = "The value..MUST.end"; struct ldb_val value_1 = { .data = value1, .length = (sizeof(value1)) }; struct ldb_val value_2 = { .data = value2, .length = (sizeof(value2)) }; struct ldb_message_element elements[] = { { .name = "foo", .num_values = 1, .values = &value_1 }, { .name = "bar", .num_values = 1, .values = &value_2 } }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 2, .elements = elements, }; assert_non_null(in.dn); /* Needed as * implies distinguishedName */ filtered_msg->dn = in.dn; ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); assert_int_equal(filtered_msg->num_elements, 3); /* * assert the ldb_filter_attrs does not modify filtered_msg.dn * in this case */ assert_ptr_equal(filtered_msg->dn, in.dn); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "distinguishedName", NULL), ldb_dn_get_linearized(in.dn)); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "foo", NULL), value1); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "bar", NULL), value2); } /* * Test against a record with only one attribute, matching the * in * the list, but without the DN being pre-filled. Fails due to need * to contstruct the distinguishedName */ static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"*", NULL}; uint8_t value[] = "The value.......end"; struct ldb_val value_1 = { .data = value, .length = (sizeof(value)) }; struct ldb_message_element element_1 = { .name = "foo", .num_values = 1, .values = &value_1 }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 1, .elements = &element_1, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, -1); assert_null(filtered_msg->elements); } /* * Test against a record with only one attribute, matching the * in * the list plus requsesting distinguishedName */ static void test_filter_attrs_one_attr_matched_star_dn(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"*", "distinguishedName", NULL}; uint8_t value[] = "The value.......end"; struct ldb_val value_1 = { .data = value, .length = (sizeof(value)) }; struct ldb_message_element element_1 = { .name = "foo", .num_values = 1, .values = &value_1 }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 1, .elements = &element_1, }; assert_non_null(in.dn); /* Needed for distinguishedName */ filtered_msg->dn = in.dn; ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); assert_int_equal(filtered_msg->num_elements, 2); /* show that ldb_filter_attrs does not modify in.dn */ assert_ptr_equal(filtered_msg->dn, in.dn); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "distinguishedName", NULL), ldb_dn_get_linearized(in.dn)); assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, "foo", NULL), value); } /* * Test against a record with only one attribute, but returning * distinguishedName from the list (only) */ static void test_filter_attrs_one_attr_matched_dn(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {"distinguishedName", NULL}; uint8_t value[] = "The value.......end"; struct ldb_val value_1 = { .data = value, .length = (sizeof(value)) }; struct ldb_message_element element_1 = { .name = "foo", .num_values = 1, .values = &value_1 }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 1, .elements = &element_1, }; assert_non_null(in.dn); /* Needed for distinguishedName */ filtered_msg->dn = in.dn; ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); assert_int_equal(filtered_msg->num_elements, 1); /* show that ldb_filter_attrs does not modify in.dn */ assert_ptr_equal(filtered_msg->dn, in.dn); assert_string_equal(filtered_msg->elements[0].name, "distinguishedName"); assert_int_equal(filtered_msg->elements[0].num_values, 1); assert_string_equal(filtered_msg->elements[0].values[0].data, ldb_dn_get_linearized(in.dn)); } /* * Test against a record with only one attribute, not matching the * empty attribute list */ static void test_filter_attrs_one_attr_empty_list(void **state) { struct ldbtest_ctx *ctx = *state; int ret; struct ldb_message *filtered_msg = ldb_msg_new(ctx); const char *attrs[] = {NULL}; uint8_t value[] = "The value.......end"; struct ldb_val value_1 = { .data = value, .length = (sizeof(value)) }; struct ldb_message_element element_1 = { .name = "foo", .num_values = 1, .values = &value_1 }; struct ldb_message in = { .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), .num_elements = 1, .elements = &element_1, }; assert_non_null(in.dn); ret = ldb_filter_attrs(ctx->ldb, &in, attrs, filtered_msg); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(filtered_msg); assert_int_equal(filtered_msg->num_elements, 0); assert_null(filtered_msg->dn); assert_null(filtered_msg->elements); } int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown( test_filter_attrs_one_attr_matched, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_one_attr_matched_of_many, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_two_attr_matched_attrs, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_two_attr_matched_one_attr, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_two_dup_attr_matched_one_attr, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_two_dup_attr_matched_dup, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_two_dup_attr_matched_one_of_two, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_two_dup_attr_matched_star, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_one_attr_matched_star, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_two_attr_matched_star, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_one_attr_matched_star_no_dn, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_one_attr_matched_star_dn, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_one_attr_matched_dn, setup, teardown), cmocka_unit_test_setup_teardown( test_filter_attrs_one_attr_empty_list, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind0000660000000000000000000000301413573675413023354 0ustar rootroot00000000000000{ Memory allocated by setup Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:setup } { Memory allocated by setup Memcheck:Leak match-leak-kinds: possible fun:realloc ... fun:setup } { Memory allocated by ldb_init Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_init } { Memory allocated by ldb_init Memcheck:Leak match-leak-kinds: possible fun:realloc ... fun:ldb_init } { Memory allocated by noconn_setup Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:noconn_setup } { Memory allocated by parse, which allocates on the NULL context Memcheck:Leak match-leak-kinds: all fun:malloc ... fun:parse } { Memory allocated by tdb_parse_data Memcheck:Leak match-leak-kinds: all fun:malloc ... fun:tdb_parse_data } { Memory allocated by ldb_connect Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_connect } { Memory allocated by ldb_connect Memcheck:Leak match-leak-kinds: possible fun:calloc ... fun:ldb_connect } { Memory allocated by ldb_kv_cache_load Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_kv_cache_load } { Memory allocated by ldb_kv_index_load Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_kv_index_load } { Memory allocated by ldb_asprintf_errstring Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_asprintf_errstring } ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c0000660000000000000000000004511613573675413021157 0ustar rootroot00000000000000/* * Tests exercising the ldb key value operations. * * Copyright (C) Andrew Bartlett 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 . * */ /* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. * */ /* */ #include #include #include #include #include #define NO_FAILURE INT_MAX #define FAILURE_LDB_ERR LDB_ERR_OTHER /* * To test failure in ldb_kv_add, ldb_kv_delete, ldb_kv_modify and ldb_kv_rename * we use the following global variables and macros to trigger a failure in * the ldb_kv__internal functions. This allows testing of the sub * transaction commits and roll backs in those operations. * * NOTE: Not all back ends support nested/sub transactions */ int cmocka_unit_test_fail_add_internal_after = NO_FAILURE; #define CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL \ {\ cmocka_unit_test_fail_add_internal_after--;\ if (cmocka_unit_test_fail_add_internal_after <= 0) {\ assert_int_equal(LDB_SUCCESS, ret);\ ret = FAILURE_LDB_ERR;\ }\ }\ int cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; #define CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL \ {\ cmocka_unit_test_fail_delete_internal_after--;\ if (cmocka_unit_test_fail_delete_internal_after <= 0) {\ assert_int_equal(LDB_SUCCESS, ret);\ ret = FAILURE_LDB_ERR;\ }\ }\ int cmocka_unit_test_fail_rename_internal_after = NO_FAILURE; #define CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL \ {\ cmocka_unit_test_fail_rename_internal_after--;\ if (cmocka_unit_test_fail_rename_internal_after <= 0) {\ assert_int_equal(LDB_SUCCESS, ret);\ ret = FAILURE_LDB_ERR;\ }\ }\ int cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; #define CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL \ {\ cmocka_unit_test_fail_modify_internal_after--;\ if (cmocka_unit_test_fail_modify_internal_after <= 0) {\ assert_int_equal(LDB_SUCCESS, ret);\ ret = FAILURE_LDB_ERR;\ }\ }\ #include "ldb_key_value/ldb_kv.c" #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; }; /* * Remove the database files */ 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(); } } /* * Test setup */ static int noconn_setup(void **state) { struct test_ctx *test_ctx; cmocka_unit_test_fail_add_internal_after = NO_FAILURE; cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; cmocka_unit_test_fail_rename_internal_after = NO_FAILURE; cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; 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; } /* * Test teardown */ 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; } /* * Test setup */ 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; } /* * Test teardown */ 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; } /* * Build an ldb_kv_context that can be passed to the ldb_kv operation under test */ static struct ldb_kv_context* build_ldb_kv_context( TALLOC_CTX *ctx, struct ldb_module *module, struct ldb_request *req) { struct ldb_kv_context *ldb_kv_ctx = NULL; ldb_kv_ctx = talloc_zero(ctx, struct ldb_kv_context); assert_non_null(ldb_kv_ctx); ldb_kv_ctx->module = module; ldb_kv_ctx->req = req; return ldb_kv_ctx; } /* * Build an add request */ static struct ldb_request *build_add_request( TALLOC_CTX *ctx, struct ldb_context *ldb, const char* dc, const char* uuid, const char* cn) { int ret; struct ldb_message *msg; struct ldb_request *req; msg = ldb_msg_new(ctx); assert_non_null(msg); msg->dn = ldb_dn_new_fmt(msg, ldb, "dc=%s", dc); assert_non_null(msg->dn); ret = ldb_msg_add_string(msg, "cn", cn); assert_int_equal(ret, 0); ret = ldb_msg_add_string(msg, "objectUUID", uuid); assert_int_equal(ret, 0); ret = ldb_msg_sanity_check(ldb, msg); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_build_add_req( &req, ldb, ldb, msg, NULL, NULL, ldb_op_default_callback, NULL); assert_int_equal(ret, LDB_SUCCESS); return req; } /* * Build a delete request */ static struct ldb_request *build_delete_request( TALLOC_CTX *ctx, struct ldb_context *ldb, const char* dc) { int ret = LDB_SUCCESS; struct ldb_dn *dn = NULL; struct ldb_request *req = NULL; dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); assert_non_null(dn); ret = ldb_build_del_req( &req, ldb, ctx, dn, NULL, NULL, ldb_op_default_callback, NULL); assert_int_equal(ret, LDB_SUCCESS); return req; } /* * Build a rename request */ static struct ldb_request *build_rename_request( TALLOC_CTX *ctx, struct ldb_context *ldb, const char* old_dc, const char* new_dc) { int ret = LDB_SUCCESS; struct ldb_dn *old_dn = NULL; struct ldb_dn *new_dn = NULL; struct ldb_request *req = NULL; old_dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", old_dc); assert_non_null(old_dn); new_dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", new_dc); assert_non_null(new_dn); ret = ldb_build_rename_req( &req, ldb, ctx, old_dn, new_dn, NULL, NULL, ldb_op_default_callback, NULL); assert_int_equal(ret, LDB_SUCCESS); return req; } /* * Build a ldb modify request */ static struct ldb_request *build_modify_request( TALLOC_CTX *ctx, struct ldb_context *ldb, const char* dc, const char* cn) { int ret; struct ldb_message *msg; struct ldb_request *req; msg = ldb_msg_new(ctx); assert_non_null(msg); msg->dn = ldb_dn_new_fmt(msg, ldb, "dc=%s", dc); assert_non_null(msg->dn); ret = ldb_msg_add_empty(msg, "cn", LDB_FLAG_MOD_REPLACE, NULL); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg, "cn", cn); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_sanity_check(ldb, msg); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_build_mod_req( &req, ldb, ldb, msg, NULL, NULL, ldb_op_default_callback, NULL); assert_int_equal(ret, LDB_SUCCESS); return req; } /* * Delete a record from the database */ static void delete_record( TALLOC_CTX *ctx, struct ldb_context *ldb, const char* dc) { struct ldb_kv_context *ldb_kv_ctx = NULL; struct ldb_dn *basedn = NULL; struct ldb_result *result = NULL; struct ldb_request *req = NULL; int ret = LDB_SUCCESS; req = build_delete_request(ctx, ldb, dc); ldb_kv_ctx = build_ldb_kv_context(ctx, ldb->modules, req); ret = ldb_transaction_start(ldb); assert_int_equal(ret, LDB_SUCCESS); cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; ret = ldb_kv_delete(ldb_kv_ctx); assert_int_equal(ret, LDB_SUCCESS); TALLOC_FREE(ldb_kv_ctx); TALLOC_FREE(req); ret = ldb_transaction_commit(ldb); assert_int_equal(ret, LDB_SUCCESS); /* * Ensure that the record was actually deleted. */ basedn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); assert_non_null(basedn); /* * DN search, indexed */ ret = ldb_search(ldb, ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 0); TALLOC_FREE(basedn); TALLOC_FREE(result); } /* * Add a record to the database */ static void add_record( TALLOC_CTX *ctx, struct ldb_context *ldb, const char* dc, const char* uuid, const char* cn) { struct ldb_request *req = NULL; int ret = LDB_SUCCESS; struct ldb_kv_context *ldb_kv_ctx = NULL; struct ldb_dn *basedn = NULL; struct ldb_result *result = NULL; req = build_add_request(ctx, ldb, dc, uuid, cn); ldb_req_set_location(req, "add_record"); assert_int_equal(ret, LDB_SUCCESS); ldb_kv_ctx = build_ldb_kv_context(ctx, ldb->modules, req); cmocka_unit_test_fail_add_internal_after = NO_FAILURE; cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; ret = ldb_transaction_start(ldb); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_kv_add(ldb_kv_ctx); assert_int_equal(ret, LDB_SUCCESS); TALLOC_FREE(ldb_kv_ctx); TALLOC_FREE(req); ret = ldb_transaction_commit(ldb); assert_int_equal(ret, LDB_SUCCESS); /* * Ensure that the record was actually written. */ basedn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); assert_non_null(basedn); /* * DN search, indexed */ ret = ldb_search(ldb, ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 1); TALLOC_FREE(result); /* * CN search unindexed */ ret = ldb_search( ldb, ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "(cn=%s)", cn); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 1); TALLOC_FREE(result); TALLOC_FREE(basedn); } /* * Test that a failed add operation does not change the database. */ static void test_add_failure(void **state) { int ret = LDB_SUCCESS; struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); struct ldb_request *req = NULL; struct ldb_dn *basedn = NULL; struct ldb_result *result = NULL; struct ldb_kv_context *ldb_kv_ctx = NULL; TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); req = build_add_request( tmp_ctx, test_ctx->ldb, "test_add_failure", "0123456789abcdef", "test_add_failure_value"); ldb_req_set_location(req, "test_add_failure"); ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); cmocka_unit_test_fail_add_internal_after = 1; ret = ldb_transaction_start(test_ctx->ldb); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_kv_add(ldb_kv_ctx); assert_int_equal(ret, FAILURE_LDB_ERR); TALLOC_FREE(ldb_kv_ctx); TALLOC_FREE(req); /* * a search for "cn=test_add_failure_value" should fail * as the transaction containing the operation should have been * rolled back leaving the database consistent * * This should be an un-indexed search so the index caches won't be * used. */ basedn = ldb_dn_new_fmt( tmp_ctx, test_ctx->ldb, "dc=%s", "test_add_failure"); assert_non_null(basedn); ret = ldb_search( test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "(cn=%s)", "test_add_failure_value"); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 0); TALLOC_FREE(basedn); TALLOC_FREE(result); ldb_transaction_cancel(test_ctx->ldb); TALLOC_FREE(tmp_ctx); } /* * Test that a failed delete operation does not modify the database. */ static void test_delete_failure(void **state) { int ret = LDB_SUCCESS; struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); struct ldb_request *req = NULL; struct ldb_dn *basedn = NULL; struct ldb_result *result = NULL; struct ldb_kv_context *ldb_kv_ctx = NULL; TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); add_record( tmp_ctx, test_ctx->ldb, "test_delete_failure", "0123456789abcded", "test_delete_failure_value"); req = build_delete_request( tmp_ctx, test_ctx->ldb, "test_delete_failure"); ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); cmocka_unit_test_fail_delete_internal_after = 1; ret = ldb_transaction_start(test_ctx->ldb); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_kv_delete(ldb_kv_ctx); assert_int_equal(ret, FAILURE_LDB_ERR); TALLOC_FREE(ldb_kv_ctx); TALLOC_FREE(req); /* * a search for "cn=test_add_failure_value" should succeed * as the transaction containing the operation should have been * rolled back leaving the database consistent * * This should be an un-indexed search so the index caches won't be * used. */ basedn = ldb_dn_new_fmt( tmp_ctx, test_ctx->ldb, "dc=%s", "test_delete_failure"); assert_non_null(basedn); ret = ldb_search( test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "(cn=%s)", "test_delete_failure_value"); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 1); TALLOC_FREE(basedn); TALLOC_FREE(result); ldb_transaction_cancel(test_ctx->ldb); delete_record( tmp_ctx, test_ctx->ldb, "test_delete_failure"); TALLOC_FREE(tmp_ctx); } /* * Test that a failed rename operation dies not change the database */ static void test_rename_failure(void **state) { int ret = LDB_SUCCESS; struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); struct ldb_request *req = NULL; struct ldb_dn *basedn = NULL; struct ldb_result *result = NULL; struct ldb_kv_context *ldb_kv_ctx = NULL; TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); add_record( tmp_ctx, test_ctx->ldb, "test_rename_failure", "0123456789abcdec", "test_rename_failure_value"); req = build_rename_request( tmp_ctx, test_ctx->ldb, "test_rename_failure", "test_rename_failure_renamed"); ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); cmocka_unit_test_fail_rename_internal_after = 1; ret = ldb_transaction_start(test_ctx->ldb); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_kv_rename(ldb_kv_ctx); assert_int_equal(ret, FAILURE_LDB_ERR); TALLOC_FREE(ldb_kv_ctx); TALLOC_FREE(req); /* * The original record should be present */ basedn = ldb_dn_new_fmt( tmp_ctx, test_ctx->ldb, "dc=%s", "test_rename_failure"); assert_non_null(basedn); ret = ldb_search( test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "(cn=%s)", "test_rename_failure_value"); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 1); TALLOC_FREE(basedn); TALLOC_FREE(result); /* * And the renamed record should not be present */ basedn = ldb_dn_new_fmt( tmp_ctx, test_ctx->ldb, "dc=%s", "test_rename_failure_renamed"); assert_non_null(basedn); ret = ldb_search( test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "(cn=%s)", "test_rename_failure_value"); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 0); TALLOC_FREE(basedn); TALLOC_FREE(result); ldb_transaction_cancel(test_ctx->ldb); delete_record( tmp_ctx, test_ctx->ldb, "test_rename_failure"); TALLOC_FREE(tmp_ctx); } /* * Test that a failed modification operation does not change the database */ static void test_modify_failure(void **state) { int ret = LDB_SUCCESS; struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); struct ldb_request *req = NULL; struct ldb_dn *basedn = NULL; struct ldb_result *result = NULL; struct ldb_kv_context *ldb_kv_ctx = NULL; TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); add_record( tmp_ctx, test_ctx->ldb, "test_modify_failure", "0123456789abcdeb", "test_modify_failure_value"); req = build_modify_request( tmp_ctx, test_ctx->ldb, "test_modify_failure", "test_modify_failure_value_modified"); ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); cmocka_unit_test_fail_modify_internal_after = 2; ret = ldb_transaction_start(test_ctx->ldb); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_kv_modify(ldb_kv_ctx); assert_int_equal(ret, FAILURE_LDB_ERR); TALLOC_FREE(ldb_kv_ctx); TALLOC_FREE(req); /* * The original value should be present */ basedn = ldb_dn_new_fmt( tmp_ctx, test_ctx->ldb, "dc=%s", "test_modify_failure"); assert_non_null(basedn); ret = ldb_search( test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "(cn=%s)", "test_modify_failure_value"); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 1); TALLOC_FREE(result); /* * And the modified record should not be present */ ret = ldb_search( test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "(cn=%s)", "test_modify_failure_value_modified"); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 0); TALLOC_FREE(basedn); TALLOC_FREE(result); ldb_transaction_cancel(test_ctx->ldb); delete_record( tmp_ctx, test_ctx->ldb, "test_modify_failure"); TALLOC_FREE(tmp_ctx); } int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown( test_add_failure, setup, teardown), cmocka_unit_test_setup_teardown( test_delete_failure, setup, teardown), cmocka_unit_test_setup_teardown( test_rename_failure, setup, teardown), cmocka_unit_test_setup_teardown( test_modify_failure, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_key_value_test.c0000660000000000000000000002335013573675413017411 0ustar rootroot00000000000000/* * Tests exercising the ldb key value operations. * * Copyright (C) Andrew Bartlett 2019 * * 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 . * */ /* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. * */ /* * * Tests for the ldb key value layer */ #include #include #include #include #include #include #include #include #include #include #include #include "ldb_key_value/ldb_kv.c" #include "ldb_key_value/ldb_kv_index.c" #include "ldb_key_value/ldb_kv_search.c" #define DEFAULT_BE "tdb" #ifndef TEST_BE #define TEST_BE DEFAULT_BE #endif /* TEST_BE */ #define NUM_RECS 1024 int ldb_kv_cache_reload(struct ldb_module *module) { return LDB_SUCCESS; } int ldb_kv_cache_load(struct ldb_module *module) { return LDB_SUCCESS; } int ldb_kv_check_at_attributes_values(const struct ldb_val *value) { return LDB_SUCCESS; } int ldb_kv_increase_sequence_number(struct ldb_module *module) { return LDB_SUCCESS; } struct test_ctx { }; static int setup(void **state) { struct test_ctx *test_ctx; test_ctx = talloc_zero(NULL, struct test_ctx); *state = test_ctx; return 0; } static int teardown(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); talloc_free(test_ctx); return 0; } /* * Test that the index cache is opened by ldb_kv_index_transaction_start * and correctly initialised with the passed index cache size. */ static void test_index_cache_init(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort( *state, struct test_ctx); struct ldb_module *module = NULL; struct ldb_kv_private *ldb_kv = NULL; int ret = LDB_SUCCESS; module = talloc_zero(test_ctx, struct ldb_module); ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); ldb_module_set_private(module, ldb_kv); ret = ldb_kv_index_transaction_start(module, 191); assert_int_equal(LDB_SUCCESS, ret); assert_non_null(ldb_kv->idxptr); assert_non_null(ldb_kv->idxptr->itdb); assert_int_equal(191, tdb_hash_size(ldb_kv->idxptr->itdb)); TALLOC_FREE(ldb_kv); TALLOC_FREE(module); } static int mock_begin_write(struct ldb_kv_private* ldb_kv) { return LDB_SUCCESS; } static int mock_abort_write(struct ldb_kv_private* ldb_kv) { return LDB_SUCCESS; } /* * Test that the index cache is set to the default cache size at the start of * a transaction. */ static void test_default_index_cache_size(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort( *state, struct test_ctx); struct ldb_module *module = NULL; struct ldb_kv_private *ldb_kv = NULL; int ret = LDB_SUCCESS; const struct kv_db_ops ops = { .begin_write = mock_begin_write, .abort_write = mock_abort_write }; module = talloc_zero(test_ctx, struct ldb_module); ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); ldb_kv->pid = getpid(); ldb_kv->kv_ops = &ops; ldb_kv->index_transaction_cache_size = DEFAULT_INDEX_CACHE_SIZE; ldb_module_set_private(module, ldb_kv); ret = ldb_kv_start_trans(module); assert_int_equal(LDB_SUCCESS, ret); assert_int_equal( DEFAULT_INDEX_CACHE_SIZE, tdb_hash_size(ldb_kv->idxptr->itdb)); ret = ldb_kv_del_trans(module); assert_int_equal(LDB_SUCCESS, ret); TALLOC_FREE(ldb_kv); TALLOC_FREE(module); } static int db_size = 0; static size_t mock_get_size(struct ldb_kv_private *ldb_kv) { return db_size; } static int mock_iterate( struct ldb_kv_private *ldb_kv, ldb_kv_traverse_fn fn, void *ctx) { return 1; } /* * Test that the index cache is correctly sized by the re_index call */ static void test_reindex_cache_size(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort( *state, struct test_ctx); struct ldb_module *module = NULL; struct ldb_kv_private *ldb_kv = NULL; int ret = LDB_SUCCESS; const struct kv_db_ops ops = { .iterate = mock_iterate, .get_size = mock_get_size, }; module = talloc_zero(test_ctx, struct ldb_module); ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); ldb_kv->kv_ops = &ops; ldb_module_set_private(module, ldb_kv); /* * Use a value less than the DEFAULT_INDEX_CACHE_SIZE * Should get the DEFAULT_INDEX_CACHE_SIZE */ db_size = DEFAULT_INDEX_CACHE_SIZE - 1; ret = ldb_kv_reindex(module); assert_int_equal(LDB_SUCCESS, ret); assert_int_equal( DEFAULT_INDEX_CACHE_SIZE, tdb_hash_size(ldb_kv->idxptr->itdb)); /* * Use a value greater than the DEFAULT_INDEX_CACHE_SIZE * Should get the value specified. */ db_size = DEFAULT_INDEX_CACHE_SIZE + 1; ret = ldb_kv_reindex(module); assert_int_equal(LDB_SUCCESS, ret); assert_int_equal(db_size, tdb_hash_size(ldb_kv->idxptr->itdb)); TALLOC_FREE(ldb_kv); TALLOC_FREE(module); } /* * Test that ldb_kv_init_store sets the default index transaction cache size * if the option is not supplied. */ static void test_init_store_default_index_cache_size(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort( *state, struct test_ctx); struct ldb_module *module = NULL; struct ldb_kv_private *ldb_kv = NULL; struct ldb_context *ldb = NULL; int ret = LDB_SUCCESS; module = talloc_zero(test_ctx, struct ldb_module); ldb = talloc_zero(test_ctx, struct ldb_context); ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); ret = ldb_kv_init_store(ldb_kv, "test", ldb, NULL, &module); assert_int_equal(LDB_SUCCESS, ret); assert_int_equal( DEFAULT_INDEX_CACHE_SIZE, ldb_kv->index_transaction_cache_size); TALLOC_FREE(ldb_kv); TALLOC_FREE(module); TALLOC_FREE(ldb); } /* * Test that ldb_kv_init_store sets the index transaction cache size * to the value specified in the option. */ static void test_init_store_set_index_cache_size(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort( *state, struct test_ctx); struct ldb_module *module = NULL; struct ldb_kv_private *ldb_kv = NULL; struct ldb_context *ldb = NULL; const char *options[] = {"transaction_index_cache_size:1900", NULL}; int ret = LDB_SUCCESS; module = talloc_zero(test_ctx, struct ldb_module); ldb = talloc_zero(test_ctx, struct ldb_context); ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); assert_int_equal(LDB_SUCCESS, ret); assert_int_equal( 1900, ldb_kv->index_transaction_cache_size); TALLOC_FREE(ldb_kv); TALLOC_FREE(module); TALLOC_FREE(ldb); } /* * Test that ldb_kv_init_store sets the default index transaction cache size * if the value specified in the option is not a number. */ static void test_init_store_set_index_cache_size_non_numeric(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort( *state, struct test_ctx); struct ldb_module *module = NULL; struct ldb_kv_private *ldb_kv = NULL; struct ldb_context *ldb = NULL; const char *options[] = {"transaction_index_cache_size:fred", NULL}; int ret = LDB_SUCCESS; module = talloc_zero(test_ctx, struct ldb_module); ldb = talloc_zero(test_ctx, struct ldb_context); ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); assert_int_equal(LDB_SUCCESS, ret); assert_int_equal( DEFAULT_INDEX_CACHE_SIZE, ldb_kv->index_transaction_cache_size); TALLOC_FREE(ldb_kv); TALLOC_FREE(module); TALLOC_FREE(ldb); } /* * Test that ldb_kv_init_store sets the default index transaction cache size * if the value specified is too large */ static void test_init_store_set_index_cache_size_range(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort( *state, struct test_ctx); struct ldb_module *module = NULL; struct ldb_kv_private *ldb_kv = NULL; struct ldb_context *ldb = NULL; const char *options[] = { "transaction_index_cache_size:0xfffffffffffffffffffffffffffff", NULL}; int ret = LDB_SUCCESS; module = talloc_zero(test_ctx, struct ldb_module); ldb = talloc_zero(test_ctx, struct ldb_context); ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); assert_int_equal(LDB_SUCCESS, ret); assert_int_equal( DEFAULT_INDEX_CACHE_SIZE, ldb_kv->index_transaction_cache_size); TALLOC_FREE(ldb_kv); TALLOC_FREE(module); TALLOC_FREE(ldb); } int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown( test_index_cache_init, setup, teardown), cmocka_unit_test_setup_teardown( test_default_index_cache_size, setup, teardown), cmocka_unit_test_setup_teardown( test_reindex_cache_size, setup, teardown), cmocka_unit_test_setup_teardown( test_init_store_default_index_cache_size, setup, teardown), cmocka_unit_test_setup_teardown( test_init_store_set_index_cache_size, setup, teardown), cmocka_unit_test_setup_teardown( test_init_store_set_index_cache_size_non_numeric, setup, teardown), cmocka_unit_test_setup_teardown( test_init_store_set_index_cache_size_range, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_kv_ops_test.c0000660000000000000000000012044413573675413016730 0ustar rootroot00000000000000/* * Tests exercising the ldb key value operations. * * Copyright (C) Andrew Bartlett 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 . * */ /* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * 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. * - has a get_size implementation that returns an estimate of the number of * records in the database. Note that this can be an estimate rather than * an accurate size. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ldb_tdb/ldb_tdb.h" #include "ldb_key_value/ldb_kv.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 ldb_kv_private *get_ldb_kv(struct ldb_context *ldb) { void *data = NULL; struct ldb_kv_private *ldb_kv = NULL; data = ldb_module_get_private(ldb->modules); assert_non_null(data); ldb_kv = talloc_get_type(data, struct ldb_kv_private); assert_non_null(ldb_kv); return ldb_kv; } static int parse(struct ldb_val key, struct ldb_val data, void *private_data) { struct ldb_val* read = private_data; /* Yes, we leak this. That is OK */ read->data = talloc_size(NULL, data.length); assert_non_null(read->data); memcpy(read->data, data.data, data.length); read->length = data.length; return LDB_SUCCESS; } /* * Parse function that just returns the int we pass it. */ static int parse_return(struct ldb_val key, struct ldb_val data, void *private_data) { int *rcode = private_data; return *rcode; } /* * 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 ldb_kv_private *ldb_kv = get_ldb_kv(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 rcode; int flags = 0; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* * Begin a transaction */ ret = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the record */ ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); assert_int_equal(ret, 0); /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); /* * And now read it back */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, 0); assert_int_equal(sizeof(value), read.length); assert_memory_equal(value, read.data, sizeof(value)); /* * Now check that the error code we return in the * parse function is returned by fetch_and_parse. */ for (rcode=0; rcode<50; rcode++) { ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse_return, &rcode); assert_int_equal(ret, rcode); } ret = ldb_kv->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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the record */ ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); assert_int_equal(ret, 0); /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); /* * And now read it back * Note there is no read transaction active */ ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the record */ ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); assert_int_equal(ret, 0); /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); /* * And now read it back */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, 0); assert_int_equal(sizeof(value), read.length); assert_memory_equal(value, read.data, sizeof(value)); ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); /* * Begin a transaction */ ret = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Now delete it. */ ret = ldb_kv->kv_ops->delete (ldb_kv, key); assert_int_equal(ret, 0); /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); /* * And now try to read it back */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); ret = ldb_kv->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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the record */ ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); assert_int_equal(ret, 0); /* * And now read it back */ ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 = ldb_kv->kv_ops->abort_write(ldb_kv); assert_int_equal(ret, 0); /* * And now read it back, should not be there */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); ret = ldb_kv->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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the record */ ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); assert_int_equal(ret, 0); /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); /* * And now read it back */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, 0); assert_int_equal(sizeof(value), read.length); assert_memory_equal(value, read.data, sizeof(value)); ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); /* * Begin a transaction */ ret = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Now delete it. */ ret = ldb_kv->kv_ops->delete (ldb_kv, key); assert_int_equal(ret, 0); /* * And now read it back */ ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); /* * Abort the transaction */ ret = ldb_kv->kv_ops->abort_write(ldb_kv); assert_int_equal(ret, 0); /* * And now try to read it back */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, 0); assert_int_equal(sizeof(value), read.length); assert_memory_equal(value, read.data, sizeof(value)); ret = ldb_kv->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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->store(ldb_kv, 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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the record */ ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); assert_int_equal(ret, 0); /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); /* * And now read it back */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, 0); assert_int_equal(sizeof(value), read.length); assert_memory_equal(value, read.data, sizeof(value)); ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); /* * Now attempt to delete a record */ ret = ldb_kv->kv_ops->delete (ldb_kv, key); assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); /* * And now read it back */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); assert_int_equal(ret, 0); assert_int_equal(sizeof(value), read.length); assert_memory_equal(value, read.data, sizeof(value)); ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); talloc_free(tmp_ctx); } static int traverse_fn(struct ldb_kv_private *ldb_kv, 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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); 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 = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); assert_int_equal(ret, 0); TALLOC_FREE(key.data); TALLOC_FREE(rec.data); } /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); /* * Now iterate over the kv store and ensure that all the * records are visited. */ ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->iterate(ldb_kv, traverse_fn, visits); for (i = 0; i kv_ops->unlock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); TALLOC_FREE(tmp_ctx); } static void do_iterate_range_test(void **state, int range_start, int range_end, bool fail) { int ret; struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); int i; int num_recs = 1024; int skip_recs = 10; int visits[num_recs]; struct ldb_val sk, ek; TALLOC_CTX *tmp_ctx; for (i = 0; i < num_recs; i++){ visits[i] = 0; } /* * No iterate_range on tdb */ if (strcmp(TEST_BE, "tdb") == 0) { return; } tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* * Begin a transaction */ ret = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the records */ for (i = skip_recs; i <= num_recs - skip_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); rec.data = (uint8_t *)talloc_asprintf(tmp_ctx, "data for record (%04d)", i); rec.length = strlen((char *)rec.data) + 1; ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); assert_int_equal(ret, 0); TALLOC_FREE(key.data); TALLOC_FREE(rec.data); } /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); sk.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_start); sk.length = strlen((char *)sk.data); ek.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_end); ek.length = strlen((char *)ek.data) + 1; ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->iterate_range(ldb_kv, sk, ek, traverse_fn, visits); if (fail){ assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); TALLOC_FREE(tmp_ctx); return; } else{ assert_int_equal(ret, 0); } for (i = 0; i < num_recs; i++) { if (i >= skip_recs && i <= num_recs - skip_recs && i >= range_start && i <= range_end){ assert_int_equal(1, visits[i]); } else { assert_int_equal(0, visits[i]); } } ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); TALLOC_FREE(tmp_ctx); } /* * Test that iterate_range visits all the records between two keys. */ static void test_iterate_range(void **state) { do_iterate_range_test(state, 300, 900, false); /* * test start_key = end_key */ do_iterate_range_test(state, 20, 20, false); /* * test reverse range fails */ do_iterate_range_test(state, 50, 40, true); /* * keys are between 10-1014 so test with keys outside that range */ do_iterate_range_test(state, 0, 20, false); do_iterate_range_test(state, 1010, 1030, false); do_iterate_range_test(state, 0, 1030, false); } struct update_context { struct ldb_context* ldb; int visits[NUM_RECS]; }; static int update_fn(struct ldb_kv_private *ldb_kv, 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(ldb_kv); 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 = ldb_kv->kv_ops->update_in_iterate( ldb_kv, 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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); 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 = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); assert_int_equal(ret, 0); TALLOC_FREE(key.data); TALLOC_FREE(rec.data); } /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); 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 = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->iterate(ldb_kv, update_fn, context); for (i = 0; i < NUM_RECS; i++) { assert_int_equal(1, context->visits[i]); } ret = ldb_kv->kv_ops->finish_write(ldb_kv); 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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); 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 = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->finish_write(ldb_kv); 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); } ldb_kv = get_ldb_kv(ldb); ret = ldb_kv->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 = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 = ldb_kv->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 = ldb_kv->kv_ops->lock_read(ldb->modules); if (ret != LDB_SUCCESS) { print_error(__location__": lock_read returned (%d)\n", ret); exit(ret); } ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); if (ret != LDB_ERR_NO_SUCH_OBJECT) { print_error(__location__": fetch_and_parse returned " "(%d)\n", ret); exit(ret); } ret = ldb_kv->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 = ldb_kv->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 = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 = ldb_kv->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 = ldb_kv->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 = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 = ldb_kv->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 = ldb_kv->kv_ops->begin_write(ldb_kv); 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 = ldb_kv->kv_ops->store(ldb_kv, 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 = ldb_kv->kv_ops->finish_write(ldb_kv); 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 ldb_kv_private *ldb_kv = get_ldb_kv(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 = ldb_kv->kv_ops->begin_write(ldb_kv); 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 = ldb_kv->kv_ops->store(ldb_kv, 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 = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); assert_int_equal(ret, 0); ret = ldb_kv->kv_ops->finish_write(ldb_kv); 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); } ldb_kv = get_ldb_kv(ldb); ret = ldb_kv->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 = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 = ldb_kv->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 = ldb_kv->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 = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, 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 = ldb_kv->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 = ldb_kv->kv_ops->lock_read(ldb->modules); if (ret != LDB_SUCCESS) { print_error(__location__": lock_read returned (%d)\n", ret); exit(ret); } ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); if (ret != LDB_ERR_NO_SUCH_OBJECT) { print_error(__location__": fetch_and_parse returned " "(%d)\n", ret); exit(ret); } ret = ldb_kv->kv_ops->unlock_read(ldb->modules); if (ret != LDB_SUCCESS) { print_error(__location__": unlock_read returned (%d)\n", ret); exit(ret); } TALLOC_FREE(tmp_ctx); 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 = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); key.length = strlen(KEY2) + 1; ret = ldb_kv->kv_ops->delete (ldb_kv, 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 = ldb_kv->kv_ops->finish_write(ldb_kv); 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); } /* * Test that get_size returns a sensible estimate of the number of records * in the database. */ static void test_get_size(void **state) { int ret; struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); struct ldb_kv_private *ldb_kv = get_ldb_kv(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) }; size_t size = 0; int flags = 0; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); size = ldb_kv->kv_ops->get_size(ldb_kv); #if defined(TEST_LMDB) assert_int_equal(2, size); #else /* * The tdb implementation of get_size over estimates for sparse files * which is perfectly acceptable for it's intended use. */ assert_true( size > 2500); #endif /* * Begin a transaction */ ret = ldb_kv->kv_ops->begin_write(ldb_kv); assert_int_equal(ret, 0); /* * Write the record */ ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); assert_int_equal(ret, 0); /* * Commit the transaction */ ret = ldb_kv->kv_ops->finish_write(ldb_kv); assert_int_equal(ret, 0); size = ldb_kv->kv_ops->get_size(ldb_kv); #ifdef TEST_LMDB assert_int_equal(3, size); #endif 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_iterate_range, 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), cmocka_unit_test_setup_teardown( test_get_size, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_kv_ops_test.valgrind0000660000000000000000000000301413573675413020305 0ustar rootroot00000000000000{ Memory allocated by setup Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:setup } { Memory allocated by setup Memcheck:Leak match-leak-kinds: possible fun:realloc ... fun:setup } { Memory allocated by ldb_init Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_init } { Memory allocated by ldb_init Memcheck:Leak match-leak-kinds: possible fun:realloc ... fun:ldb_init } { Memory allocated by noconn_setup Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:noconn_setup } { Memory allocated by parse, which allocates on the NULL context Memcheck:Leak match-leak-kinds: all fun:malloc ... fun:parse } { Memory allocated by tdb_parse_data Memcheck:Leak match-leak-kinds: all fun:malloc ... fun:tdb_parse_data } { Memory allocated by ldb_connect Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_connect } { Memory allocated by ldb_connect Memcheck:Leak match-leak-kinds: possible fun:calloc ... fun:ldb_connect } { Memory allocated by ldb_kv_cache_load Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_kv_cache_load } { Memory allocated by ldb_kv_index_load Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_kv_index_load } { Memory allocated by ldb_asprintf_errstring Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_asprintf_errstring } ldb-2.0.8/tests/ldb_lmdb_size_test.c0000660000000000000000000001114613552036070017360 0ustar rootroot00000000000000/* * lmdb backend specific tests for ldb * Tests for truncated index keys * * Copyright (C) Andrew Bartlett 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 . * */ /* * 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 * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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); } ldb-2.0.8/tests/ldb_lmdb_test.c0000660000000000000000000003333213573675413016344 0ustar rootroot00000000000000/* * lmdb backend specific tests for ldb * * Copyright (C) Andrew Bartlett 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 . * */ /* * 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 * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../ldb_tdb/ldb_tdb.h" #include "../ldb_mdb/ldb_mdb.h" #include "../ldb_key_value/ldb_kv.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 ldb_kv_private *ldb_kv = NULL; struct lmdb_private *lmdb = NULL; struct MDB_env *env = NULL; data = ldb_module_get_private(ldb->modules); assert_non_null(data); ldb_kv = talloc_get_type(data, struct ldb_kv_private); assert_non_null(ldb_kv); lmdb = ldb_kv->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); } ldb-2.0.8/tests/ldb_match_test.c0000660000000000000000000001114413435160105016477 0ustar rootroot00000000000000/* * Tests exercising the ldb match operations. * * * Copyright (C) Catalyst.NET Ltd 2017 * * 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 . * */ /* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. */ #include #include #include #include #include #include "../common/ldb_match.c" #include "../include/ldb.h" struct ldbtest_ctx { struct tevent_context *ev; struct ldb_context *ldb; }; static int ldb_test_canonicalise( struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { out->length = in->length; out->data = in->data; return 0; } static int setup(void **state) { struct ldbtest_ctx *test_ctx; struct ldb_schema_syntax *syntax = NULL; int ret; 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); syntax = talloc_zero(test_ctx, struct ldb_schema_syntax); assert_non_null(syntax); syntax->canonicalise_fn = ldb_test_canonicalise; ret = ldb_schema_attribute_add_with_syntax( test_ctx->ldb, "a", LDB_ATTR_FLAG_FIXED, syntax); assert_int_equal(LDB_SUCCESS, ret); *state = test_ctx; return 0; } static int teardown(void **state) { talloc_free(*state); return 0; } /* * The wild card pattern "attribute=*" is parsed as an LDB_OP_PRESENT operation * rather than a LDB_OP_???? * * This test serves to document that behaviour, and to confirm that * ldb_wildcard_compare handles this case appropriately. */ static void test_wildcard_match_star(void **state) { struct ldbtest_ctx *ctx = *state; bool matched = false; int ret; uint8_t value[] = "The value.......end"; struct ldb_val val = { .data = value, .length = (sizeof(value)) }; struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*"); assert_non_null(tree); ret = ldb_wildcard_compare(ctx->ldb, tree, val, &matched); assert_false(matched); assert_int_equal(LDB_ERR_INAPPROPRIATE_MATCHING, ret); } /* * Test basic wild card matching * */ static void test_wildcard_match(void **state) { struct ldbtest_ctx *ctx = *state; bool matched = false; uint8_t value[] = "The value.......end"; struct ldb_val val = { .data = value, .length = (sizeof(value)) }; struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "objectClass=*end"); assert_non_null(tree); ldb_wildcard_compare(ctx->ldb, tree, val, &matched); assert_true(matched); } /* * ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0' * to the data, to make them safe to use the C string functions on. * * However testing for the trailing '\0' is not the correct way to test for * the end of a value, the length should be checked instead. */ static void test_wildcard_match_end_condition(void **state) { struct ldbtest_ctx *ctx = *state; bool matched = false; uint8_t value[] = "hellomynameisbobx"; struct ldb_val val = { .data = talloc_memdup(NULL, value, sizeof(value)), .length = (sizeof(value) - 2) }; struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*hello*mynameis*bob"); assert_non_null(tree); ldb_wildcard_compare(ctx->ldb, tree, val, &matched); assert_true(matched); } /* * Note: to run under valgrind use: * valgrind \ * --suppressions=lib/ldb/tests/ldb_match_test.valgrind \ * bin/ldb_match_test */ int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown( test_wildcard_match_star, setup, teardown), cmocka_unit_test_setup_teardown( test_wildcard_match, setup, teardown), cmocka_unit_test_setup_teardown( test_wildcard_match_end_condition, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_match_test.valgrind0000660000000000000000000000035313435160105020063 0ustar rootroot00000000000000{ Memory allocated in set-up Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:setup } { Memory allocated by ldb_init Memcheck:Leak match-leak-kinds: possible fun:malloc ... fun:ldb_init } ldb-2.0.8/tests/ldb_mod_op_test.c0000660000000000000000000035206113573675413016706 0ustar rootroot00000000000000/* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. */ #include #include #include #include #include #include #include #include #define TEVENT_DEPRECATED 1 #include #include #include #include #include #include #include #define DEFAULT_BE "tdb" #ifndef TEST_BE #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; 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 void test_connect(void **state) { struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); int ret; ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); assert_int_equal(ret, 0); } static struct ldb_message *get_test_ldb_message(TALLOC_CTX *mem_ctx, struct ldb_context *ldb) { struct ldb_message *msg = ldb_msg_new(mem_ctx); int ret; assert_non_null(msg); msg->dn = ldb_dn_new(msg, ldb, "dc=samba,dc=org"); assert_non_null(msg->dn); ret = ldb_msg_add_string(msg, "public", "key"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg, "supersecret", "password"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0"); assert_int_equal(ret, LDB_SUCCESS); return msg; } static void test_ldif_message(void **state) { struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); char *got_ldif; const char *expected_ldif = "dn: dc=samba,dc=org\n" "changetype: add\n" "public: key\n" "supersecret: password\n" "binary:: //8=\n" "\n"; struct ldb_message *msg = get_test_ldb_message(test_ctx, test_ctx->ldb); got_ldif = ldb_ldif_message_string(test_ctx->ldb, test_ctx, LDB_CHANGETYPE_ADD, msg); assert_string_equal(got_ldif, expected_ldif); TALLOC_FREE(got_ldif); } static void test_ldif_message_redacted(void **state) { struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); int ret; char *got_ldif; const char *expected_ldif = "dn: dc=samba,dc=org\n" "changetype: add\n" "public: key\n" "# supersecret::: REDACTED SECRET ATTRIBUTE\n" "binary:: //8=\n" "\n"; const char *secret_attrs[] = { "supersecret", NULL }; struct ldb_message *msg = ldb_msg_new(test_ctx); ldb_set_opaque(test_ctx->ldb, LDB_SECRET_ATTRIBUTE_LIST_OPAQUE, secret_attrs); assert_non_null(msg); msg->dn = ldb_dn_new(msg, test_ctx->ldb, "dc=samba,dc=org"); ret = ldb_msg_add_string(msg, "public", "key"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg, "supersecret", "password"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0"); assert_int_equal(ret, LDB_SUCCESS); got_ldif = ldb_ldif_message_redacted_string(test_ctx->ldb, test_ctx, LDB_CHANGETYPE_ADD, msg); assert_string_equal(got_ldif, expected_ldif); TALLOC_FREE(got_ldif); assert_int_equal(ret, 0); } 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); 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(void **state) { int ret; struct ldb_message *msg; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); 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); msg->dn = ldb_dn_new_fmt(msg, test_ctx->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", "0123456789abcdef"); assert_int_equal(ret, 0); ret = ldb_add(test_ctx->ldb, msg); assert_int_equal(ret, 0); talloc_free(tmp_ctx); } static void test_ldb_search(void **state) { int ret; struct ldb_message *msg; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; struct ldb_dn *basedn2; struct ldb_result *result = NULL; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); assert_non_null(basedn); ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, 0); assert_non_null(result); assert_int_equal(result->count, 0); msg = ldb_msg_new(tmp_ctx); assert_non_null(msg); msg->dn = basedn; assert_non_null(msg->dn); 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); basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2"); assert_non_null(basedn2); msg = ldb_msg_new(tmp_ctx); assert_non_null(msg); msg->dn = basedn2; assert_non_null(msg->dn); 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); ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, 0); assert_non_null(result); assert_int_equal(result->count, 1); assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), ldb_dn_get_linearized(basedn)); ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, 0); assert_non_null(result); assert_int_equal(result->count, 1); assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), ldb_dn_get_linearized(basedn2)); talloc_free(tmp_ctx); } static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; struct ldb_result *result = NULL; int ret; int count; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn); assert_non_null(basedn); ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); count = result->count; talloc_free(tmp_ctx); return count; } static int sub_search_count(struct ldbtest_ctx *test_ctx, const char *base_dn, const char *filter) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; struct ldb_result *result = NULL; int ret; int count; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn); assert_non_null(basedn); ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "%s", filter); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); count = result->count; talloc_free(tmp_ctx); return count; } /* In general it would be better if utility test functions didn't assert * but only returned a value, then assert in the test shows correct * line */ static void assert_dn_exists(struct ldbtest_ctx *test_ctx, const char *entry_dn) { int count; count = base_search_count(test_ctx, entry_dn); assert_int_equal(count, 1); } static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx, const char *entry_dn) { int count; count = base_search_count(test_ctx, entry_dn); assert_int_equal(count, 0); } static void add_dn_with_cn(struct ldbtest_ctx *test_ctx, struct ldb_dn *dn, const char *cn_value, const char *uuid_value) { int ret; TALLOC_CTX *tmp_ctx; struct ldb_message *msg; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); assert_dn_doesnt_exist(test_ctx, ldb_dn_get_linearized(dn)); msg = ldb_msg_new(tmp_ctx); assert_non_null(msg); msg->dn = dn; 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); assert_dn_exists(test_ctx, ldb_dn_get_linearized(dn)); talloc_free(tmp_ctx); } static void test_ldb_del(void **state) { int ret; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); const char *basedn = "dc=ldb_del_test"; struct ldb_dn *dn; 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"); ret = ldb_delete(test_ctx->ldb, dn); assert_int_equal(ret, LDB_SUCCESS); assert_dn_doesnt_exist(test_ctx, basedn); } static void test_ldb_del_noexist(void **state) { struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_dn *basedn; int ret; basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace"); assert_non_null(basedn); ret = ldb_delete(test_ctx->ldb, basedn); assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); } static void test_ldb_handle(void **state) { int ret; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; struct ldb_request *request = NULL; struct ldb_request *request2 = NULL; struct ldb_result *res = NULL; const char *attrs[] = { "cn", NULL }; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); assert_non_null(basedn); res = talloc_zero(tmp_ctx, struct ldb_result); assert_non_null(res); ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx, basedn, LDB_SCOPE_BASE, NULL, attrs, NULL, res, ldb_search_default_callback, NULL); assert_int_equal(ret, 0); /* We are against ldb_tdb, so expect private event contexts */ assert_ptr_not_equal(ldb_handle_get_event_context(request->handle), ldb_get_event_context(test_ctx->ldb)); ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx, basedn, LDB_SCOPE_BASE, NULL, attrs, NULL, res, ldb_search_default_callback, request); assert_int_equal(ret, 0); /* Expect that same event context will be chained */ assert_ptr_equal(ldb_handle_get_event_context(request->handle), ldb_handle_get_event_context(request2->handle)); /* Now force this to use the global context */ ldb_handle_use_global_event_context(request2->handle); assert_ptr_equal(ldb_handle_get_event_context(request2->handle), ldb_get_event_context(test_ctx->ldb)); talloc_free(tmp_ctx); } static void test_ldb_build_search_req(void **state) { int ret; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; struct ldb_request *request = NULL; struct ldb_request *request2 = NULL; struct ldb_result *res = NULL; const char *attrs[] = { "cn", NULL }; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); assert_non_null(basedn); res = talloc_zero(tmp_ctx, struct ldb_result); assert_non_null(res); ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx, basedn, LDB_SCOPE_BASE, NULL, attrs, NULL, res, ldb_search_default_callback, NULL); assert_int_equal(ret, 0); assert_int_equal(request->operation, LDB_SEARCH); assert_ptr_equal(request->op.search.base, basedn); assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE); assert_non_null(request->op.search.tree); assert_ptr_equal(request->op.search.attrs, attrs); assert_ptr_equal(request->context, res); assert_ptr_equal(request->callback, ldb_search_default_callback); ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx, basedn, LDB_SCOPE_BASE, NULL, attrs, NULL, res, ldb_search_default_callback, request); assert_int_equal(ret, 0); assert_ptr_equal(request, request2->handle->parent); assert_int_equal(request->starttime, request2->starttime); assert_int_equal(request->timeout, request2->timeout); talloc_free(tmp_ctx); } static void add_keyval(struct ldbtest_ctx *test_ctx, const char *key, const char *val, const char *uuid) { int ret; struct ldb_message *msg; msg = ldb_msg_new(test_ctx); assert_non_null(msg); msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val); assert_non_null(msg->dn); 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); talloc_free(msg); } static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx, const char *key, const char *val) { int ret; struct ldb_result *result; struct ldb_dn *basedn; basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val); assert_non_null(basedn); ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, 0); return result; } static void test_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"); /* commit lev-0 transaction */ ret = ldb_transaction_commit(test_ctx->ldb); assert_int_equal(ret, 0); /* 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); res = get_keyval(test_ctx, "vegetable", "carrot"); assert_non_null(res); assert_int_equal(res->count, 1); res = get_keyval(test_ctx, "fruit", "apple"); assert_non_null(res); 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; }; struct keyval { const char *key; const char *val; }; static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx, struct ldbtest_ctx *test_ctx, const char *dn, int modify_flags, struct keyval *kvs) { struct ldb_message *msg; int ret; int i; msg = ldb_msg_new(mem_ctx); assert_non_null(msg); msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn); assert_non_null(msg->dn); for (i = 0; kvs[i].key != NULL; i++) { if (modify_flags) { ret = ldb_msg_add_empty(msg, kvs[i].key, modify_flags, NULL); assert_int_equal(ret, 0); } if (kvs[i].val) { ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val); assert_int_equal(ret, LDB_SUCCESS); } } return msg; } static void ldb_test_add_data(TALLOC_CTX *mem_ctx, struct ldbtest_ctx *ldb_test_ctx, const char *basedn, struct keyval *kvs) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_result *result = NULL; int ret; tmp_ctx = talloc_new(mem_ctx); assert_non_null(tmp_ctx); msg = build_mod_msg(tmp_ctx, ldb_test_ctx, basedn, 0, kvs); assert_non_null(msg); ret = ldb_add(ldb_test_ctx->ldb, msg); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(result); assert_int_equal(result->count, 1); assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), ldb_dn_get_linearized(msg->dn)); talloc_free(tmp_ctx); } static void ldb_test_remove_data(TALLOC_CTX *mem_ctx, struct ldbtest_ctx *ldb_test_ctx, const char *strdn) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; int ret; size_t count; tmp_ctx = talloc_new(mem_ctx); assert_non_null(tmp_ctx); basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb, "%s", strdn); assert_non_null(basedn); ret = ldb_delete(ldb_test_ctx->ldb, basedn); assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT); count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn)); assert_int_equal(count, 0); talloc_free(tmp_ctx); } static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx, struct keyval *kvs) { ldb_test_add_data(mod_test_ctx, mod_test_ctx->ldb_test_ctx, mod_test_ctx->entry_dn, kvs); } static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx) { ldb_test_remove_data(mod_test_ctx, mod_test_ctx->ldb_test_ctx, mod_test_ctx->entry_dn); } static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx, int modify_flags, struct keyval *kvs) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_message *mod_msg; struct ldb_dn *basedn; struct ldbtest_ctx *ldb_test_ctx; int ret; ldb_test_ctx = mod_test_ctx->ldb_test_ctx; tmp_ctx = talloc_new(mod_test_ctx); assert_non_null(tmp_ctx); mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn, modify_flags, kvs); assert_non_null(mod_msg); ret = ldb_modify(ldb_test_ctx->ldb, mod_msg); assert_int_equal(ret, LDB_SUCCESS); basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb, "%s", mod_test_ctx->entry_dn); assert_non_null(basedn); ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(res); assert_int_equal(res->count, 1); assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn), ldb_dn_get_linearized(mod_msg->dn)); talloc_free(tmp_ctx); return res; } static int ldb_modify_test_setup(void **state) { struct ldbtest_ctx *ldb_test_ctx; struct ldb_mod_test_ctx *mod_test_ctx; struct keyval kvs[] = { { "cn", "test_mod_cn" }, { "objectUUID", "0123456789abcdef"}, { NULL, NULL }, }; ldbtest_setup((void **) &ldb_test_ctx); mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx); assert_non_null(mod_test_ctx); mod_test_ctx->entry_dn = "dc=mod_test_entry"; mod_test_ctx->ldb_test_ctx = ldb_test_ctx; mod_test_remove_data(mod_test_ctx); mod_test_add_data(mod_test_ctx, kvs); *state = mod_test_ctx; return 0; } static int ldb_modify_test_teardown(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct ldbtest_ctx *ldb_test_ctx; ldb_test_ctx = mod_test_ctx->ldb_test_ctx; mod_test_remove_data(mod_test_ctx); talloc_free(mod_test_ctx); ldbtest_teardown((void **) &ldb_test_ctx); return 0; } static void test_ldb_modify_add_key(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct keyval mod_kvs[] = { { "name", "test_mod_name" }, { NULL, NULL }, }; struct ldb_result *res; struct ldb_message_element *el; res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs); assert_non_null(res); /* Check cn is intact and name was added */ assert_int_equal(res->count, 1); el = ldb_msg_find_element(res->msgs[0], "cn"); assert_non_null(el); assert_int_equal(el->num_values, 1); assert_string_equal(el->values[0].data, "test_mod_cn"); el = ldb_msg_find_element(res->msgs[0], "name"); assert_non_null(el); assert_int_equal(el->num_values, 1); assert_string_equal(el->values[0].data, "test_mod_name"); } static void test_ldb_modify_extend_key(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct keyval mod_kvs[] = { { "cn", "test_mod_cn2" }, { NULL, NULL }, }; struct ldb_result *res; struct ldb_message_element *el; res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs); assert_non_null(res); /* Check cn was extended with another value */ assert_int_equal(res->count, 1); el = ldb_msg_find_element(res->msgs[0], "cn"); assert_non_null(el); assert_int_equal(el->num_values, 2); assert_string_equal(el->values[0].data, "test_mod_cn"); assert_string_equal(el->values[1].data, "test_mod_cn2"); } static void test_ldb_modify_add_key_noval(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct ldb_message *mod_msg; struct ldbtest_ctx *ldb_test_ctx; struct ldb_message_element *el; int ret; ldb_test_ctx = mod_test_ctx->ldb_test_ctx; mod_msg = ldb_msg_new(mod_test_ctx); assert_non_null(mod_msg); mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb, "%s", mod_test_ctx->entry_dn); assert_non_null(mod_msg->dn); el = talloc_zero(mod_msg, struct ldb_message_element); el->flags = LDB_FLAG_MOD_ADD; assert_non_null(el); el->name = talloc_strdup(el, "cn"); assert_non_null(el->name); mod_msg->elements = el; mod_msg->num_elements = 1; ret = ldb_modify(ldb_test_ctx->ldb, mod_msg); assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); } static void test_ldb_modify_replace_key(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); const char *new_cn = "new_cn"; struct keyval mod_kvs[] = { { "cn", new_cn }, { NULL, NULL }, }; struct ldb_result *res; struct ldb_message_element *el; res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs); assert_non_null(res); /* Check cn was replaced */ assert_int_equal(res->count, 1); el = ldb_msg_find_element(res->msgs[0], "cn"); assert_non_null(el); assert_int_equal(el->num_values, 1); assert_string_equal(el->values[0].data, new_cn); } static void test_ldb_modify_replace_noexist_key(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct keyval mod_kvs[] = { { "name", "name_val" }, { NULL, NULL }, }; struct ldb_result *res; struct ldb_message_element *el; res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs); assert_non_null(res); /* Check cn is intact and name was added */ assert_int_equal(res->count, 1); el = ldb_msg_find_element(res->msgs[0], "cn"); assert_non_null(el); assert_int_equal(el->num_values, 1); assert_string_equal(el->values[0].data, "test_mod_cn"); el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key); assert_non_null(el); assert_int_equal(el->num_values, 1); assert_string_equal(el->values[0].data, mod_kvs[0].val); } static void test_ldb_modify_replace_zero_vals(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct ldb_message_element *el; struct ldb_result *res; struct keyval kvs[] = { { "cn", NULL }, { NULL, NULL }, }; /* cn must be gone */ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs); assert_non_null(res); el = ldb_msg_find_element(res->msgs[0], "cn"); assert_null(el); } static void test_ldb_modify_replace_noexist_key_zero_vals(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct ldb_message_element *el; struct ldb_result *res; struct keyval kvs[] = { { "noexist_key", NULL }, { NULL, NULL }, }; /* cn must be gone */ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs); assert_non_null(res); /* cn should be intact */ el = ldb_msg_find_element(res->msgs[0], "cn"); assert_non_null(el); } static void test_ldb_modify_del_key(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct ldb_message_element *el; struct ldb_result *res; struct keyval kvs[] = { { "cn", NULL }, { NULL, NULL }, }; /* cn must be gone */ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs); assert_non_null(res); el = ldb_msg_find_element(res->msgs[0], "cn"); assert_null(el); } static void test_ldb_modify_del_keyval(void **state) { struct ldb_mod_test_ctx *mod_test_ctx = \ talloc_get_type_abort(*state, struct ldb_mod_test_ctx); struct ldb_message_element *el; struct ldb_result *res; struct keyval kvs[] = { { "cn", "test_mod_cn" }, { NULL, NULL }, }; /* cn must be gone */ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs); assert_non_null(res); el = ldb_msg_find_element(res->msgs[0], "cn"); assert_null(el); } struct search_test_ctx { struct ldbtest_ctx *ldb_test_ctx; const char *base_dn; }; static char *get_full_dn(TALLOC_CTX *mem_ctx, struct search_test_ctx *search_test_ctx, const char *rdn) { char *full_dn; full_dn = talloc_asprintf(mem_ctx, "%s,%s", rdn, search_test_ctx->base_dn); assert_non_null(full_dn); return full_dn; } static void search_test_add_data(struct search_test_ctx *search_test_ctx, const char *rdn, struct keyval *kvs) { char *full_dn; full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn); ldb_test_add_data(search_test_ctx, search_test_ctx->ldb_test_ctx, full_dn, kvs); } static void search_test_remove_data(struct search_test_ctx *search_test_ctx, const char *rdn) { char *full_dn; full_dn = talloc_asprintf(search_test_ctx, "%s,%s", rdn, search_test_ctx->base_dn); assert_non_null(full_dn); ldb_test_remove_data(search_test_ctx, search_test_ctx->ldb_test_ctx, full_dn); } static int ldb_search_test_setup(void **state) { struct ldbtest_ctx *ldb_test_ctx; struct search_test_ctx *search_test_ctx; struct keyval kvs[] = { { "cn", "test_search_cn" }, { "cn", "test_search_cn2" }, { "uid", "test_search_uid" }, { "uid", "test_search_uid2" }, { "objectUUID", "0123456789abcde0"}, { NULL, NULL }, }; struct keyval kvs2[] = { { "cn", "test_search_2_cn" }, { "cn", "test_search_2_cn2" }, { "uid", "test_search_2_uid" }, { "uid", "test_search_2_uid2" }, { "objectUUID", "0123456789abcde1"}, { NULL, NULL }, }; ldbtest_setup((void **) &ldb_test_ctx); search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx); assert_non_null(search_test_ctx); search_test_ctx->base_dn = "dc=search_test_entry"; search_test_ctx->ldb_test_ctx = ldb_test_ctx; search_test_remove_data(search_test_ctx, "cn=test_search_cn"); search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs); search_test_remove_data(search_test_ctx, "cn=test_search_2_cn"); search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2); *state = search_test_ctx; return 0; } static int ldb_search_test_teardown(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); struct ldbtest_ctx *ldb_test_ctx; ldb_test_ctx = search_test_ctx->ldb_test_ctx; search_test_remove_data(search_test_ctx, "cn=test_search_cn"); search_test_remove_data(search_test_ctx, "cn=test_search_2_cn"); ldbtest_teardown((void **) &ldb_test_ctx); return 0; } static void assert_attr_has_vals(struct ldb_message *msg, const char *attr, const char *vals[], const size_t nvals) { struct ldb_message_element *el; size_t i; el = ldb_msg_find_element(msg, attr); assert_non_null(el); assert_int_equal(el->num_values, nvals); for (i = 0; i < nvals; i++) { assert_string_equal(el->values[i].data, vals[i]); } } static void assert_has_no_attr(struct ldb_message *msg, const char *attr) { struct ldb_message_element *el; el = ldb_msg_find_element(msg, attr); assert_null(el); } static bool has_dn(struct ldb_message *msg, const char *dn) { const char *msgdn; msgdn = ldb_dn_get_linearized(msg->dn); if (strcmp(dn, msgdn) == 0) { return true; } return false; } static void test_search_match_none(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); size_t count; count = base_search_count(search_test_ctx->ldb_test_ctx, "dc=no_such_entry"); assert_int_equal(count, 0); } static void test_search_match_one(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); int ret; struct ldb_dn *basedn; struct ldb_result *result = NULL; const char *cn_vals[] = { "test_search_cn", "test_search_cn2" }; const char *uid_vals[] = { "test_search_uid", "test_search_uid2" }; basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(basedn); ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "cn=test_search_cn"); assert_int_equal(ret, 0); assert_non_null(result); assert_int_equal(result->count, 1); assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2); assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2); } static void test_search_match_filter(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); int ret; struct ldb_dn *basedn; struct ldb_result *result = NULL; const char *cn_vals[] = { "test_search_cn", "test_search_cn2" }; const char *attrs[] = { "cn", NULL }; basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(basedn); ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &result, basedn, LDB_SCOPE_SUBTREE, attrs, "cn=test_search_cn"); assert_int_equal(ret, 0); assert_non_null(result); assert_int_equal(result->count, 1); assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2); assert_has_no_attr(result->msgs[0], "uid"); } static void assert_expected(struct search_test_ctx *search_test_ctx, struct ldb_message *msg) { char *full_dn1; char *full_dn2; const char *cn_vals[] = { "test_search_cn", "test_search_cn2" }; const char *uid_vals[] = { "test_search_uid", "test_search_uid2" }; const char *cn2_vals[] = { "test_search_2_cn", "test_search_2_cn2" }; const char *uid2_vals[] = { "test_search_2_uid", "test_search_2_uid2" }; full_dn1 = get_full_dn(search_test_ctx, search_test_ctx, "cn=test_search_cn"); full_dn2 = get_full_dn(search_test_ctx, search_test_ctx, "cn=test_search_2_cn"); if (has_dn(msg, full_dn1) == true) { assert_attr_has_vals(msg, "cn", cn_vals, 2); assert_attr_has_vals(msg, "uid", uid_vals, 2); } else if (has_dn(msg, full_dn2) == true) { assert_attr_has_vals(msg, "cn", cn2_vals, 2); assert_attr_has_vals(msg, "uid", uid2_vals, 2); } else { fail(); } } static void test_search_match_both(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); int ret; struct ldb_dn *basedn; struct ldb_result *result = NULL; basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(basedn); ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "cn=test_search_*"); assert_int_equal(ret, 0); assert_non_null(result); assert_int_equal(result->count, 2); assert_expected(search_test_ctx, result->msgs[0]); assert_expected(search_test_ctx, result->msgs[1]); } static void test_search_match_basedn(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); int ret; struct ldb_dn *basedn; struct ldb_result *result = NULL; struct ldb_message *msg; basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "dc=nosuchdn"); assert_non_null(basedn); ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "cn=*"); assert_int_equal(ret, 0); /* Add 'checkBaseOnSearch' to @OPTIONS */ msg = ldb_msg_new(search_test_ctx); assert_non_null(msg); msg->dn = ldb_dn_new_fmt(msg, search_test_ctx->ldb_test_ctx->ldb, "@OPTIONS"); assert_non_null(msg->dn); ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE"); assert_int_equal(ret, 0); ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg); assert_int_equal(ret, 0); /* Search again */ /* The search should return LDB_ERR_NO_SUCH_OBJECT */ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &result, basedn, LDB_SCOPE_SUBTREE, NULL, "cn=*"); assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn); assert_int_equal(ret, 0); } /* * This test is complex. * The purpose is to test for a deadlock detected between ldb_search() * and ldb_transaction_commit(). The deadlock happens if in process * (1) and (2): * - (1) the all-record lock is taken in ltdb_search() * - (2) the ldb_transaction_start() call is made * - (1) an un-indexed search starts (forced here by doing it in * the callback * - (2) the ldb_transaction_commit() is called. * This returns LDB_ERR_BUSY if the deadlock is detected * * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing * lock call in ltdb_search() due to a refcounting bug in * ltdb_lock_read() */ struct search_against_transaction_ctx { struct ldbtest_ctx *test_ctx; int res_count; pid_t child_pid; struct ldb_dn *basedn; }; static int test_ldb_search_against_transaction_callback2(struct ldb_request *req, struct ldb_reply *ares) { struct search_against_transaction_ctx *ctx = req->context; switch (ares->type) { case LDB_REPLY_ENTRY: ctx->res_count++; if (ctx->res_count != 1) { return LDB_SUCCESS; } break; case LDB_REPLY_REFERRAL: break; case LDB_REPLY_DONE: return ldb_request_done(req, LDB_SUCCESS); } return 0; } /* * This purpose of this callback is to trigger a transaction in * the child process while the all-record lock is held, but before * we take any locks in the tdb_traverse_read() handler. * * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock * however in ldb 1.1.31 ltdb_search() forgets to take the all-record * lock (except the very first time) due to a ref-counting bug. * */ static int test_ldb_search_against_transaction_callback1(struct ldb_request *req, struct ldb_reply *ares) { int ret, ret2; int pipes[2]; char buf[2]; struct search_against_transaction_ctx *ctx = req->context; 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); } ret = pipe(pipes); assert_int_equal(ret, 0); ctx->child_pid = fork(); if (ctx->child_pid == 0) { TALLOC_CTX *tmp_ctx = NULL; 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); } ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, ctx->test_ctx->ev); if (ctx->test_ctx->ldb == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_connect(ctx->test_ctx->ldb, ctx->test_ctx->dbpath, 0, NULL); if (ret != LDB_SUCCESS) { exit(ret); } tmp_ctx = talloc_new(ctx->test_ctx); if (tmp_ctx == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, "dc=test"); if (msg->dn == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); if (ret != 0) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_transaction_start(ctx->test_ctx->ldb); if (ret != 0) { exit(ret); } ret = write(pipes[1], "GO", 2); if (ret != 2) { 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); } ret = ldb_transaction_commit(ctx->test_ctx->ldb); exit(ret); } close(pipes[1]); ret = read(pipes[0], buf, 2); assert_int_equal(ret, 2); /* This search must be unindexed (ie traverse in tdb) */ ret = ldb_build_search_req(&req, ctx->test_ctx->ldb, ctx->test_ctx, ctx->basedn, LDB_SCOPE_SUBTREE, "cn=*", NULL, NULL, ctx, test_ldb_search_against_transaction_callback2, NULL); /* * we don't assert on these return codes until after the search is * finished, or the clean up will fail because we hold locks. */ ret2 = ldb_request(ctx->test_ctx->ldb, req); if (ret2 == LDB_SUCCESS) { ret2 = ldb_wait(req->handle, LDB_WAIT_ALL); } assert_int_equal(ret, 0); assert_int_equal(ret2, 0); assert_int_equal(ctx->res_count, 2); return LDB_SUCCESS; } static void test_ldb_search_against_transaction(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); struct search_against_transaction_ctx ctx = { .res_count = 0, .test_ctx = search_test_ctx->ldb_test_ctx }; int ret; struct ldb_request *req; pid_t pid; int wstatus; struct ldb_dn *base_search_dn; tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); base_search_dn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "cn=test_search_cn,%s", search_test_ctx->base_dn); assert_non_null(base_search_dn); ctx.basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(ctx.basedn); /* This search must be indexed (ie no traverse in tdb) */ ret = ldb_build_search_req(&req, search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, base_search_dn, LDB_SCOPE_BASE, "cn=*", NULL, NULL, &ctx, test_ldb_search_against_transaction_callback1, NULL); assert_int_equal(ret, 0); ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } assert_int_equal(ret, 0); assert_int_equal(ctx.res_count, 2); pid = waitpid(ctx.child_pid, &wstatus, 0); assert_int_equal(pid, ctx.child_pid); assert_true(WIFEXITED(wstatus)); assert_int_equal(WEXITSTATUS(wstatus), 0); } /* * This test is also complex. * The purpose is to test if a modify can occur during an ldb_search() * This would be a failure if if in process * (1) and (2): * - (1) ltdb_search() starts and calls back for one entry * - (2) one of the entries to be matched is modified * - (1) the indexed search tries to return the modified entry, but * it is no longer found, either: * - despite it still matching (dn changed) * - it no longer matching (attrs changed) * * We also try un-indexed to show that the behaviour differs on this * point, which it should not (an index should only impact search * speed). */ struct modify_during_search_test_ctx { struct ldbtest_ctx *test_ctx; int res_count; pid_t child_pid; struct ldb_dn *basedn; bool got_cn; bool got_2_cn; bool rename; }; /* * This purpose of this callback is to trigger a write in * the child process while a search is in progress. * * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock * however in ldb 1.1.31 ltdb_search() forgets to take the all-record * lock (except the very first time) due to a ref-counting bug. * * We assume that if the write will proceed, it will proceed in a 3 * second window after the function is called. */ static int test_ldb_modify_during_search_callback1(struct ldb_request *req, struct ldb_reply *ares) { int ret; int pipes[2]; char buf[2]; struct modify_during_search_test_ctx *ctx = req->context; switch (ares->type) { case LDB_REPLY_ENTRY: { const struct ldb_val *cn_val = ldb_dn_get_component_val(ares->message->dn, 0); const char *cn = (char *)cn_val->data; ctx->res_count++; if (strcmp(cn, "test_search_cn") == 0) { ctx->got_cn = true; } else if (strcmp(cn, "test_search_2_cn") == 0) { ctx->got_2_cn = true; } if (ctx->res_count == 2) { return LDB_SUCCESS; } break; } case LDB_REPLY_REFERRAL: return LDB_SUCCESS; case LDB_REPLY_DONE: return ldb_request_done(req, LDB_SUCCESS); } ret = pipe(pipes); assert_int_equal(ret, 0); ctx->child_pid = fork(); if (ctx->child_pid == 0 && ctx->rename) { TALLOC_CTX *tmp_ctx = NULL; 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); } ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, ctx->test_ctx->ev); if (ctx->test_ctx->ldb == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_connect(ctx->test_ctx->ldb, ctx->test_ctx->dbpath, 0, NULL); if (ret != LDB_SUCCESS) { exit(ret); } tmp_ctx = talloc_new(ctx->test_ctx); if (tmp_ctx == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } if (ctx->got_cn) { /* Modify the other one */ dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_2_cn," "dc=search_test_entry"); } else { dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_cn," "dc=search_test_entry"); } if (dn == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_cn_renamed," "dc=search_test_entry"); if (new_dn == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_transaction_start(ctx->test_ctx->ldb); if (ret != 0) { exit(ret); } if (write(pipes[1], "GO", 2) != 2) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn); if (ret != 0) { exit(ret); } ret = ldb_transaction_commit(ctx->test_ctx->ldb); exit(ret); } else if (ctx->child_pid == 0) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_message *msg; 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); } ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, ctx->test_ctx->ev); if (ctx->test_ctx->ldb == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_connect(ctx->test_ctx->ldb, ctx->test_ctx->dbpath, 0, NULL); if (ret != LDB_SUCCESS) { exit(ret); } tmp_ctx = talloc_new(ctx->test_ctx); if (tmp_ctx == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } if (ctx->got_cn) { /* Modify the other one */ msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, "cn=test_search_2_cn," "dc=search_test_entry"); } else { msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, "cn=test_search_cn," "dc=search_test_entry"); } if (msg->dn == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); if (ret != 0) { exit(LDB_ERR_OPERATIONS_ERROR); } el = ldb_msg_find_element(msg, "filterAttr"); if (el == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } el->flags = LDB_FLAG_MOD_REPLACE; ret = ldb_transaction_start(ctx->test_ctx->ldb); if (ret != 0) { exit(ret); } if (write(pipes[1], "GO", 2) != 2) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_modify(ctx->test_ctx->ldb, msg); if (ret != 0) { exit(ret); } ret = ldb_transaction_commit(ctx->test_ctx->ldb); exit(ret); } /* * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()" * we will hang here because the child process can not proceed to * 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); sleep(3); return LDB_SUCCESS; } static void test_ldb_modify_during_search(void **state, bool add_index, bool rename) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); struct modify_during_search_test_ctx ctx = { .res_count = 0, .test_ctx = search_test_ctx->ldb_test_ctx, .rename = rename }; int ret; struct ldb_request *req; pid_t pid; int wstatus; if (add_index) { struct ldb_message *msg; struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "@INDEXLIST"); assert_non_null(indexlist); msg = ldb_msg_new(search_test_ctx); assert_non_null(msg); msg->dn = indexlist; 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); } tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); ctx.basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(ctx.basedn); /* * This search must be over multiple items, and should include * the new name after a rename, to show that it would match * both before and after that modify */ ret = ldb_build_search_req(&req, search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, ctx.basedn, LDB_SCOPE_SUBTREE, "(&(!(filterAttr=*))" "(|(cn=test_search_cn_renamed)" "(cn=test_search_cn)" "(cn=test_search_2_cn)" "))", NULL, NULL, &ctx, test_ldb_modify_during_search_callback1, NULL); assert_int_equal(ret, 0); ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } assert_int_equal(ret, 0); assert_int_equal(ctx.res_count, 2); assert_int_equal(ctx.got_cn, true); assert_int_equal(ctx.got_2_cn, true); pid = waitpid(ctx.child_pid, &wstatus, 0); assert_int_equal(pid, ctx.child_pid); assert_true(WIFEXITED(wstatus)); assert_int_equal(WEXITSTATUS(wstatus), 0); } static void test_ldb_modify_during_indexed_search(void **state) { test_ldb_modify_during_search(state, true, false); } static void test_ldb_modify_during_unindexed_search(void **state) { test_ldb_modify_during_search(state, false, false); } static void test_ldb_rename_during_indexed_search(void **state) { test_ldb_modify_during_search(state, true, true); } static void test_ldb_rename_during_unindexed_search(void **state) { test_ldb_modify_during_search(state, false, true); } /* * This test is also complex. * * The purpose is to test if a modify can occur during an ldb_search() * before the end of the callback * * This would be a failure if if in process * (1) and (2): * - (1) ldb_search() starts and calls back for a number of entries * - (2) an entry in the DB is allowed to change before the callback returns * - (1) the callback can see the modification * */ /* * This purpose of this callback is to trigger a write in * the child process while a search DONE callback is in progress. * * In ldb 1.1.31 ldb_search() omitted to take a all-record * lock for the full duration of the search and callbacks * * We assume that if the write will proceed, it will proceed in a 3 * second window after the function is called. */ static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req, struct ldb_reply *ares) { int ret; int pipes[2]; char buf[2]; struct modify_during_search_test_ctx *ctx = req->context; struct ldb_dn *search_dn; struct ldb_result *res2; unsigned res_count; switch (ares->type) { case LDB_REPLY_ENTRY: case LDB_REPLY_REFERRAL: return LDB_SUCCESS; case LDB_REPLY_DONE: break; } ret = pipe(pipes); assert_int_equal(ret, 0); ctx->child_pid = fork(); if (ctx->child_pid == 0) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_message *msg; 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); } ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, ctx->test_ctx->ev); if (ctx->test_ctx->ldb == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_connect(ctx->test_ctx->ldb, ctx->test_ctx->dbpath, 0, NULL); if (ret != LDB_SUCCESS) { exit(ret); } tmp_ctx = talloc_new(ctx->test_ctx); if (tmp_ctx == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, "cn=test_search_cn," "dc=search_test_entry"); if (msg->dn == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); if (ret != 0) { exit(LDB_ERR_OPERATIONS_ERROR); } el = ldb_msg_find_element(msg, "filterAttr"); if (el == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } el->flags = LDB_FLAG_MOD_REPLACE; ret = ldb_transaction_start(ctx->test_ctx->ldb); if (ret != 0) { exit(ret); } if (write(pipes[1], "GO", 2) != 2) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_modify(ctx->test_ctx->ldb, msg); if (ret != 0) { exit(ret); } ret = ldb_transaction_commit(ctx->test_ctx->ldb); exit(ret); } close(pipes[1]); ret = read(pipes[0], buf, 2); assert_int_equal(ret, 2); sleep(3); /* * If writes are not blocked until after this function, we * will be able to successfully search for this modification * here */ search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb, "cn=test_search_cn," "dc=search_test_entry"); ret = ldb_search(ctx->test_ctx->ldb, ares, &res2, search_dn, LDB_SCOPE_BASE, NULL, "filterAttr=TRUE"); /* * We do this in an unusual order, because if we fail an assert before * ldb_request_done(), we will also fail to clean up as we hold locks. */ res_count = res2->count; ldb_request_done(req, LDB_SUCCESS); assert_int_equal(ret, 0); /* We should not have got the result */ assert_int_equal(res_count, 0); return ret; } static void test_ldb_modify_during_whole_search(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); struct modify_during_search_test_ctx ctx = { .test_ctx = search_test_ctx->ldb_test_ctx, }; int ret; struct ldb_request *req; pid_t pid; int wstatus; struct ldb_dn *search_dn; struct ldb_result *res2; tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); ctx.basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(ctx.basedn); /* * 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, ctx.basedn, LDB_SCOPE_SUBTREE, "(&(!(filterAttr=*))" "(cn=test_search_cn))", NULL, NULL, &ctx, test_ldb_modify_during_whole_search_callback1, NULL); assert_int_equal(ret, 0); ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } assert_int_equal(ret, 0); pid = waitpid(ctx.child_pid, &wstatus, 0); assert_int_equal(pid, ctx.child_pid); assert_true(WIFEXITED(wstatus)); assert_int_equal(WEXITSTATUS(wstatus), 0); /* * If writes are blocked until after the search function, we * will be able to successfully search for this modification * now */ search_dn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "cn=test_search_cn," "dc=search_test_entry"); ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &res2, search_dn, LDB_SCOPE_BASE, NULL, "filterAttr=TRUE"); assert_int_equal(ret, 0); /* We got the result */ assert_int_equal(res2->count, 1); } /* * This test is also complex. * * The purpose is to test if a modify can occur during an ldb_search() * before the request is destroyed with TALLOC_FREE() * * This would be a failure if in process * (1) and (2): * - (1) ldb_search() starts and waits * - (2) an entry in the DB is allowed to change before the ldb_wait() is called * - (1) the original process can see the modification before the TALLOC_FREE() * also we check that * - (1) the original process can see the modification after the TALLOC_FREE() * */ /* * This purpose of this callback is to trigger a write in * the child process before the ldb_wait() is called * * In ldb 1.1.31 ldb_search() omitted to take a all-record * lock for the full duration of the search and callbacks * * We assume that if the write will proceed, it will proceed in a 3 * second window after the function is called. */ static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req, struct ldb_reply *ares) { switch (ares->type) { case LDB_REPLY_ENTRY: case LDB_REPLY_REFERRAL: return LDB_SUCCESS; case LDB_REPLY_DONE: break; } return ldb_request_done(req, LDB_SUCCESS); } static void test_ldb_modify_before_ldb_wait(void **state) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); int ret; struct ldb_request *req; pid_t pid; int wstatus; struct ldb_dn *search_dn; struct ldb_dn *basedn; struct ldb_result *res2; int pipes[2]; char buf[2]; pid_t child_pid; unsigned res_count; 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); basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(basedn); /* * 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, basedn, LDB_SCOPE_SUBTREE, "(&(!(filterAttr=*))" "(cn=test_search_cn))", NULL, NULL, NULL, test_ldb_modify_before_ldb_wait_callback1, NULL); assert_int_equal(ret, 0); ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); ret = pipe(pipes); assert_int_equal(ret, 0); child_pid = fork(); if (child_pid == 0) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_message *msg; 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); } search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx, search_test_ctx->ldb_test_ctx->ev); if (search_test_ctx->ldb_test_ctx->ldb == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx->ldb_test_ctx->dbpath, 0, NULL); if (ret != LDB_SUCCESS) { exit(ret); } tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx); if (tmp_ctx == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } /* * We must re-create this DN from a string to ensure * it does not reference the now-gone LDB context of * the parent */ msg->dn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "cn=test_search_cn," "dc=search_test_entry"); if (msg->dn == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); if (ret != 0) { exit(LDB_ERR_OPERATIONS_ERROR); } el = ldb_msg_find_element(msg, "filterAttr"); if (el == NULL) { exit(LDB_ERR_OPERATIONS_ERROR); } el->flags = LDB_FLAG_MOD_REPLACE; ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb); if (ret != 0) { exit(ret); } if (write(pipes[1], "GO", 2) != 2) { exit(LDB_ERR_OPERATIONS_ERROR); } ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg); if (ret != 0) { exit(ret); } 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); sleep(3); /* * If writes are not blocked until after the (never called) ldb_wait(), we * will be able to successfully search for this modification * here */ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &res2, search_dn, LDB_SCOPE_BASE, NULL, "filterAttr=TRUE"); /* * We avoid making assertions before TALLOC_FREE()ing the request, * lest the assert fail and mess with the clean-up because we still * have locks. */ res_count = res2->count; TALLOC_FREE(req); /* We should not have got the result */ assert_int_equal(res_count, 0); assert_int_equal(ret, 0); pid = waitpid(child_pid, &wstatus, 0); assert_int_equal(pid, child_pid); assert_true(WIFEXITED(wstatus)); assert_int_equal(WEXITSTATUS(wstatus), 0); /* * If writes are blocked until after the search request was freed, we * will be able to successfully search for this modification * now */ search_dn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "cn=test_search_cn," "dc=search_test_entry"); ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, &res2, search_dn, LDB_SCOPE_BASE, NULL, "filterAttr=TRUE"); assert_int_equal(ret, 0); /* We got the result */ assert_int_equal(res2->count, 1); } /* * This test is also complex. * The purpose is to test if a modify can occur during an ldb_search() * This would be a failure if if in process * (1) and (2): * - (1) ltdb_search() starts and calls back for one entry * - (2) one of the entries to be matched is modified * - (1) the indexed search tries to return the modified entry, but * it is no longer found, either: * - despite it still matching (dn changed) * - it no longer matching (attrs changed) * * We also try un-indexed to show that the behaviour differs on this * point, which it should not (an index should only impact search * speed). */ /* * This purpose of this callback is to trigger a write in the callback * so as to change in in-memory index code while looping over the * index result. */ static int test_ldb_callback_modify_during_search_callback1(struct ldb_request *req, struct ldb_reply *ares) { int ret; struct modify_during_search_test_ctx *ctx = req->context; struct ldb_dn *dn = NULL, *new_dn = NULL; TALLOC_CTX *tmp_ctx = talloc_new(ctx->test_ctx); struct ldb_message *msg = NULL; assert_non_null(tmp_ctx); switch (ares->type) { case LDB_REPLY_ENTRY: { const struct ldb_val *cn_val = ldb_dn_get_component_val(ares->message->dn, 0); const char *cn = (char *)cn_val->data; ctx->res_count++; if (strcmp(cn, "test_search_cn") == 0) { ctx->got_cn = true; } else if (strcmp(cn, "test_search_2_cn") == 0) { ctx->got_2_cn = true; } if (ctx->res_count == 2) { return LDB_SUCCESS; } break; } case LDB_REPLY_REFERRAL: return LDB_SUCCESS; case LDB_REPLY_DONE: return ldb_request_done(req, LDB_SUCCESS); } if (ctx->rename) { if (ctx->got_2_cn) { /* Modify this one */ dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_2_cn,%s", ldb_dn_get_linearized(ctx->basedn)); } else { dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_cn,%s", ldb_dn_get_linearized(ctx->basedn)); } assert_non_null(dn); new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_cn_renamed," "dc=not_search_test_entry"); assert_non_null(new_dn); ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn); assert_int_equal(ret, 0); } else { if (ctx->got_2_cn) { /* Delete this one */ dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_2_cn,%s", ldb_dn_get_linearized(ctx->basedn)); } else { dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, "cn=test_search_cn,%s", ldb_dn_get_linearized(ctx->basedn)); } assert_non_null(dn); ret = ldb_delete(ctx->test_ctx->ldb, dn); assert_int_equal(ret, 0); } /* * Now fill in the position we just removed from the * index to ensure we fail the test (otherwise we just read * past the end of the array and find the value we wanted to * skip) */ msg = ldb_msg_new(tmp_ctx); assert_non_null(msg); /* We deliberatly use ou= not cn= here */ msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, "ou=test_search_cn_extra,%s", ldb_dn_get_linearized(ctx->basedn)); ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde3"); ret = ldb_add(ctx->test_ctx->ldb, msg); assert_int_equal(ret, LDB_SUCCESS); TALLOC_FREE(tmp_ctx); return LDB_SUCCESS; } static void test_ldb_callback_modify_during_search(void **state, bool add_index, bool rename) { struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); struct modify_during_search_test_ctx ctx = { .res_count = 0, .test_ctx = search_test_ctx->ldb_test_ctx, .rename = rename }; int ret; struct ldb_request *req; ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb); assert_int_equal(ret, 0); if (add_index) { struct ldb_message *msg; struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "@INDEXLIST"); assert_non_null(indexlist); msg = ldb_msg_new(search_test_ctx); assert_non_null(msg); msg->dn = indexlist; ret = ldb_msg_add_string(msg, "@IDXONE", "1"); assert_int_equal(ret, LDB_SUCCESS); 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; msg->elements[1].flags = LDB_FLAG_MOD_ADD; ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg); } assert_int_equal(ret, LDB_SUCCESS); /* * Now bring the IDXONE index into memory by modifying * it. This exposes an issue in ldb_tdb */ msg = ldb_msg_new(search_test_ctx); assert_non_null(msg); msg->dn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "cn=test_search_cn_extra,%s", search_test_ctx->base_dn); ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde2"); ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn); assert_int_equal(ret, LDB_SUCCESS); } tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); ctx.basedn = ldb_dn_new_fmt(search_test_ctx, search_test_ctx->ldb_test_ctx->ldb, "%s", search_test_ctx->base_dn); assert_non_null(ctx.basedn); /* * This search must be over multiple items, and should include * the new name after a rename, to show that it would match * both before and after that modify * * This needs to be a search that isn't matched by an index so * that we just use the one-level index. */ ret = ldb_build_search_req(&req, search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, ctx.basedn, LDB_SCOPE_ONELEVEL, "(cn=*)", NULL, NULL, &ctx, test_ldb_callback_modify_during_search_callback1, NULL); assert_int_equal(ret, 0); ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } assert_int_equal(ret, 0); ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb); assert_int_equal(ret, 0); assert_int_equal(ctx.res_count, 2); assert_int_equal(ctx.got_cn, true); assert_int_equal(ctx.got_2_cn, true); } static void test_ldb_callback_delete_during_indexed_search(void **state) { test_ldb_callback_modify_during_search(state, true, false); } static void test_ldb_callback_delete_during_unindexed_search(void **state) { test_ldb_callback_modify_during_search(state, false, false); } static void test_ldb_callback_rename_during_indexed_search(void **state) { test_ldb_callback_modify_during_search(state, true, true); } static void test_ldb_callback_rename_during_unindexed_search(void **state) { test_ldb_callback_modify_during_search(state, false, true); } static int ldb_case_test_setup(void **state) { int ret; struct ldb_ldif *ldif; struct ldbtest_ctx *ldb_test_ctx; const char *attrs_ldif = \ "dn: @ATTRIBUTES\n" "cn: CASE_INSENSITIVE\n" "\n"; struct keyval kvs[] = { { "cn", "CaseInsensitiveValue" }, { "uid", "CaseSensitiveValue" }, { "objectUUID", "0123456789abcdef" }, { NULL, NULL }, }; ldbtest_setup((void **) &ldb_test_ctx); while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); assert_int_equal(ret, LDB_SUCCESS); } ldb_test_add_data(ldb_test_ctx, ldb_test_ctx, "cn=CaseInsensitiveValue", kvs); *state = ldb_test_ctx; return 0; } static int ldb_case_test_teardown(void **state) { int ret; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_dn *del_dn; del_dn = ldb_dn_new_fmt(ldb_test_ctx, ldb_test_ctx->ldb, "@ATTRIBUTES"); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); assert_int_equal(ret, LDB_SUCCESS); assert_dn_doesnt_exist(ldb_test_ctx, "@ATTRIBUTES"); ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx, "cn=CaseInsensitiveValue"); ldbtest_teardown((void **) &ldb_test_ctx); return 0; } static void test_ldb_attrs_case_insensitive(void **state) { int cnt; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); /* cn matches exact case */ cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue"); assert_int_equal(cnt, 1); /* cn matches lower case */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 1); /* uid matches exact case */ cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue"); assert_int_equal(cnt, 1); /* uid does not match lower case */ cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue"); assert_int_equal(cnt, 0); } static struct ldb_schema_attribute cn_attr_1; static struct ldb_schema_attribute cn_attr_2; static struct ldb_schema_attribute default_attr; /* override the name to attribute handler function */ static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb, void *private_data, const char *name) { if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) { return &cn_attr_1; } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) { return &cn_attr_2; } else if (ldb_attr_cmp(name, "uid") == 0) { return &cn_attr_2; } return &default_attr; } static void test_ldb_attrs_case_handler(void **state) { int cnt; int ret; const struct ldb_schema_syntax *syntax; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_context *ldb = ldb_test_ctx->ldb; /* cn matches lower case */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 1); 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); syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); assert_non_null(syntax); ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, "cn", 0, syntax, &cn_attr_1); assert_int_equal(ret, LDB_SUCCESS); /* * Set an attribute handler, which will fail to match as we * force case sensitive */ ldb_schema_attribute_set_override_handler(ldb, ldb_test_attribute_handler_override, (void *)1); /* cn does not matche lower case */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 0); syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING); assert_non_null(syntax); ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, "cn", 0, syntax, &cn_attr_2); assert_int_equal(ret, LDB_SUCCESS); /* * Set an attribute handler, which will match as we * force case insensitive */ ldb_schema_attribute_set_override_handler(ldb, ldb_test_attribute_handler_override, NULL); /* cn matches lower case */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 1); } static void test_ldb_attrs_index_handler(void **state) { int cnt; int ret; const struct ldb_schema_syntax *syntax; struct ldb_ldif *ldif; const char *index_ldif = \ "dn: @INDEXLIST\n" "@IDXATTR: cn\n" "\n"; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_context *ldb = ldb_test_ctx->ldb; /* cn matches lower case */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 1); syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); assert_non_null(syntax); ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, "cn", 0, syntax, &cn_attr_1); assert_int_equal(ret, LDB_SUCCESS); syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING); assert_non_null(syntax); ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, "cn", LDB_ATTR_FLAG_INDEXED, 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 */ ldb_schema_attribute_set_override_handler(ldb, ldb_test_attribute_handler_override, NULL); /* cn matches lower case */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 1); /* 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); } ldb_schema_set_override_indexlist(ldb, false); /* cn does match as there is an index now */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 1); /* * Set an attribute handler, which will later fail to match as we * didn't re-index the DB */ ldb_schema_attribute_set_override_handler(ldb, ldb_test_attribute_handler_override, (void *)1); /* * cn does not match as we changed the case sensitivity, but * didn't re-index * * This shows that the override is in control */ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); assert_int_equal(cnt, 0); } static int ldb_case_attrs_index_test_teardown(void **state) { int ret; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_dn *del_dn; del_dn = ldb_dn_new_fmt(ldb_test_ctx, ldb_test_ctx->ldb, "@INDEXLIST"); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); if (ret != LDB_ERR_NO_SUCH_OBJECT) { assert_int_equal(ret, LDB_SUCCESS); } assert_dn_doesnt_exist(ldb_test_ctx, "@INDEXLIST"); ldb_case_test_teardown(state); return 0; } struct rename_test_ctx { struct ldbtest_ctx *ldb_test_ctx; struct ldb_dn *basedn; const char *str_basedn; const char *teardown_dn; }; static int ldb_rename_test_setup(void **state) { struct ldbtest_ctx *ldb_test_ctx; struct rename_test_ctx *rename_test_ctx; const char *strdn = "dc=rename_test_entry_from"; ldbtest_setup((void **) &ldb_test_ctx); rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx); assert_non_null(rename_test_ctx); rename_test_ctx->ldb_test_ctx = ldb_test_ctx; assert_non_null(rename_test_ctx->ldb_test_ctx); rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx, rename_test_ctx->ldb_test_ctx->ldb, "%s", strdn); assert_non_null(rename_test_ctx->basedn); rename_test_ctx->str_basedn = strdn; rename_test_ctx->teardown_dn = strdn; add_dn_with_cn(ldb_test_ctx, rename_test_ctx->basedn, "test_rename_cn_val", "0123456789abcde0"); *state = rename_test_ctx; return 0; } static int ldb_rename_test_teardown(void **state) { int ret; struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state, struct rename_test_ctx); struct ldbtest_ctx *ldb_test_ctx; struct ldb_dn *del_dn; ldb_test_ctx = rename_test_ctx->ldb_test_ctx; del_dn = ldb_dn_new_fmt(rename_test_ctx, rename_test_ctx->ldb_test_ctx->ldb, "%s", rename_test_ctx->teardown_dn); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); assert_int_equal(ret, LDB_SUCCESS); assert_dn_doesnt_exist(ldb_test_ctx, rename_test_ctx->teardown_dn); ldbtest_teardown((void **) &ldb_test_ctx); return 0; } static void test_ldb_rename(void **state) { struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state, struct rename_test_ctx); int ret; const char *str_new_dn = "dc=rename_test_entry_to"; struct ldb_dn *new_dn; new_dn = ldb_dn_new_fmt(rename_test_ctx, rename_test_ctx->ldb_test_ctx->ldb, "%s", str_new_dn); assert_non_null(new_dn); ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, rename_test_ctx->basedn, new_dn); assert_int_equal(ret, LDB_SUCCESS); assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn); assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, rename_test_ctx->str_basedn); rename_test_ctx->teardown_dn = str_new_dn; /* FIXME - test the values which didn't change */ } static void test_ldb_rename_from_doesnt_exist(void **state) { struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( *state, struct rename_test_ctx); int ret; const char *str_new_dn = "dc=rename_test_entry_to"; const char *str_bad_old_dn = "dc=rename_test_no_such_entry"; struct ldb_dn *new_dn; struct ldb_dn *bad_old_dn; new_dn = ldb_dn_new_fmt(rename_test_ctx, rename_test_ctx->ldb_test_ctx->ldb, "%s", str_new_dn); assert_non_null(new_dn); bad_old_dn = ldb_dn_new_fmt(rename_test_ctx, rename_test_ctx->ldb_test_ctx->ldb, "%s", str_bad_old_dn); assert_non_null(bad_old_dn); assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, str_bad_old_dn); ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, bad_old_dn, new_dn); assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, str_new_dn); } static void test_ldb_rename_to_exists(void **state) { struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( *state, struct rename_test_ctx); int ret; const char *str_new_dn = "dc=rename_test_already_exists"; struct ldb_dn *new_dn; new_dn = ldb_dn_new_fmt(rename_test_ctx, rename_test_ctx->ldb_test_ctx->ldb, "%s", str_new_dn); assert_non_null(new_dn); add_dn_with_cn(rename_test_ctx->ldb_test_ctx, new_dn, "test_rename_cn_val", "0123456789abcde1"); ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, rename_test_ctx->basedn, new_dn); assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); /* Old object must still exist */ assert_dn_exists(rename_test_ctx->ldb_test_ctx, rename_test_ctx->str_basedn); ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb, new_dn); assert_int_equal(ret, LDB_SUCCESS); assert_dn_exists(rename_test_ctx->ldb_test_ctx, rename_test_ctx->teardown_dn); } static void test_ldb_rename_self(void **state) { struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( *state, struct rename_test_ctx); int ret; /* Oddly enough, this is a success in ldb.. */ ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, rename_test_ctx->basedn, rename_test_ctx->basedn); assert_int_equal(ret, LDB_SUCCESS); /* Old object must still exist */ assert_dn_exists(rename_test_ctx->ldb_test_ctx, rename_test_ctx->str_basedn); } static void test_ldb_rename_dn_case_change(void **state) { struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( *state, struct rename_test_ctx); int ret; char *str_new_dn; struct ldb_dn *new_dn; unsigned i; str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn); assert_non_null(str_new_dn); for (i = 0; str_new_dn[i]; i++) { str_new_dn[i] = toupper(str_new_dn[i]); } new_dn = ldb_dn_new_fmt(rename_test_ctx, rename_test_ctx->ldb_test_ctx->ldb, "%s", str_new_dn); assert_non_null(new_dn); ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, rename_test_ctx->basedn, new_dn); assert_int_equal(ret, LDB_SUCCESS); /* DNs are case insensitive, so both searches will match */ assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn); assert_dn_exists(rename_test_ctx->ldb_test_ctx, rename_test_ctx->str_basedn); /* FIXME - test the values didn't change */ } static int ldb_read_only_setup(void **state) { struct ldbtest_ctx *test_ctx; ldbtest_setup((void **) &test_ctx); *state = test_ctx; return 0; } static int ldb_read_only_teardown(void **state) { struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); ldbtest_teardown((void **) &test_ctx); return 0; } static void test_read_only(void **state) { struct ldb_context *ro_ldb = NULL; struct ldb_context *rw_ldb = NULL; int ret; TALLOC_CTX *tmp_ctx = NULL; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); /* * Close the ldb context freeing it this will ensure it exists on * disk and can be opened in read only mode */ TALLOC_FREE(test_ctx->ldb); /* * Open the database in read only and read write mode, * ensure it's opend in read only mode first */ ro_ldb = ldb_init(test_ctx, test_ctx->ev); ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); assert_int_equal(ret, 0); rw_ldb = ldb_init(test_ctx, test_ctx->ev); ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL); assert_int_equal(ret, 0); /* * Set up a context for the temporary variables */ tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* * Ensure that we can search the read write database */ { struct ldb_result *result = NULL; struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test"); assert_non_null(dn); ret = ldb_search(rw_ldb, tmp_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, LDB_SUCCESS); TALLOC_FREE(result); TALLOC_FREE(dn); } /* * Ensure that we can search the read only database */ { struct ldb_result *result = NULL; struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test"); assert_non_null(dn); ret = ldb_search(ro_ldb, tmp_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL); assert_int_equal(ret, LDB_SUCCESS); TALLOC_FREE(result); TALLOC_FREE(dn); } /* * Ensure that a write to the read only database fails */ { struct ldb_message *msg = NULL; msg = ldb_msg_new(tmp_ctx); assert_non_null(msg); 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", "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); } /* * Ensure that a write to the read write database succeeds */ { struct ldb_message *msg = NULL; msg = ldb_msg_new(tmp_ctx); assert_non_null(msg); msg->dn = ldb_dn_new_fmt(msg, rw_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); } /* * Ensure that a delete from a read only database fails */ { struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test"); assert_non_null(dn); ret = ldb_delete(ro_ldb, dn); assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM); TALLOC_FREE(dn); } /* * Ensure that a delete from a read write succeeds */ { struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test"); assert_non_null(dn); ret = ldb_delete(rw_ldb, dn); assert_int_equal(ret, LDB_SUCCESS); TALLOC_FREE(dn); } TALLOC_FREE(tmp_ctx); } static bool unique_values = false; static int unique_index_test_module_add( struct ldb_module *module, struct ldb_request *req) { if (unique_values) { struct ldb_message *msg = discard_const(req->op.add.message); struct ldb_message_element *el = NULL; el = ldb_msg_find_element(msg, "cn"); if (el != NULL) { el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX; } } return ldb_next_request(module, req); } static int unique_index_test_module_init(struct ldb_module *module) { return ldb_next_init(module); } static const struct ldb_module_ops ldb_unique_index_test_module_ops = { .name = "unique_index_test", .init_context = unique_index_test_module_init, .add = unique_index_test_module_add, }; static int ldb_unique_index_test_setup(void **state) { int ret; struct ldb_ldif *ldif; struct ldbtest_ctx *ldb_test_ctx; const char *attrs_ldif = \ "dn: @ATTRIBUTES\n" "cn: UNIQUE_INDEX\n" "\n"; 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}; ret = ldb_register_module(&ldb_unique_index_test_module_ops); assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS); ldbtest_noconn_setup((void **) &ldb_test_ctx); ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options); assert_int_equal(ret, 0); while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); assert_int_equal(ret, LDB_SUCCESS); } while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); assert_int_equal(ret, LDB_SUCCESS); } unique_values = true; *state = ldb_test_ctx; return 0; } static int ldb_unique_index_test_teardown(void **state) { int ret; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_dn *del_dn; del_dn = ldb_dn_new_fmt(ldb_test_ctx, ldb_test_ctx->ldb, "@INDEXLIST"); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); if (ret != LDB_ERR_NO_SUCH_OBJECT) { assert_int_equal(ret, LDB_SUCCESS); } assert_dn_doesnt_exist(ldb_test_ctx, "@INDEXLIST"); TALLOC_FREE(del_dn); del_dn = ldb_dn_new_fmt(ldb_test_ctx, ldb_test_ctx->ldb, "@ATTRIBUTES"); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); if (ret != LDB_ERR_NO_SUCH_OBJECT) { assert_int_equal(ret, LDB_SUCCESS); } assert_dn_doesnt_exist(ldb_test_ctx, "@ATTRIBUTES"); ldbtest_teardown((void **) &ldb_test_ctx); return 0; } static void test_ldb_add_unique_value_to_unique_index(void **state) { int ret; struct ldb_message *msg; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); 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); msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test"); assert_non_null(msg->dn); 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); talloc_free(tmp_ctx); } static int ldb_non_unique_index_test_setup(void **state) { int ret; struct ldb_ldif *ldif; struct ldbtest_ctx *ldb_test_ctx; 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}; ret = ldb_register_module(&ldb_unique_index_test_module_ops); assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS); ldbtest_noconn_setup((void **) &ldb_test_ctx); ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options); assert_int_equal(ret, 0); while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); assert_int_equal(ret, LDB_SUCCESS); } unique_values = true; *state = ldb_test_ctx; return 0; } static int ldb_non_unique_index_test_teardown(void **state) { int ret; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_dn *del_dn; del_dn = ldb_dn_new_fmt(ldb_test_ctx, ldb_test_ctx->ldb, "@INDEXLIST"); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); if (ret != LDB_ERR_NO_SUCH_OBJECT) { assert_int_equal(ret, LDB_SUCCESS); } assert_dn_doesnt_exist(ldb_test_ctx, "@INDEXLIST"); TALLOC_FREE(del_dn); ldbtest_teardown((void **) &ldb_test_ctx); return 0; } static void test_ldb_add_duplicate_value_to_unique_index(void **state) { int ret; struct ldb_message *msg01; struct ldb_message *msg02; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); msg01 = ldb_msg_new(tmp_ctx); assert_non_null(msg01); msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); assert_non_null(msg01->dn); 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); msg02 = ldb_msg_new(tmp_ctx); assert_non_null(msg02); msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); assert_non_null(msg02->dn); 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); } static void test_ldb_add_to_index_duplicates_allowed(void **state) { int ret; struct ldb_message *msg01; struct ldb_message *msg02; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; unique_values = false; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); msg01 = ldb_msg_new(tmp_ctx); assert_non_null(msg01); msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); assert_non_null(msg01->dn); 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); msg02 = ldb_msg_new(tmp_ctx); assert_non_null(msg02); msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); assert_non_null(msg02->dn); 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); } static void test_ldb_add_to_index_unique_values_required(void **state) { int ret; struct ldb_message *msg01; struct ldb_message *msg02; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; unique_values = true; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); msg01 = ldb_msg_new(tmp_ctx); assert_non_null(msg01); msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); assert_non_null(msg01->dn); 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); msg02 = ldb_msg_new(tmp_ctx); assert_non_null(msg02); msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); assert_non_null(msg02->dn); 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); } static void ldb_debug_string(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) { if (level <= LDB_DEBUG_WARNING) { *((char **)context) = talloc_vasprintf(NULL, fmt, ap); } } static void test_ldb_unique_index_duplicate_logging(void **state) { int ret; struct ldb_message *msg01; struct ldb_message *msg02; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; 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); msg01 = ldb_msg_new(tmp_ctx); assert_non_null(msg01); msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); assert_non_null(msg01->dn); 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); msg02 = ldb_msg_new(tmp_ctx); assert_non_null(msg02); msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); assert_non_null(msg02->dn); 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); assert_non_null(debug_string); p = strstr( debug_string, "unique index violation on cn " "in dc=test02, conflicts with dc=test01 in " "@INDEX:CN:test_unique_index"); assert_non_null(p); TALLOC_FREE(debug_string); talloc_free(tmp_ctx); } static void test_ldb_duplicate_dn_logging(void **state) { int ret; struct ldb_message *msg01; struct ldb_message *msg02; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); 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); msg01 = ldb_msg_new(tmp_ctx); assert_non_null(msg01); msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); assert_non_null(msg01->dn); 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); msg02 = ldb_msg_new(tmp_ctx); assert_non_null(msg02); msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01"); assert_non_null(msg02->dn); 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); assert_null(debug_string); talloc_free(tmp_ctx); } static int ldb_guid_index_test_setup(void **state) { int ret; struct ldb_ldif *ldif; struct ldbtest_ctx *ldb_test_ctx; const char *attrs_ldif = \ "dn: @ATTRIBUTES\n" "cn: UNIQUE_INDEX\n" "\n"; const char *index_ldif = \ "dn: @INDEXLIST\n" "@IDXATTR: cn\n" "@IDXGUID: objectUUID\n" "@IDX_DN_GUID: GUID\n" "\n"; ldbtest_noconn_setup((void **) &ldb_test_ctx); ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL); assert_int_equal(ret, 0); while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); assert_int_equal(ret, LDB_SUCCESS); } while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); assert_int_equal(ret, LDB_SUCCESS); } *state = ldb_test_ctx; return 0; } static int ldb_guid_index_test_teardown(void **state) { int ret; struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_dn *del_dn; del_dn = ldb_dn_new_fmt(ldb_test_ctx, ldb_test_ctx->ldb, "@INDEXLIST"); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); if (ret != LDB_ERR_NO_SUCH_OBJECT) { assert_int_equal(ret, LDB_SUCCESS); } assert_dn_doesnt_exist(ldb_test_ctx, "@INDEXLIST"); TALLOC_FREE(del_dn); del_dn = ldb_dn_new_fmt(ldb_test_ctx, ldb_test_ctx->ldb, "@ATTRIBUTES"); assert_non_null(del_dn); ret = ldb_delete(ldb_test_ctx->ldb, del_dn); if (ret != LDB_ERR_NO_SUCH_OBJECT) { assert_int_equal(ret, LDB_SUCCESS); } assert_dn_doesnt_exist(ldb_test_ctx, "@ATTRIBUTES"); ldbtest_teardown((void **) &ldb_test_ctx); return 0; } static void test_ldb_unique_index_duplicate_with_guid(void **state) { int ret; struct ldb_message *msg01; struct ldb_message *msg02; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; char *debug_string = NULL; char *p = NULL; ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); msg01 = ldb_msg_new(tmp_ctx); assert_non_null(msg01); msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); assert_non_null(msg01->dn); ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_add(test_ctx->ldb, msg01); assert_int_equal(ret, LDB_SUCCESS); msg02 = ldb_msg_new(tmp_ctx); assert_non_null(msg02); msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); assert_non_null(msg02->dn); ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_add(test_ctx->ldb, msg02); assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); assert_non_null(debug_string); p = strstr( debug_string, "unique index violation on cn in dc=test02, conflicts with " "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index"); assert_non_null(p); TALLOC_FREE(debug_string); talloc_free(tmp_ctx); ldb_set_debug(test_ctx->ldb, NULL, NULL); } static void test_ldb_guid_index_duplicate_dn_logging(void **state) { int ret; struct ldb_message *msg01; struct ldb_message *msg02; struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); TALLOC_CTX *tmp_ctx; char *debug_string = NULL; ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); msg01 = ldb_msg_new(tmp_ctx); assert_non_null(msg01); msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); assert_non_null(msg01->dn); ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_add(test_ctx->ldb, msg01); assert_int_equal(ret, LDB_SUCCESS); msg02 = ldb_msg_new(tmp_ctx); assert_non_null(msg02); msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01"); assert_non_null(msg02->dn); ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1"); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_add(test_ctx->ldb, msg02); assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); assert_null(debug_string); talloc_free(tmp_ctx); ldb_set_debug(test_ctx->ldb, NULL, NULL); } 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) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_connect, ldbtest_noconn_setup, ldbtest_noconn_teardown), cmocka_unit_test_setup_teardown(test_ldif_message, ldbtest_noconn_setup, ldbtest_noconn_teardown), cmocka_unit_test_setup_teardown(test_ldif_message_redacted, ldbtest_noconn_setup, ldbtest_noconn_teardown), cmocka_unit_test_setup_teardown(test_ldb_add, ldbtest_setup, ldbtest_teardown), cmocka_unit_test_setup_teardown(test_ldb_search, ldbtest_setup, ldbtest_teardown), cmocka_unit_test_setup_teardown(test_ldb_del, ldbtest_setup, ldbtest_teardown), cmocka_unit_test_setup_teardown(test_ldb_del_noexist, ldbtest_setup, ldbtest_teardown), cmocka_unit_test_setup_teardown(test_ldb_handle, ldbtest_setup, ldbtest_teardown), cmocka_unit_test_setup_teardown(test_ldb_build_search_req, ldbtest_setup, ldbtest_teardown), 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), cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_del_key, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval, ldb_modify_test_setup, ldb_modify_test_teardown), cmocka_unit_test_setup_teardown(test_search_match_none, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_search_match_one, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_search_match_filter, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_search_match_both, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_search_match_basedn, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_unindexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_indexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_unindexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_indexed_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait, ldb_search_test_setup, ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive, ldb_case_test_setup, ldb_case_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler, ldb_case_test_setup, ldb_case_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler, ldb_case_test_setup, ldb_case_attrs_index_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_rename, ldb_rename_test_setup, ldb_rename_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist, ldb_rename_test_setup, ldb_rename_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists, ldb_rename_test_setup, ldb_rename_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_rename_self, ldb_rename_test_setup, ldb_rename_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change, ldb_rename_test_setup, ldb_rename_test_teardown), cmocka_unit_test_setup_teardown(test_read_only, ldb_read_only_setup, ldb_read_only_teardown), cmocka_unit_test_setup_teardown( test_ldb_add_unique_value_to_unique_index, ldb_unique_index_test_setup, ldb_unique_index_test_teardown), cmocka_unit_test_setup_teardown( test_ldb_add_duplicate_value_to_unique_index, ldb_unique_index_test_setup, ldb_unique_index_test_teardown), cmocka_unit_test_setup_teardown( test_ldb_add_to_index_duplicates_allowed, ldb_non_unique_index_test_setup, ldb_non_unique_index_test_teardown), cmocka_unit_test_setup_teardown( 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, ldb_unique_index_test_teardown), cmocka_unit_test_setup_teardown( test_ldb_duplicate_dn_logging, ldb_unique_index_test_setup, ldb_unique_index_test_teardown), cmocka_unit_test_setup_teardown( test_ldb_guid_index_duplicate_dn_logging, ldb_guid_index_test_setup, ldb_guid_index_test_teardown), cmocka_unit_test_setup_teardown( 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); } ldb-2.0.8/tests/ldb_msg.c0000660000000000000000000002755513573675413015167 0ustar rootroot00000000000000/* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. */ #include #include #include #include #include #include #include #include #include #include #include #include struct test_ctx { struct ldb_message *msg; }; static int ldb_msg_setup(void **state) { struct test_ctx *test_ctx; test_ctx = talloc_zero(NULL, struct test_ctx); assert_non_null(test_ctx); test_ctx->msg = ldb_msg_new(test_ctx); *state = test_ctx; return 0; } static int ldb_msg_teardown(void **state) { struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); talloc_free(test_ctx); return 0; } static void add_uint_value(struct test_ctx *test_ctx, struct ldb_message *msg, const char *attr, unsigned int x) { int ret; struct ldb_val v, v_dup; char s[5]; snprintf(s, sizeof(s), "%04x", x); v.data = (uint8_t *)s; v.length = 4; v_dup = ldb_val_dup(test_ctx, &v); assert_non_null(v_dup.data); assert_ptr_not_equal(v_dup.data, v.data); assert_int_equal(v_dup.length, 4); ret = ldb_msg_add_value(msg, attr, &v_dup, NULL); assert_int_equal(ret, LDB_SUCCESS); } static void test_ldb_msg_find_duplicate_val(void **state) { int ret; unsigned int i; struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); struct ldb_message *msg = test_ctx->msg; struct ldb_message_element *el; struct ldb_val dummy; struct ldb_val *dupe = &dummy; /* so we can tell it was modified to NULL, not left as NULL */ ret = ldb_msg_add_empty(msg, "el1", 0, &el); assert_int_equal(ret, LDB_SUCCESS); /* An empty message contains no duplicates */ ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); assert_int_equal(ret, LDB_SUCCESS); assert_null(dupe); for (i = 0; i < 5; i++) { add_uint_value(test_ctx, msg, "el1", i); } /* at this point there are no duplicates, and the check uses the naive quadratic path */ ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); assert_int_equal(ret, LDB_SUCCESS); assert_null(dupe); /* add a duplicate, still using quadratric path */ add_uint_value(test_ctx, msg, "el1", 3); ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(dupe); assert_int_equal(dupe->length, 4); assert_memory_equal(dupe->data, "0003", 4); /* add some more, triggering algorithmic jump */ for (i = 2; i < 11; i++) { add_uint_value(test_ctx, msg, "el1", i); } ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); assert_int_equal(ret, LDB_SUCCESS); assert_non_null(dupe); assert_int_equal(dupe->length, 4); /*XXX not really guaranteed by the API */ assert_memory_equal(dupe->data, "0002", 4); /* start a new element without duplicates, for the clever algorithm */ ldb_msg_add_empty(msg, "el2", 0, &el); for (i = 0; i < 12; i++) { add_uint_value(test_ctx, msg, "el2", i); } ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); assert_int_equal(ret, LDB_SUCCESS); assert_null(dupe); } static struct ldb_message_element *new_msg_element(TALLOC_CTX *mem_ctx, const char *name, unsigned int value_offset, unsigned int num_values) { unsigned int i, x; struct ldb_message_element *el = talloc_zero(mem_ctx, struct ldb_message_element); el->values = talloc_array(el, struct ldb_val, num_values); for (i = 0; i < num_values; i++) { struct ldb_val v; char s[50]; v.data = (uint8_t *)s; /* % 3 is to ensure the values list is unsorted */ x = i + value_offset; v.length = snprintf(s, sizeof(s), "%u %u", x % 3, x); el->values[i] = ldb_val_dup(mem_ctx, &v); } el->name = name; el->num_values = num_values; return el; } static void _assert_element_equal(struct ldb_message_element *a, struct ldb_message_element *b, const char * const file, const int line) { unsigned int i; _assert_int_equal(a->num_values, b->num_values, file, line); _assert_int_equal(a->flags, b->flags, file, line); _assert_string_equal(a->name, b->name, file, line); for (i = 0; i < a->num_values; i++) { struct ldb_val *v1 = &a->values[i]; struct ldb_val *v2 = &b->values[i]; _assert_int_equal(v1->length, v2->length, file, line); _assert_memory_equal(v1->data, v2->data, v1->length, file, line); } } #define assert_element_equal(a, b) \ _assert_element_equal((a), (b), \ __FILE__, __LINE__) static void test_ldb_msg_find_common_values(void **state) { /* we only use the state as a talloc context */ struct ldb_message_element *el, *el2, *el3, *el4, *el2b, *empty; struct ldb_message_element *orig, *orig2, *orig3, *orig4; int ret; const uint32_t remove_dupes = LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; el = new_msg_element(*state, "test", 0, 4); el2 = new_msg_element(*state, "test", 4, 4); el3 = new_msg_element(*state, "test", 6, 4); empty = new_msg_element(*state, "test", 0, 0); orig = new_msg_element(*state, "test", 0, 4); orig2 = new_msg_element(*state, "test", 4, 4); orig3 = new_msg_element(*state, "test", 6, 4); /* first round is with short value arrays, using quadratic method */ /* we expect no collisions here */ ret = ldb_msg_find_common_values(NULL, *state, el, el2, 0); assert_int_equal(ret, LDB_SUCCESS); /*or here */ ret = ldb_msg_find_common_values(NULL, *state, el, el3, 0); assert_int_equal(ret, LDB_SUCCESS); /* the same elements in reverse order */ ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el3, el, 0); assert_int_equal(ret, LDB_SUCCESS); /* 6, 7 collide */ ret = ldb_msg_find_common_values(NULL, *state, el2, el3, 0); assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); /* and again */ ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); /* make sure the arrays haven't changed */ assert_element_equal(el, orig); assert_element_equal(el2, orig2); assert_element_equal(el3, orig3); /* now with the control permisive flag, the first element should be modified to remove the overlap.*/ /* 6, 7 collide, so el2 will only have 4 and 5 */ ret = ldb_msg_find_common_values(NULL, *state, el2, el3, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); assert_element_equal(el3, orig3); assert_int_not_equal(el2->num_values, orig2->num_values); assert_int_equal(el2->num_values, 2); el2b = new_msg_element(*state, "test", 4, 2); assert_element_equal(el2, el2b); /* now try the same things with a long and a short value list. this should still trigger the quadratic path. */ el2 = new_msg_element(*state, "test", 4, 10); orig2 = new_msg_element(*state, "test", 4, 10); /* no collisions */ ret = ldb_msg_find_common_values(NULL, *state, el, el2, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); assert_int_equal(ret, LDB_SUCCESS); /*collisions */ ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); assert_element_equal(el, orig); assert_element_equal(el2, orig2); assert_element_equal(el3, orig3); /*collisions with permissive flag*/ ret = ldb_msg_find_common_values(NULL, *state, el3, el2, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); assert_element_equal(el2, orig2); assert_int_equal(el3->num_values, 0); /* permutations involving empty elements. everything should succeed. */ ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el3, el, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el2, el3, 0); assert_int_equal(ret, LDB_SUCCESS); assert_int_equal(el2->num_values, orig2->num_values); ret = ldb_msg_find_common_values(NULL, *state, el3, el2, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); assert_int_equal(el2->num_values, orig2->num_values); assert_int_equal(el3->num_values, 0); /* el3 is now empty */ ret = ldb_msg_find_common_values(NULL, *state, el2, el3, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el3, empty, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, empty, empty, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, empty, el3, 0); assert_int_equal(ret, LDB_SUCCESS); assert_element_equal(el2, orig2); assert_element_equal(el, orig); assert_int_equal(el3->num_values, 0); /* now with two large value lists */ el = new_msg_element(*state, "test", 0, 12); orig = new_msg_element(*state, "test", 0, 12); el4 = new_msg_element(*state, "test", 12, 12); orig4 = new_msg_element(*state, "test", 12, 12); /* no collisions */ ret = ldb_msg_find_common_values(NULL, *state, el, el4, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el4, el, 0); assert_int_equal(ret, LDB_SUCCESS); /* collisions */ ret = ldb_msg_find_common_values(NULL, *state, el4, el2, 0); assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); ret = ldb_msg_find_common_values(NULL, *state, el2, el4, 0); assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); assert_element_equal(el, orig); assert_element_equal(el2, orig2); assert_element_equal(el4, orig4); /* with permissive control, but no collisions */ ret = ldb_msg_find_common_values(NULL, *state, el, el4, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el4, el, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); assert_element_equal(el, orig); assert_element_equal(el4, orig4); /* now with collisions, thus modifications. At this stage: el is 0-11 (inclusive) e2 is 4-13 el3 is empty el4 is 12-23 */ ret = ldb_msg_find_common_values(NULL, *state, el4, el2, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); assert_element_equal(el2, orig2); assert_int_not_equal(el4->num_values, orig4->num_values); /* 4 should start at 14 */ orig4 = new_msg_element(*state, "test", 14, 10); assert_element_equal(el4, orig4); ret = ldb_msg_find_common_values(NULL, *state, el2, el, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); assert_element_equal(el, orig); assert_int_not_equal(el2->num_values, orig2->num_values); orig2 = new_msg_element(*state, "test", 12, 2); assert_element_equal(el2, orig2); /* test the empty el against the full elements */ ret = ldb_msg_find_common_values(NULL, *state, el, empty, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, empty, el, 0); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, el, empty, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); ret = ldb_msg_find_common_values(NULL, *state, empty, el, remove_dupes); assert_int_equal(ret, LDB_SUCCESS); assert_element_equal(el, orig); assert_element_equal(empty, el3); /* make sure an identical element with a different name is rejected */ el2 = new_msg_element(*state, "fish", 12, 2); ret = ldb_msg_find_common_values(NULL, *state, el2, el, remove_dupes); assert_int_equal(ret, LDB_ERR_INAPPROPRIATE_MATCHING); } int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_ldb_msg_find_duplicate_val, ldb_msg_setup, ldb_msg_teardown), cmocka_unit_test_setup_teardown( test_ldb_msg_find_common_values, ldb_msg_setup, ldb_msg_teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_no_lmdb_test.c0000660000000000000000000000674713573675413017052 0ustar rootroot00000000000000/* * Ensure lmdb backend is disabled * * Copyright (C) Mathieu Parent 2019 * * 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 . * */ /* * Ensure lmdb backend is disabled * * Setup and tear down code copied from ldb_lmdb_test.c */ /* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. * */ #include #include #include #include #include #include #include #include #include #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, LDB_ERR_OTHER); *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_lmdb_not_found(void **state) { // Actual test in ldbtest_setup assert_int_equal(0, 0); } int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown( test_ldb_lmdb_not_found, ldbtest_setup, ldbtest_teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_parse_test.c0000660000000000000000000000434713573675413016544 0ustar rootroot00000000000000/* * Tests exercising the ldb parse operations. * * Copyright (C) Catalyst.NET Ltd 2017 * Copyright (C) Michael Hanselmann 2019 * * 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 . * */ #include #include #include #include #include #include "../include/ldb.h" struct test_ctx { }; static int setup(void **state) { struct test_ctx *ctx; ctx = talloc_zero(NULL, struct test_ctx); assert_non_null(ctx); *state = ctx; return 0; } static int teardown(void **state) { struct test_ctx *ctx = talloc_get_type_abort(*state, struct test_ctx); talloc_free(ctx); return 0; } static void test_roundtrip(TALLOC_CTX *mem_ctx, const char *filter, const char *expected) { struct ldb_parse_tree *tree; char *serialized; assert_non_null(filter); assert_non_null(expected); tree = ldb_parse_tree(mem_ctx, filter); assert_non_null(tree); serialized = ldb_filter_from_tree(mem_ctx, tree); assert_non_null(serialized); assert_string_equal(serialized, expected); } static void test_parse_filtertype(void **state) { struct test_ctx *ctx = talloc_get_type_abort(*state, struct test_ctx); test_roundtrip(ctx, "", "(|(objectClass=*)(distinguishedName=*))"); test_roundtrip(ctx, "a=value", "(a=value)"); test_roundtrip(ctx, "(|(foo=bar)(baz=hello))", "(|(foo=bar)(baz=hello))"); test_roundtrip(ctx, " ", "(|(objectClass=*)(distinguishedName=*))"); } int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_parse_filtertype, setup, teardown), }; cmocka_set_message_output(CM_OUTPUT_SUBUNIT); return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/ldb_tdb_test.c0000660000000000000000000002176313573675413016204 0ustar rootroot00000000000000/* * lmdb backend specific tests for ldb * * Copyright (C) Andrew Bartlett 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 . * */ /* * 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 * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../ldb_tdb/ldb_tdb.h" #include "../ldb_key_value/ldb_kv.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 ldb_kv_private *ldb_kv = NULL; TDB_CONTEXT *tdb = NULL; data = ldb_module_get_private(ldb->modules); assert_non_null(data); ldb_kv = talloc_get_type(data, struct ldb_kv_private); assert_non_null(ldb_kv); tdb = ldb_kv->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); } ldb-2.0.8/tests/photo.ldif0000660000000000000000000000023612406075657015366 0ustar rootroot00000000000000dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST changetype: modify add: jpegPhoto jpegPhoto:< file://tests/samba4.png ldb-2.0.8/tests/python/api.py0000770000000000000000000035075613573675413016064 0ustar rootroot00000000000000#!/usr/bin/env python3 # Simple tests for the ldb python bindings. # Copyright (C) 2007 Jelmer Vernooij import os from unittest import TestCase import sys import gc import time import ldb import shutil 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 try: dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") except KeyError: dir_prefix = None return tempfile.mkdtemp(dir=dir_prefix) class NoContextTests(TestCase): def test_valid_attr_name(self): self.assertTrue(ldb.valid_attr_name("foo")) self.assertFalse(ldb.valid_attr_name("24foo")) def test_timestring(self): self.assertEqual("19700101000000.0Z", ldb.timestring(0)) self.assertEqual("20071119191012.0Z", ldb.timestring(1195499412)) def test_string_to_time(self): self.assertEqual(0, ldb.string_to_time("19700101000000.0Z")) self.assertEqual(1195499412, ldb.string_to_time("20071119191012.0Z")) def test_binary_encode(self): encoded = ldb.binary_encode(b'test\\x') decoded = ldb.binary_decode(encoded) self.assertEqual(decoded, b'test\\x') encoded2 = ldb.binary_encode('test\\x') self.assertEqual(encoded2, encoded) class LdbBaseTest(TestCase): def setUp(self): super(LdbBaseTest, self).setUp() try: if self.prefix is None: self.prefix = TDB_PREFIX except AttributeError: self.prefix = TDB_PREFIX def tearDown(self): super(LdbBaseTest, self).tearDown() def url(self): return self.prefix + self.filename def flags(self): if self.prefix == MDB_PREFIX: return ldb.FLG_NOSYNC else: return 0 class SimpleLdb(LdbBaseTest): def setUp(self): super(SimpleLdb, self).setUp() 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) super(SimpleLdb, self).tearDown() # Ensure the LDB is closed now, so we close the FD del(self.ldb) def test_connect(self): ldb.Ldb(self.url(), flags=self.flags()) def test_connect_none(self): ldb.Ldb() def test_connect_later(self): x = ldb.Ldb() x.connect(self.url(), flags=self.flags()) def test_repr(self): x = ldb.Ldb() self.assertTrue(repr(x).startswith("]", repr(x.modules())) def test_firstmodule_none(self): x = ldb.Ldb() self.assertEqual(x.firstmodule, None) def test_firstmodule_tdb(self): x = ldb.Ldb(self.url(), flags=self.flags()) mod = x.firstmodule self.assertEqual(repr(mod), "") def test_search(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(len(l.search()), 0) def test_search_controls(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(len(l.search(controls=["paged_results:0:5"])), 0) def test_utf8_ldb_Dn(self): l = ldb.Ldb(self.url(), flags=self.flags()) dn = ldb.Dn(l, (b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc').decode('utf8')) def test_utf8_encoded_ldb_Dn(self): l = ldb.Ldb(self.url(), flags=self.flags()) dn_encoded_utf8 = b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc' try: dn = ldb.Dn(l, dn_encoded_utf8) except UnicodeDecodeError as e: raise except TypeError as te: if PY3: p3errors = ["argument 2 must be str, not bytes", "Can't convert 'bytes' object to str implicitly"] self.assertIn(str(te), p3errors) else: raise def test_search_attrs(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) def test_search_string_dn(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) def test_search_attr_string(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertRaises(TypeError, l.search, attrs="dc") self.assertRaises(TypeError, l.search, attrs=b"dc") def test_opaque(self): l = ldb.Ldb(self.url(), flags=self.flags()) l.set_opaque("my_opaque", l) self.assertTrue(l.get_opaque("my_opaque") is not None) self.assertEqual(None, l.get_opaque("unknown")) def test_search_scope_base_empty_db(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"), ldb.SCOPE_BASE)), 0) def test_search_scope_onelevel_empty_db(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"), ldb.SCOPE_ONELEVEL)), 0) def test_delete(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2"))) def test_delete_w_unhandled_ctrl(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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) def test_contains(self): name = self.url() l = ldb.Ldb(name, flags=self.flags()) self.assertFalse(ldb.Dn(l, "dc=foo3") in l) l = ldb.Ldb(name, flags=self.flags()) 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) self.assertFalse(ldb.Dn(l, "dc=foo4") in l) finally: l.delete(m.dn) def test_get_config_basedn(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(None, l.get_config_basedn()) def test_get_root_basedn(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(None, l.get_root_basedn()) def test_get_schema_basedn(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(None, l.get_schema_basedn()) def test_get_default_basedn(self): l = ldb.Ldb(self.url(), flags=self.flags()) self.assertEqual(None, l.get_default_basedn()) def test_add(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo4")) def test_search_iterator(self): l = ldb.Ldb(self.url(), flags=self.flags()) s = l.search_iterator() s.abandon() try: for me in s: self.fail() self.fail() except RuntimeError as re: pass try: s.abandon() self.fail() except RuntimeError as re: pass try: s.result() self.fail() except RuntimeError as re: pass s = l.search_iterator() count = 0 for me in s: self.assertTrue(isinstance(me, ldb.Message)) count += 1 r = s.result() self.assertEqual(len(r), 0) self.assertEqual(count, 0) 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() msgs = [] for me in s: self.assertTrue(isinstance(me, ldb.Message)) count += 1 msgs.append(me) r = s.result() self.assertEqual(len(r), 0) self.assertEqual(len(msgs), 1) self.assertEqual(msgs[0].dn, m1.dn) 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() msgs = [] for me in s: self.assertTrue(isinstance(me, ldb.Message)) count += 1 msgs.append(me) r = s.result() self.assertEqual(len(r), 0) self.assertEqual(len(msgs), 2) if msgs[0].dn == m1.dn: self.assertEqual(msgs[0].dn, m1.dn) self.assertEqual(msgs[1].dn, m2.dn) else: self.assertEqual(msgs[0].dn, m2.dn) self.assertEqual(msgs[1].dn, m1.dn) s = l.search_iterator() msgs = [] for me in s: self.assertTrue(isinstance(me, ldb.Message)) count += 1 msgs.append(me) break try: s.result() self.fail() except RuntimeError as re: pass for me in s: self.assertTrue(isinstance(me, ldb.Message)) count += 1 msgs.append(me) break for me in s: self.fail() r = s.result() self.assertEqual(len(r), 0) self.assertEqual(len(msgs), 2) if msgs[0].dn == m1.dn: self.assertEqual(msgs[0].dn, m1.dn) self.assertEqual(msgs[1].dn, m2.dn) else: self.assertEqual(msgs[0].dn, m2.dn) self.assertEqual(msgs[1].dn, m1.dn) finally: l.delete(ldb.Dn(l, "dc=foo4")) l.delete(ldb.Dn(l, "dc=foo5")) def test_add_text(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo4")) def test_add_w_unhandled_ctrl(self): l = ldb.Ldb(self.url(), flags=self.flags()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=foo4") m["bla"] = b"bla" self.assertEqual(len(l.search()), 0) self.assertRaises(ldb.LdbError, lambda: l.add(m, ["search_options:1:2"])) 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"} self.assertEqual(len(l.search()), 0) l.add(m) try: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo5")) 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"} self.assertEqual(len(l.search()), 0) l.add(m) try: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo5")) 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"} self.assertEqual(len(l.search()), 0) l.add(m) try: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo6")) 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"} self.assertEqual(len(l.search()), 0) l.add(m) try: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo6")) def test_rename(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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: l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar")) self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=bar")) def test_rename_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) try: l.rename("dc=foo8", "dc=bar") self.assertEqual(len(l.search()), 1) 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())) rm = l.search(m.dn) self.assertEqual(1, len(rm)) self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), set(rm[0].keys())) rm = l.search(m.dn, attrs=["blah"]) self.assertEqual(1, len(rm)) self.assertEqual(0, len(rm[0])) def test_modify_delete(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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"])) try: m = ldb.Message() m.dn = ldb.Dn(l, "dc=modifydelete") m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags()) l.modify(m) rm = l.search(m.dn) self.assertEqual(1, len(rm)) self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), set(rm[0].keys())) rm = l.search(m.dn, attrs=["bla"]) self.assertEqual(1, len(rm)) self.assertEqual(0, len(rm[0])) finally: l.delete(ldb.Dn(l, "dc=modifydelete")) def test_modify_delete_text(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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"])) try: m = ldb.Message() m.dn = ldb.Dn(l, "dc=modifydelete") m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags()) l.modify(m) rm = l.search(m.dn) self.assertEqual(1, len(rm)) self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), set(rm[0].keys())) rm = l.search(m.dn, attrs=["bla"]) self.assertEqual(1, len(rm)) self.assertEqual(0, len(rm[0])) finally: l.delete(ldb.Dn(l, "dc=modifydelete")) def test_modify_add(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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() m.dn = ldb.Dn(l, "dc=add") m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") 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([b"1234", b"456"], list(rm["bla"])) finally: l.delete(ldb.Dn(l, "dc=add")) def test_modify_add_text(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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() m.dn = ldb.Dn(l, "dc=add") m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") 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(["1234", "456"], list(rm.text["bla"])) finally: l.delete(ldb.Dn(l, "dc=add")) def test_modify_replace(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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() m.dn = ldb.Dn(l, "dc=modify2") m["bla"] = ldb.MessageElement([b"789"], ldb.FLAG_MOD_REPLACE, "bla") 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([b"789"], list(rm["bla"])) rm = l.search(m.dn, attrs=["bla"])[0] self.assertEqual(1, len(rm)) finally: l.delete(ldb.Dn(l, "dc=modify2")) def test_modify_replace_text(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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() m.dn = ldb.Dn(l, "dc=modify2") m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla") 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(["789"], list(rm.text["bla"])) rm = l.search(m.dn, attrs=["bla"])[0] self.assertEqual(1, len(rm)) finally: l.delete(ldb.Dn(l, "dc=modify2")) def test_modify_flags_change(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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() m.dn = ldb.Dn(l, "dc=add") m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") 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([b"1234", b"456"], list(rm["bla"])) # Now create another modify, but switch the flags before we do it m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") m["bla"].set_flags(ldb.FLAG_MOD_DELETE) l.modify(m) rm = l.search(m.dn, attrs=["bla"])[0] self.assertEqual(1, len(rm)) self.assertEqual([b"1234"], list(rm["bla"])) finally: l.delete(ldb.Dn(l, "dc=add")) def test_modify_flags_change_text(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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() m.dn = ldb.Dn(l, "dc=add") m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") 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(["1234", "456"], list(rm.text["bla"])) # Now create another modify, but switch the flags before we do it m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") m["bla"].set_flags(ldb.FLAG_MOD_DELETE) l.modify(m) rm = l.search(m.dn, attrs=["bla"])[0] self.assertEqual(1, len(rm)) self.assertEqual(["1234"], list(rm.text["bla"])) finally: l.delete(ldb.Dn(l, "dc=add")) def test_transaction_commit(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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) def test_transaction_cancel(self): l = ldb.Ldb(self.url(), flags=self.flags()) 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")))) def test_set_debug(self): def my_report_fn(level, text): pass l = ldb.Ldb(self.url(), flags=self.flags()) l.set_debug(my_report_fn) def test_zero_byte_string(self): """Testing we do not get trapped in the \0 byte in a property string.""" l = ldb.Ldb(self.url(), flags=self.flags()) l.add({ "dn": b"dc=somedn", "objectclass": b"user", "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]) def test_no_crash_broken_expr(self): 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): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX self.index = MDB_INDEX_OBJ super(SimpleLdbLmdb, self).setUp() def tearDown(self): super(SimpleLdbLmdb, self).tearDown() class SimpleLdbNoLmdb(LdbBaseTest): def setUp(self): if os.environ.get('HAVE_LMDB', '1') != '0': self.skipTest("lmdb backend enabled") self.prefix = MDB_PREFIX self.index = MDB_INDEX_OBJ super(SimpleLdbNoLmdb, self).setUp() def tearDown(self): super(SimpleLdbNoLmdb, self).tearDown() def test_lmdb_disabled(self): self.testdir = tempdir() self.filename = os.path.join(self.testdir, "test.ldb") try: self.ldb = ldb.Ldb(self.url(), flags=self.flags()) self.fail("Should have failed on missing LMDB") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_OTHER) class SearchTests(LdbBaseTest): def tearDown(self): shutil.rmtree(self.testdir) super(SearchTests, self).tearDown() # Ensure the LDB is closed now, so we close the FD del(self.l) def setUp(self): super(SearchTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "search_test.ldb") options = ["modules:rdn_name"] if hasattr(self, 'IDXCHECK'): options.append("disable_full_db_scan_for_self_test:1") self.l = ldb.Ldb(self.url(), flags=self.flags(), options=options) try: self.l.add(self.index) except AttributeError: pass self.l.add({"dn": "@ATTRIBUTES", "DC": "CASE_INSENSITIVE"}) # Note that we can't use the name objectGUID here, as we # want to stay clear of the objectGUID handler in LDB and # instead use just the 16 bytes raw, which we just keep # to printable chars here for ease of handling. self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": b"samba.org", "objectUUID": b"0123456789abcdef"}) self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": b"Users", "x": "z", "y": "a", "objectUUID": b"0123456789abcde2"}) self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": b"OU #1", "x": "y", "y": "a", "objectUUID": b"0123456789abcde3"}) self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": b"OU #2", "x": "y", "y": "a", "objectUUID": b"0123456789abcde4"}) self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": b"OU #3", "x": "y", "y": "a", "objectUUID": b"0123456789abcde5"}) self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": b"OU #4", "x": "y", "y": "a", "objectUUID": b"0123456789abcde6"}) self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": b"OU #5", "x": "y", "y": "a", "objectUUID": b"0123456789abcde7"}) self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": b"OU #6", "x": "y", "y": "a", "objectUUID": b"0123456789abcde8"}) self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": b"OU #7", "x": "y", "y": "a", "objectUUID": b"0123456789abcde9"}) self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": b"OU #8", "x": "y", "y": "a", "objectUUID": b"0123456789abcde0"}) self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": b"OU #9", "x": "y", "y": "a", "objectUUID": b"0123456789abcdea"}) self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "y", "y": "a", "objectUUID": b"0123456789abcdeb"}) self.l.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "y", "y": "a", "objectUUID": b"0123456789abcdec"}) self.l.add({"dn": "OU=OU12,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "y", "y": "b", "objectUUID": b"0123456789abcded"}) self.l.add({"dn": "OU=OU13,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcdee"}) self.l.add({"dn": "OU=OU14,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcd01"}) self.l.add({"dn": "OU=OU15,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcd02"}) self.l.add({"dn": "OU=OU16,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcd03"}) self.l.add({"dn": "OU=OU17,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcd04"}) self.l.add({"dn": "OU=OU18,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcd05"}) self.l.add({"dn": "OU=OU19,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcd06"}) self.l.add({"dn": "OU=OU20,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "b", "objectUUID": b"0123456789abcd07"}) self.l.add({"dn": "OU=OU21,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "c", "objectUUID": b"0123456789abcd08"}) self.l.add({"dn": "OU=OU22,DC=SAMBA,DC=ORG", "name": b"OU #10", "x": "x", "y": "c", "objectUUID": b"0123456789abcd09"}) def test_base(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE) self.assertEqual(len(res11), 1) def test_base_lower(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=samba,DC=org", scope=ldb.SCOPE_BASE) self.assertEqual(len(res11), 1) def test_base_or(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(|(ou=ou11)(ou=ou12))") self.assertEqual(len(res11), 1) def test_base_or2(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(|(x=y)(y=b))") self.assertEqual(len(res11), 1) def test_base_and(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(&(ou=ou11)(ou=ou12))") self.assertEqual(len(res11), 0) def test_base_and2(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(&(x=y)(y=a))") self.assertEqual(len(res11), 1) def test_base_false(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(|(ou=ou13)(ou=ou12))") self.assertEqual(len(res11), 0) def test_check_base_false(self): """Testing a search""" res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(|(ou=ou13)(ou=ou12))") self.assertEqual(len(res11), 0) def test_check_base_error(self): """Testing a search""" checkbaseonsearch = {"dn": "@OPTIONS", "checkBaseOnSearch": b"TRUE"} try: self.l.add(checkbaseonsearch) except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) m = ldb.Message.from_dict(self.l, checkbaseonsearch) self.l.modify(m) try: res11 = self.l.search(base="OU=OU11x,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(|(ou=ou13)(ou=ou12))") self.fail("Should have failed on missing base") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) def test_subtree_and(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(ou=ou11)(ou=ou12))") self.assertEqual(len(res11), 0) def test_subtree_and2(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(x=y)(|(y=b)(y=c)))") self.assertEqual(len(res11), 1) def test_subtree_and2_lower(self): """Testing a search""" res11 = self.l.search(base="DC=samba,DC=org", scope=ldb.SCOPE_SUBTREE, expression="(&(x=y)(|(y=b)(y=c)))") self.assertEqual(len(res11), 1) def test_subtree_or(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(|(ou=ou11)(ou=ou12))") self.assertEqual(len(res11), 2) def test_subtree_or2(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(|(x=y)(y=b))") self.assertEqual(len(res11), 20) def test_subtree_or3(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(|(x=y)(y=b)(y=c))") self.assertEqual(len(res11), 22) def test_one_and(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression="(&(ou=ou11)(ou=ou12))") self.assertEqual(len(res11), 0) def test_one_and2(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression="(&(x=y)(y=b))") self.assertEqual(len(res11), 1) def test_one_or(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression="(|(ou=ou11)(ou=ou12))") self.assertEqual(len(res11), 2) def test_one_or2(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression="(|(x=y)(y=b))") self.assertEqual(len(res11), 20) def test_one_or2_lower(self): """Testing a search""" res11 = self.l.search(base="DC=samba,DC=org", scope=ldb.SCOPE_ONELEVEL, expression="(|(x=y)(y=b))") self.assertEqual(len(res11), 20) def test_one_unindexable(self): """Testing a search""" try: res11 = self.l.search(base="DC=samba,DC=org", scope=ldb.SCOPE_ONELEVEL, expression="(y=b*)") if hasattr(self, 'IDX') and \ not hasattr(self, 'IDXONE') and \ hasattr(self, 'IDXCHECK'): self.fail("Should have failed as un-indexed search") self.assertEqual(len(res11), 9) except ldb.LdbError as err: enum = err.args[0] estr = err.args[1] self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) self.assertIn(estr, "ldb FULL SEARCH disabled") def test_one_unindexable_presence(self): """Testing a search""" try: res11 = self.l.search(base="DC=samba,DC=org", scope=ldb.SCOPE_ONELEVEL, expression="(y=*)") if hasattr(self, 'IDX') and \ not hasattr(self, 'IDXONE') and \ hasattr(self, 'IDXCHECK'): self.fail("Should have failed as un-indexed search") self.assertEqual(len(res11), 24) except ldb.LdbError as err: enum = err.args[0] estr = err.args[1] self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) self.assertIn(estr, "ldb FULL SEARCH disabled") def test_subtree_and_or(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(|(x=z)(y=b))(x=x)(y=c))") self.assertEqual(len(res11), 0) def test_subtree_and_or2(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(x=x)(y=c)(|(x=z)(y=b)))") self.assertEqual(len(res11), 0) def test_subtree_and_or3(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(|(ou=ou11)(ou=ou10))(|(x=y)(y=b)(y=c)))") self.assertEqual(len(res11), 2) def test_subtree_and_or4(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(|(x=y)(y=b)(y=c))(|(ou=ou11)(ou=ou10)))") self.assertEqual(len(res11), 2) def test_subtree_and_or5(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(|(x=y)(y=b)(y=c))(ou=ou11))") self.assertEqual(len(res11), 1) def test_subtree_or_and(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(|(x=x)(y=c)(&(x=z)(y=b)))") self.assertEqual(len(res11), 10) def test_subtree_large_and_unique(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(ou=ou10)(y=a))") self.assertEqual(len(res11), 1) def test_subtree_and_none(self): """Testing a search""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(&(ou=ouX)(y=a))") self.assertEqual(len(res11), 0) def test_subtree_and_idx_record(self): """Testing a search against the index record""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(@IDXDN=DC=SAMBA,DC=ORG)") self.assertEqual(len(res11), 0) def test_subtree_and_idxone_record(self): """Testing a search against the index record""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(@IDXONE=DC=SAMBA,DC=ORG)") self.assertEqual(len(res11), 0) def test_subtree_unindexable(self): """Testing a search""" try: res11 = self.l.search(base="DC=samba,DC=org", scope=ldb.SCOPE_SUBTREE, expression="(y=b*)") if hasattr(self, 'IDX') and \ hasattr(self, 'IDXCHECK'): self.fail("Should have failed as un-indexed search") self.assertEqual(len(res11), 9) except ldb.LdbError as err: enum = err.args[0] estr = err.args[1] self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) self.assertIn(estr, "ldb FULL SEARCH disabled") def test_subtree_unindexable_presence(self): """Testing a search""" try: res11 = self.l.search(base="DC=samba,DC=org", scope=ldb.SCOPE_SUBTREE, expression="(y=*)") if hasattr(self, 'IDX') and \ hasattr(self, 'IDXCHECK'): self.fail("Should have failed as un-indexed search") self.assertEqual(len(res11), 24) except ldb.LdbError as err: enum = err.args[0] estr = err.args[1] self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) self.assertIn(estr, "ldb FULL SEARCH disabled") def test_dn_filter_one(self): """Testing that a dn= filter succeeds (or fails with disallowDNFilter set and IDXGUID or (IDX and not IDXONE) mode) when the scope is SCOPE_ONELEVEL. This should be made more consistent, but for now lock in the behaviour """ res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") if hasattr(self, 'disallowDNFilter') and \ hasattr(self, 'IDX') and \ (hasattr(self, 'IDXGUID') or ((hasattr(self, 'IDXONE') == False and hasattr(self, 'IDX')))): self.assertEqual(len(res11), 0) else: self.assertEqual(len(res11), 1) def test_dn_filter_subtree(self): """Testing that a dn= filter succeeds (or fails with disallowDNFilter set) when the scope is SCOPE_SUBTREE""" res11 = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") if hasattr(self, 'disallowDNFilter') \ and hasattr(self, 'IDX'): self.assertEqual(len(res11), 0) else: self.assertEqual(len(res11), 1) def test_dn_filter_base(self): """Testing that (incorrectly) a dn= filter works when the scope is SCOPE_BASE""" res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE, expression="(dn=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_distinguishedName_filter_one(self): """Testing that a distinguishedName= filter succeeds when the scope is SCOPE_ONELEVEL. This should be made more consistent, but for now lock in the behaviour """ 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) def test_bad_dn_search_base(self): """Testing with a bad base DN (SCOPE_BASE)""" try: res11 = self.l.search(base="OU=OU1,DC=SAMBA,DCXXX", scope=ldb.SCOPE_BASE) self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) def test_bad_dn_search_one(self): """Testing with a bad base DN (SCOPE_ONELEVEL)""" try: res11 = self.l.search(base="DC=SAMBA,DCXXXX", scope=ldb.SCOPE_ONELEVEL) self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) def test_bad_dn_search_subtree(self): """Testing with a bad base DN (SCOPE_SUBTREE)""" try: res11 = self.l.search(base="DC=SAMBA,DCXXXX", scope=ldb.SCOPE_SUBTREE) self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) # Run the search tests against an lmdb backend class SearchTestsLmdb(SearchTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX self.index = MDB_INDEX_OBJ super(SearchTestsLmdb, self).setUp() def tearDown(self): super(SearchTestsLmdb, self).tearDown() class IndexedSearchTests(SearchTests): """Test searches using the index, to ensure the index doesn't break things""" def setUp(self): super(IndexedSearchTests, self).setUp() self.l.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"]}) self.IDX = True class IndexedCheckSearchTests(IndexedSearchTests): """Test searches using the index, to ensure the index doesn't break things (full scan disabled)""" def setUp(self): self.IDXCHECK = True super(IndexedCheckSearchTests, self).setUp() class IndexedSearchDnFilterTests(SearchTests): """Test searches using the index, to ensure the index doesn't break things""" def setUp(self): super(IndexedSearchDnFilterTests, self).setUp() self.l.add({"dn": "@OPTIONS", "disallowDNFilter": "TRUE"}) self.disallowDNFilter = True self.l.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"]}) self.IDX = True class IndexedAndOneLevelSearchTests(SearchTests): """Test searches using the index including @IDXONE, to ensure the index doesn't break things""" def setUp(self): super(IndexedAndOneLevelSearchTests, self).setUp() self.l.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"], "@IDXONE": [b"1"]}) self.IDX = True self.IDXONE = True class IndexedCheckedAndOneLevelSearchTests(IndexedAndOneLevelSearchTests): """Test searches using the index including @IDXONE, to ensure the index doesn't break things (full scan disabled)""" def setUp(self): self.IDXCHECK = True super(IndexedCheckedAndOneLevelSearchTests, self).setUp() class IndexedAndOneLevelDNFilterSearchTests(SearchTests): """Test searches using the index including @IDXONE, to ensure the index doesn't break things""" def setUp(self): super(IndexedAndOneLevelDNFilterSearchTests, self).setUp() self.l.add({"dn": "@OPTIONS", "disallowDNFilter": "TRUE", "checkBaseOnSearch": "TRUE"}) self.disallowDNFilter = True self.checkBaseOnSearch = True self.l.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"], "@IDXONE": [b"1"]}) self.IDX = True self.IDXONE = True 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.IDXGUID = True self.IDXONE = True 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", "checkBaseOnSearch": "TRUE"}) self.disallowDNFilter = True self.checkBaseOnSearch = True self.IDX = True self.IDXGUID = True 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", "checkBaseOnSearch": "TRUE"}) self.disallowDNFilter = True self.checkBaseOnSearch = True self.IDX = True self.IDXGUID = True self.IDXONE = True class GUIDIndexedSearchTestsLmdb(GUIDIndexedSearchTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX super(GUIDIndexedSearchTestsLmdb, self).setUp() def tearDown(self): super(GUIDIndexedSearchTestsLmdb, self).tearDown() class GUIDIndexedDNFilterSearchTestsLmdb(GUIDIndexedDNFilterSearchTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX super(GUIDIndexedDNFilterSearchTestsLmdb, self).setUp() def tearDown(self): super(GUIDIndexedDNFilterSearchTestsLmdb, self).tearDown() class GUIDAndOneLevelIndexedSearchTestsLmdb(GUIDAndOneLevelIndexedSearchTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).setUp() def tearDown(self): super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).tearDown() class AddModifyTests(LdbBaseTest): def tearDown(self): shutil.rmtree(self.testdir) super(AddModifyTests, self).tearDown() # Ensure the LDB is closed now, so we close the FD del(self.l) def setUp(self): super(AddModifyTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "add_test.ldb") 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"}) self.l.add({"dn": "@ATTRIBUTES", "objectUUID": "UNIQUE_INDEX"}) def test_add_dup(self): self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) try: self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde2"}) self.fail("Should have failed adding dupliate entry") except ldb.LdbError as err: 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", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) self.l.delete("OU=DUP,DC=SAMBA,DC=ORG") self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde2"}) def test_add_move_add(self): self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", "OU=DUP2,DC=SAMBA,DC=ORG") self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde2"}) def test_add_move_fail_move_move(self): self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", "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") self.fail("Should have failed on duplicate DN") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG", "OU=DUP3,DC=SAMBA,DC=ORG") self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", "OU=DUP2,DC=SAMBA,DC=ORG") 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=DUP2,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=DUP3,DC=SAMBA,DC=ORG") def test_move_missing(self): try: self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", "OU=DUP2,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_NO_SUCH_OBJECT) def test_move_missing2(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", "OU=DUP2,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_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", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) 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", "OU=DUP2,DC=SAMBA,DC=ORG") self.fail("Should have failed on duplicate DN") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG", "OU=DUP3,DC=SAMBA,DC=ORG") self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde3"}) class AddModifyTestsLmdb(AddModifyTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") 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", b"z"], "@IDXONE": [b"1"]} super(IndexedAddModifyTests, self).setUp() def test_duplicate_GUID(self): try: self.l.add({"dn": "OU=DUPGUID,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcdef"}) self.fail("Should have failed adding dupliate GUID") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) def test_duplicate_name_dup_GUID(self): self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"a123456789abcdef"}) try: self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"a123456789abcdef"}) self.fail("Should have failed adding dupliate GUID") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) def test_duplicate_name_dup_GUID2(self): self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"abc3456789abcdef"}) try: self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"aaa3456789abcdef"}) self.fail("Should have failed adding dupliate DN") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) # Checking the GUID didn't stick in the index self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"aaa3456789abcdef"}) def test_add_dup_guid_add(self): self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) try: self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde1"}) self.fail("Should have failed on duplicate GUID") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", "name": b"Admins", "x": "z", "y": "a", "objectUUID": b"0123456789abcde2"}) def test_duplicate_index_values(self): self.l.add({"dn": "OU=DIV1,DC=SAMBA,DC=ORG", "name": b"Admins", "z": "1", "objectUUID": b"0123456789abcdff"}) self.l.add({"dn": "OU=DIV2,DC=SAMBA,DC=ORG", "name": b"Admins", "z": "1", "objectUUID": b"0123456789abcdfd"}) 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() class GUIDTransIndexedAddModifyTests(GUIDIndexedAddModifyTests): """Test GUID index behaviour insdie the transaction""" def setUp(self): super(GUIDTransIndexedAddModifyTests, self).setUp() self.l.transaction_start() def tearDown(self): self.l.transaction_commit() super(GUIDTransIndexedAddModifyTests, self).tearDown() class TransIndexedAddModifyTests(IndexedAddModifyTests): """Test index behaviour insdie the transaction""" def setUp(self): super(TransIndexedAddModifyTests, self).setUp() self.l.transaction_start() def tearDown(self): self.l.transaction_commit() super(TransIndexedAddModifyTests, self).tearDown() class GuidIndexedAddModifyTestsLmdb(GUIDIndexedAddModifyTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX super(GuidIndexedAddModifyTestsLmdb, self).setUp() def tearDown(self): super(GuidIndexedAddModifyTestsLmdb, self).tearDown() class GuidTransIndexedAddModifyTestsLmdb(GUIDTransIndexedAddModifyTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX super(GuidTransIndexedAddModifyTestsLmdb, self).setUp() def tearDown(self): super(GuidTransIndexedAddModifyTestsLmdb, self).tearDown() class BadIndexTests(LdbBaseTest): def setUp(self): super(BadIndexTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "test.ldb") self.ldb = ldb.Ldb(self.url(), flags=self.flags()) if hasattr(self, 'IDXGUID'): self.ldb.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"], "@IDXGUID": [b"objectUUID"], "@IDX_DN_GUID": [b"GUID"]}) else: self.ldb.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"]}) super(BadIndexTests, self).setUp() def test_unique(self): self.ldb.add({"dn": "x=x,dc=samba,dc=org", "objectUUID": b"0123456789abcde1", "y": "1"}) self.ldb.add({"dn": "x=y,dc=samba,dc=org", "objectUUID": b"0123456789abcde2", "y": "1"}) self.ldb.add({"dn": "x=z,dc=samba,dc=org", "objectUUID": b"0123456789abcde3", "y": "1"}) res = self.ldb.search(expression="(y=1)", base="dc=samba,dc=org") self.assertEqual(len(res), 3) # Now set this to unique index, but forget to check the result try: self.ldb.add({"dn": "@ATTRIBUTES", "y": "UNIQUE_INDEX"}) self.fail() except ldb.LdbError: pass # We must still have a working index res = self.ldb.search(expression="(y=1)", base="dc=samba,dc=org") self.assertEqual(len(res), 3) def test_unique_transaction(self): self.ldb.add({"dn": "x=x,dc=samba,dc=org", "objectUUID": b"0123456789abcde1", "y": "1"}) self.ldb.add({"dn": "x=y,dc=samba,dc=org", "objectUUID": b"0123456789abcde2", "y": "1"}) self.ldb.add({"dn": "x=z,dc=samba,dc=org", "objectUUID": b"0123456789abcde3", "y": "1"}) res = self.ldb.search(expression="(y=1)", base="dc=samba,dc=org") self.assertEqual(len(res), 3) self.ldb.transaction_start() # Now set this to unique index, but forget to check the result try: self.ldb.add({"dn": "@ATTRIBUTES", "y": "UNIQUE_INDEX"}) except ldb.LdbError: pass try: self.ldb.transaction_commit() self.fail() except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) # We must still have a working index res = self.ldb.search(expression="(y=1)", base="dc=samba,dc=org") self.assertEqual(len(res), 3) def test_casefold(self): self.ldb.add({"dn": "x=x,dc=samba,dc=org", "objectUUID": b"0123456789abcde1", "y": "a"}) self.ldb.add({"dn": "x=y,dc=samba,dc=org", "objectUUID": b"0123456789abcde2", "y": "A"}) self.ldb.add({"dn": "x=z,dc=samba,dc=org", "objectUUID": b"0123456789abcde3", "y": ["a", "A"]}) res = self.ldb.search(expression="(y=a)", base="dc=samba,dc=org") self.assertEqual(len(res), 2) self.ldb.add({"dn": "@ATTRIBUTES", "y": "CASE_INSENSITIVE"}) # We must still have a working index res = self.ldb.search(expression="(y=a)", base="dc=samba,dc=org") if hasattr(self, 'IDXGUID'): self.assertEqual(len(res), 3) else: # We should not return this entry twice, but sadly # we have not yet fixed # https://bugzilla.samba.org/show_bug.cgi?id=13361 self.assertEqual(len(res), 4) def test_casefold_transaction(self): self.ldb.add({"dn": "x=x,dc=samba,dc=org", "objectUUID": b"0123456789abcde1", "y": "a"}) self.ldb.add({"dn": "x=y,dc=samba,dc=org", "objectUUID": b"0123456789abcde2", "y": "A"}) self.ldb.add({"dn": "x=z,dc=samba,dc=org", "objectUUID": b"0123456789abcde3", "y": ["a", "A"]}) res = self.ldb.search(expression="(y=a)", base="dc=samba,dc=org") self.assertEqual(len(res), 2) self.ldb.transaction_start() self.ldb.add({"dn": "@ATTRIBUTES", "y": "CASE_INSENSITIVE"}) self.ldb.transaction_commit() # We must still have a working index res = self.ldb.search(expression="(y=a)", base="dc=samba,dc=org") if hasattr(self, 'IDXGUID'): self.assertEqual(len(res), 3) else: # We should not return this entry twice, but sadly # we have not yet fixed # https://bugzilla.samba.org/show_bug.cgi?id=13361 self.assertEqual(len(res), 4) def test_modify_transaction(self): self.ldb.add({"dn": "x=y,dc=samba,dc=org", "objectUUID": b"0123456789abcde1", "y": "2", "z": "2"}) res = self.ldb.search(expression="(y=2)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) self.ldb.add({"dn": "@ATTRIBUTES", "y": "UNIQUE_INDEX"}) self.ldb.transaction_start() m = ldb.Message() m.dn = ldb.Dn(self.ldb, "x=y,dc=samba,dc=org") m["0"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "y") m["1"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "not-here") try: self.ldb.modify(m) self.fail() except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) try: self.ldb.transaction_commit() # We should fail here, but we want to be sure # we fail below except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) # The index should still be pointing to x=y res = self.ldb.search(expression="(y=2)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) try: self.ldb.add({"dn": "x=y2,dc=samba,dc=org", "objectUUID": b"0123456789abcde2", "y": "2"}) self.fail("Added unique attribute twice") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) res = self.ldb.search(expression="(y=2)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) self.assertEqual(str(res[0].dn), "x=y,dc=samba,dc=org") def tearDown(self): super(BadIndexTests, self).tearDown() class GUIDBadIndexTests(BadIndexTests): """Test Bad index things with GUID index mode""" def setUp(self): self.IDXGUID = True super(GUIDBadIndexTests, self).setUp() class GUIDBadIndexTestsLmdb(BadIndexTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX self.index = MDB_INDEX_OBJ self.IDXGUID = True super(GUIDBadIndexTestsLmdb, self).setUp() def tearDown(self): super(GUIDBadIndexTestsLmdb, self).tearDown() class BatchModeTests(LdbBaseTest): def setUp(self): super(BatchModeTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "test.ldb") self.ldb = ldb.Ldb(self.url(), flags=self.flags(), options=["batch_mode:1"]) if hasattr(self, 'IDXGUID'): self.ldb.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"], "@IDXGUID": [b"objectUUID"], "@IDX_DN_GUID": [b"GUID"]}) else: self.ldb.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"]}) def test_modify_transaction(self): self.ldb.add({"dn": "x=y,dc=samba,dc=org", "objectUUID": b"0123456789abcde1", "y": "2", "z": "2"}) res = self.ldb.search(expression="(y=2)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) self.ldb.add({"dn": "@ATTRIBUTES", "y": "UNIQUE_INDEX"}) self.ldb.transaction_start() m = ldb.Message() m.dn = ldb.Dn(self.ldb, "x=y,dc=samba,dc=org") m["0"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "y") m["1"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "not-here") try: self.ldb.modify(m) self.fail() except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) try: self.ldb.transaction_commit() self.fail("Commit should have failed as we were in batch mode") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) def tearDown(self): super(BatchModeTests, self).tearDown() class DnTests(TestCase): def setUp(self): super(DnTests, self).setUp() self.ldb = ldb.Ldb() def tearDown(self): super(DnTests, self).tearDown() del(self.ldb) def test_set_dn_invalid(self): x = ldb.Message() def assign(): x.dn = "astring" self.assertRaises(TypeError, assign) def test_eq(self): x = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") self.assertEqual(x, y) y = ldb.Dn(self.ldb, "dc=foo11,bar=blie") self.assertNotEqual(x, y) def test_str(self): x = ldb.Dn(self.ldb, "dc=foo12,bar=bloe") self.assertEqual(x.__str__(), "dc=foo12,bar=bloe") def test_repr(self): x = ldb.Dn(self.ldb, "dc=foo13,bla=blie") self.assertEqual(x.__repr__(), "Dn('dc=foo13,bla=blie')") def test_get_casefold_2(self): x = ldb.Dn(self.ldb, "dc=foo14,bar=bloe") self.assertEqual(x.get_casefold(), "DC=FOO14,BAR=bloe") def test_validate(self): x = ldb.Dn(self.ldb, "dc=foo15,bar=bloe") self.assertTrue(x.validate()) def test_parent(self): x = ldb.Dn(self.ldb, "dc=foo16,bar=bloe") self.assertEqual("bar=bloe", x.parent().__str__()) def test_parent_nonexistent(self): x = ldb.Dn(self.ldb, "@BLA") self.assertEqual(None, x.parent()) def test_is_valid(self): x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe") self.assertTrue(x.is_valid()) x = ldb.Dn(self.ldb, "") self.assertTrue(x.is_valid()) def test_is_special(self): x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe") self.assertFalse(x.is_special()) x = ldb.Dn(self.ldb, "@FOOBAR") self.assertTrue(x.is_special()) def test_check_special(self): x = ldb.Dn(self.ldb, "dc=foo20,bar=bloe") self.assertFalse(x.check_special("FOOBAR")) x = ldb.Dn(self.ldb, "@FOOBAR") self.assertTrue(x.check_special("@FOOBAR")) def test_len(self): x = ldb.Dn(self.ldb, "dc=foo21,bar=bloe") self.assertEqual(2, len(x)) x = ldb.Dn(self.ldb, "dc=foo21") self.assertEqual(1, len(x)) def test_add_child(self): x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") self.assertTrue(x.add_child(ldb.Dn(self.ldb, "bla=bloe"))) self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__()) def test_add_base(self): x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") base = ldb.Dn(self.ldb, "bla=bloe") self.assertTrue(x.add_base(base)) self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__()) def test_add_child_str(self): x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") self.assertTrue(x.add_child("bla=bloe")) self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__()) def test_add_base_str(self): x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") base = "bla=bloe" self.assertTrue(x.add_base(base)) self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__()) def test_add(self): x = ldb.Dn(self.ldb, "dc=foo24") y = ldb.Dn(self.ldb, "bar=bla") self.assertEqual("dc=foo24,bar=bla", str(x + y)) def test_remove_base_components(self): x = ldb.Dn(self.ldb, "dc=foo24,dc=samba,dc=org") x.remove_base_components(len(x) - 1) self.assertEqual("dc=foo24", str(x)) def test_parse_ldif(self): msgs = self.ldb.parse_ldif("dn: foo=bar\n") msg = next(msgs) self.assertEqual("foo=bar", str(msg[1].dn)) self.assertTrue(isinstance(msg[1], ldb.Message)) ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) self.assertEqual("dn: foo=bar\n\n", ldif) def test_parse_ldif_more(self): msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") msg = next(msgs) self.assertEqual("foo=bar", str(msg[1].dn)) msg = next(msgs) self.assertEqual("bar=bar", str(msg[1].dn)) def test_print_ldif(self): ldif = '''dn: dc=foo27 foo: foo ''' self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) self.msg["foo"] = [b"foo"] self.assertEqual(ldif, self.ldb.write_ldif(self.msg, ldb.CHANGETYPE_NONE)) def test_print_ldif_binary(self): # this also confirms that ldb flags are set even without a URL) self.ldb = ldb.Ldb(flags=ldb.FLG_SHOW_BINARY) ldif = '''dn: dc=foo27 foo: f öö ''' self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) self.msg["foo"] = ["f\nöö"] self.assertEqual(ldif, self.ldb.write_ldif(self.msg, ldb.CHANGETYPE_NONE)) def test_print_ldif_no_base64_bad(self): ldif = '''dn: dc=foo27 foo: f öö ''' self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) self.msg["foo"] = ["f\nöö"] self.msg["foo"].set_flags(ldb.FLAG_FORCE_NO_BASE64_LDIF) self.assertEqual(ldif, self.ldb.write_ldif(self.msg, ldb.CHANGETYPE_NONE)) def test_print_ldif_no_base64_good(self): ldif = '''dn: dc=foo27 foo: föö ''' self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) self.msg["foo"] = ["föö"] self.msg["foo"].set_flags(ldb.FLAG_FORCE_NO_BASE64_LDIF) self.assertEqual(ldif, self.ldb.write_ldif(self.msg, ldb.CHANGETYPE_NONE)) def test_canonical_string(self): x = ldb.Dn(self.ldb, "dc=foo25,bar=bloe") self.assertEqual("/bloe/foo25", x.canonical_str()) def test_canonical_ex_string(self): x = ldb.Dn(self.ldb, "dc=foo26,bar=bloe") self.assertEqual("/bloe\nfoo26", x.canonical_ex_str()) def test_ldb_is_child_of(self): """Testing ldb_dn_compare_dn""" dn1 = ldb.Dn(self.ldb, "dc=base") dn2 = ldb.Dn(self.ldb, "cn=foo,dc=base") 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)) def test_ldb_is_child_of_str(self): """Testing ldb_dn_compare_dn""" dn1_str = "dc=base" dn2_str = "cn=foo,dc=base" dn3_str = "cn=bar,dc=base" dn4_str = "cn=baz,cn=bar,dc=base" dn1 = ldb.Dn(self.ldb, dn1_str) dn2 = ldb.Dn(self.ldb, dn2_str) 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)) def test_get_component_name(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") self.assertEqual(dn.get_component_name(0), 'cn') self.assertEqual(dn.get_component_name(1), 'dc') self.assertEqual(dn.get_component_name(2), None) self.assertEqual(dn.get_component_name(-1), None) def test_get_component_value(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") self.assertEqual(dn.get_component_value(0), 'foo') self.assertEqual(dn.get_component_value(1), 'base') self.assertEqual(dn.get_component_name(2), None) self.assertEqual(dn.get_component_name(-1), None) def test_set_component(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") dn.set_component(0, 'cn', 'bar') self.assertEqual(str(dn), "cn=bar,dc=base") dn.set_component(1, 'o', 'asep') self.assertEqual(str(dn), "cn=bar,o=asep") self.assertRaises(TypeError, dn.set_component, 2, 'dc', 'base') self.assertEqual(str(dn), "cn=bar,o=asep") dn.set_component(1, 'o', 'a,b+c') self.assertEqual(str(dn), r"cn=bar,o=a\,b\+c") def test_set_component_bytes(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") dn.set_component(0, 'cn', b'bar') self.assertEqual(str(dn), "cn=bar,dc=base") dn.set_component(1, 'o', b'asep') self.assertEqual(str(dn), "cn=bar,o=asep") def test_set_component_none(self): dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base") self.assertRaises(TypeError, dn.set_component, 1, 'cn', None) def test_get_extended_component_null(self): dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base") self.assertEqual(dn.get_extended_component("TEST"), None) def test_get_extended_component(self): self.ldb._register_test_extensions() dn = ldb.Dn(self.ldb, ";cn=bar,dc=base") self.assertEqual(dn.get_extended_component("TEST"), b"foo") def test_set_extended_component(self): self.ldb._register_test_extensions() dn = ldb.Dn(self.ldb, "dc=base") dn.set_extended_component("TEST", "foo") self.assertEqual(dn.get_extended_component("TEST"), b"foo") dn.set_extended_component("TEST", b"bar") self.assertEqual(dn.get_extended_component("TEST"), b"bar") def test_extended_str(self): self.ldb._register_test_extensions() dn = ldb.Dn(self.ldb, ";cn=bar,dc=base") self.assertEqual(dn.extended_str(), ";cn=bar,dc=base") def test_get_rdn_name(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") self.assertEqual(dn.get_rdn_name(), 'cn') def test_get_rdn_value(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") self.assertEqual(dn.get_rdn_value(), 'foo') def test_get_casefold(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") self.assertEqual(dn.get_casefold(), 'CN=FOO,DC=BASE') def test_get_linearized(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") self.assertEqual(dn.get_linearized(), 'cn=foo,dc=base') def test_is_null(self): dn = ldb.Dn(self.ldb, "cn=foo,dc=base") self.assertFalse(dn.is_null()) dn = ldb.Dn(self.ldb, '') self.assertTrue(dn.is_null()) class LdbMsgTests(TestCase): def setUp(self): super(LdbMsgTests, self).setUp() self.msg = ldb.Message() def test_init_dn(self): self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo27")) self.assertEqual("dc=foo27", str(self.msg.dn)) def test_iter_items(self): self.assertEqual(0, len(self.msg.items())) self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo28") self.assertEqual(1, len(self.msg.items())) def test_repr(self): self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo29") self.msg["dc"] = b"foo" if PY3: self.assertIn(repr(self.msg), [ "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])})", "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')})", ]) self.assertIn(repr(self.msg.text), [ "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])}).text", "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')}).text", ]) else: self.assertIn(repr(self.msg), [ "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", "Message({'dc': MessageElement(['foo']), 'dn': Dn('dc=foo29')})", ]) self.assertIn(repr(self.msg.text), [ "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])}).text", "Message({'dc': MessageElement(['foo']), 'dn': Dn('dc=foo29')}).text", ]) def test_len(self): self.assertEqual(0, len(self.msg)) def test_notpresent(self): self.assertRaises(KeyError, lambda: self.msg["foo"]) def test_del(self): del self.msg["foo"] def test_add(self): self.msg.add(ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")) def test_add_text(self): self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")) def test_elements_empty(self): self.assertEqual([], self.msg.elements()) def test_elements(self): el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") self.msg.add(el) self.assertEqual([el], self.msg.elements()) self.assertEqual([el.text], self.msg.text.elements()) def test_add_value(self): self.assertEqual(0, len(self.msg)) self.msg["foo"] = [b"foo"] self.assertEqual(1, len(self.msg)) def test_add_value_text(self): self.assertEqual(0, len(self.msg)) self.msg["foo"] = ["foo"] self.assertEqual(1, len(self.msg)) def test_add_value_multiple(self): self.assertEqual(0, len(self.msg)) self.msg["foo"] = [b"foo", b"bla"] self.assertEqual(1, len(self.msg)) self.assertEqual([b"foo", b"bla"], list(self.msg["foo"])) def test_add_value_multiple_text(self): self.assertEqual(0, len(self.msg)) self.msg["foo"] = ["foo", "bla"] self.assertEqual(1, len(self.msg)) self.assertEqual(["foo", "bla"], list(self.msg.text["foo"])) def test_set_value(self): self.msg["foo"] = [b"fool"] self.assertEqual([b"fool"], list(self.msg["foo"])) self.msg["foo"] = [b"bar"] self.assertEqual([b"bar"], list(self.msg["foo"])) def test_set_value_text(self): self.msg["foo"] = ["fool"] self.assertEqual(["fool"], list(self.msg.text["foo"])) self.msg["foo"] = ["bar"] self.assertEqual(["bar"], list(self.msg.text["foo"])) def test_keys(self): 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())) 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())) def test_dn(self): self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") self.assertEqual("@BASEINFO", self.msg.dn.__str__()) def test_get_dn(self): self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") self.assertEqual("@BASEINFO", self.msg.get("dn").__str__()) def test_dn_text(self): self.msg.text.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") self.assertEqual("@BASEINFO", str(self.msg.dn)) self.assertEqual("@BASEINFO", str(self.msg.text.dn)) def test_get_dn_text(self): self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") self.assertEqual("@BASEINFO", str(self.msg.get("dn"))) self.assertEqual("@BASEINFO", str(self.msg.text.get("dn"))) def test_get_invalid(self): self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") self.assertRaises(TypeError, self.msg.get, 42) def test_get_other(self): self.msg["foo"] = [b"bar"] self.assertEqual(b"bar", self.msg.get("foo")[0]) self.assertEqual(b"bar", self.msg.get("foo", idx=0)) self.assertEqual(None, self.msg.get("foo", idx=1)) self.assertEqual("", self.msg.get("foo", default='', idx=1)) def test_get_other_text(self): self.msg["foo"] = ["bar"] self.assertEqual(["bar"], list(self.msg.text.get("foo"))) self.assertEqual("bar", self.msg.text.get("foo")[0]) self.assertEqual("bar", self.msg.text.get("foo", idx=0)) self.assertEqual(None, self.msg.get("foo", idx=1)) self.assertEqual("", self.msg.get("foo", default='', idx=1)) def test_get_default(self): self.assertEqual(None, self.msg.get("tatayoyo", idx=0)) self.assertEqual("anniecordie", self.msg.get("tatayoyo", "anniecordie")) def test_get_default_text(self): self.assertEqual(None, self.msg.text.get("tatayoyo", idx=0)) self.assertEqual("anniecordie", self.msg.text.get("tatayoyo", "anniecordie")) def test_get_unknown(self): self.assertEqual(None, self.msg.get("lalalala")) def test_get_unknown_text(self): self.assertEqual(None, self.msg.text.get("lalalala")) def test_msg_diff(self): l = ldb.Ldb() msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n") msg1 = next(msgs)[1] msg2 = next(msgs)[1] msgdiff = l.msg_diff(msg1, msg2) self.assertEqual("foo=bar", msgdiff.get("dn").__str__()) self.assertRaises(KeyError, lambda: msgdiff["foo"]) self.assertEqual(1, len(msgdiff)) def test_equal_empty(self): msg1 = ldb.Message() msg2 = ldb.Message() self.assertEqual(msg1, msg2) def test_equal_simplel(self): db = ldb.Ldb() msg1 = ldb.Message() msg1.dn = ldb.Dn(db, "foo=bar") msg2 = ldb.Message() msg2.dn = ldb.Dn(db, "foo=bar") self.assertEqual(msg1, msg2) msg1['foo'] = b'bar' msg2['foo'] = b'bar' self.assertEqual(msg1, msg2) msg2['foo'] = b'blie' self.assertNotEqual(msg1, msg2) msg2['foo'] = b'blie' def test_from_dict(self): rec = {"dn": "dc=fromdict", "a1": [b"a1-val1", b"a1-val1"]} l = ldb.Ldb() # check different types of input Flags for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: m = ldb.Message.from_dict(l, rec, flags) self.assertEqual(rec["a1"], list(m["a1"])) self.assertEqual(flags, m["a1"].flags()) # check input params self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) # Message.from_dict expects dictionary with 'dn' err_rec = {"a1": [b"a1-val1", b"a1-val1"]} self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) def test_from_dict_text(self): rec = {"dn": "dc=fromdict", "a1": ["a1-val1", "a1-val1"]} l = ldb.Ldb() # check different types of input Flags for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: m = ldb.Message.from_dict(l, rec, flags) self.assertEqual(rec["a1"], list(m.text["a1"])) self.assertEqual(flags, m.text["a1"].flags()) # check input params self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) # Message.from_dict expects dictionary with 'dn' err_rec = {"a1": ["a1-val1", "a1-val1"]} self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) def test_copy_add_message_element(self): m = ldb.Message() m["1"] = ldb.MessageElement([b"val 111"], ldb.FLAG_MOD_ADD, "1") m["2"] = ldb.MessageElement([b"val 222"], ldb.FLAG_MOD_ADD, "2") mto = ldb.Message() mto["1"] = m["1"] mto["2"] = m["2"] self.assertEqual(mto["1"], m["1"]) self.assertEqual(mto["2"], m["2"]) mto = ldb.Message() mto.add(m["1"]) mto.add(m["2"]) self.assertEqual(mto["1"], m["1"]) self.assertEqual(mto["2"], m["2"]) def test_copy_add_message_element_text(self): m = ldb.Message() m["1"] = ldb.MessageElement(["val 111"], ldb.FLAG_MOD_ADD, "1") m["2"] = ldb.MessageElement(["val 222"], ldb.FLAG_MOD_ADD, "2") mto = ldb.Message() mto["1"] = m["1"] mto["2"] = m["2"] self.assertEqual(mto["1"], m.text["1"]) self.assertEqual(mto["2"], m.text["2"]) mto = ldb.Message() mto.add(m["1"]) mto.add(m["2"]) self.assertEqual(mto.text["1"], m.text["1"]) self.assertEqual(mto.text["2"], m.text["2"]) self.assertEqual(mto["1"], m["1"]) self.assertEqual(mto["2"], m["2"]) class MessageElementTests(TestCase): def test_cmp_element(self): x = ldb.MessageElement([b"foo"]) y = ldb.MessageElement([b"foo"]) z = ldb.MessageElement([b"bzr"]) self.assertEqual(x, y) self.assertNotEqual(x, z) def test_cmp_element_text(self): x = ldb.MessageElement([b"foo"]) y = ldb.MessageElement(["foo"]) self.assertEqual(x, y) def test_create_iterable(self): x = ldb.MessageElement([b"foo"]) self.assertEqual([b"foo"], list(x)) self.assertEqual(["foo"], list(x.text)) def test_repr(self): x = ldb.MessageElement([b"foo"]) if PY3: self.assertEqual("MessageElement([b'foo'])", repr(x)) self.assertEqual("MessageElement([b'foo']).text", repr(x.text)) else: self.assertEqual("MessageElement(['foo'])", repr(x)) self.assertEqual("MessageElement(['foo']).text", repr(x.text)) x = ldb.MessageElement([b"foo", b"bla"]) self.assertEqual(2, len(x)) if PY3: self.assertEqual("MessageElement([b'foo',b'bla'])", repr(x)) self.assertEqual("MessageElement([b'foo',b'bla']).text", repr(x.text)) else: self.assertEqual("MessageElement(['foo','bla'])", repr(x)) self.assertEqual("MessageElement(['foo','bla']).text", repr(x.text)) def test_get_item(self): x = ldb.MessageElement([b"foo", b"bar"]) self.assertEqual(b"foo", x[0]) self.assertEqual(b"bar", x[1]) self.assertEqual(b"bar", x[-1]) self.assertRaises(IndexError, lambda: x[45]) def test_get_item_text(self): x = ldb.MessageElement(["foo", "bar"]) self.assertEqual("foo", x.text[0]) self.assertEqual("bar", x.text[1]) self.assertEqual("bar", x.text[-1]) self.assertRaises(IndexError, lambda: x[45]) def test_len(self): x = ldb.MessageElement([b"foo", b"bar"]) self.assertEqual(2, len(x)) def test_eq(self): x = ldb.MessageElement([b"foo", b"bar"]) y = ldb.MessageElement([b"foo", b"bar"]) self.assertEqual(y, x) x = ldb.MessageElement([b"foo"]) self.assertNotEqual(y, x) y = ldb.MessageElement([b"foo"]) self.assertEqual(y, x) def test_extended(self): el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") if PY3: self.assertEqual("MessageElement([b'456'])", repr(el)) self.assertEqual("MessageElement([b'456']).text", repr(el.text)) else: self.assertEqual("MessageElement(['456'])", repr(el)) self.assertEqual("MessageElement(['456']).text", repr(el.text)) def test_bad_text(self): el = ldb.MessageElement(b'\xba\xdd') self.assertRaises(UnicodeDecodeError, el.text.__getitem__, 0) class ModuleTests(TestCase): def setUp(self): super(ModuleTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "test.ldb") self.ldb = ldb.Ldb(self.filename) def tearDown(self): shutil.rmtree(self.testdir) super(ModuleTests, self).setUp() def test_register_module(self): class ExampleModule: name = "example" ldb.register_module(ExampleModule) def test_use_module(self): ops = [] class ExampleModule: name = "bla" def __init__(self, ldb, next): ops.append("init") self.next = next def search(self, *args, **kwargs): return self.next.search(*args, **kwargs) def request(self, *args, **kwargs): pass ldb.register_module(ExampleModule) l = ldb.Ldb(self.filename) l.add({"dn": "@MODULES", "@LIST": "bla"}) self.assertEqual([], ops) l = ldb.Ldb(self.filename) self.assertEqual(["init"], ops) class LdbResultTests(LdbBaseTest): def setUp(self): super(LdbResultTests, self).setUp() 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"}) def tearDown(self): shutil.rmtree(self.testdir) super(LdbResultTests, self).tearDown() # Ensure the LDB is closed now, so we close the FD del(self.l) def test_return_type(self): res = self.l.search() self.assertEqual(str(res), "") def test_get_msgs(self): res = self.l.search() list = res.msgs def test_get_controls(self): res = self.l.search() list = res.controls def test_get_referals(self): res = self.l.search() list = res.referals def test_iter_msgs(self): found = False for l in self.l.search().msgs: if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": found = True self.assertTrue(found) def test_iter_msgs_count(self): self.assertTrue(self.l.search().count > 0) # 13 objects has been added to the DC=SAMBA, DC=ORG self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13) def test_iter_controls(self): res = self.l.search().controls it = iter(res) def test_create_control(self): self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0") c = ldb.Control(self.l, "relax:1") self.assertEqual(c.critical, True) self.assertEqual(c.oid, "1.3.6.1.4.1.4203.666.5.12") def test_iter_refs(self): res = self.l.search().referals it = iter(res) def test_search_sequence_msgs(self): found = False res = self.l.search().msgs for i in range(0, len(res)): l = res[i] if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": found = True self.assertTrue(found) def test_search_as_iter(self): found = False res = self.l.search() for l in res: if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": found = True self.assertTrue(found) def test_search_iter(self): found = False res = self.l.search_iterator() for l in res: if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": found = True self.assertTrue(found) # Show that search results can't see into a transaction def test_search_against_trans(self): found11 = False (r1, w1) = os.pipe() (r2, w2) = os.pipe() # For the first element, fork a child that will # write to the DB pid = os.fork() if pid == 0: # In the child, re-open del(self.l) gc.collect() child_ldb = ldb.Ldb(self.url(), flags=self.flags()) # start a transaction child_ldb.transaction_start() # write to it child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", "name": b"samba.org", "objectUUID": b"o123456789acbdef"}) os.write(w1, b"added") # Now wait for the search to be done os.read(r2, 6) # and commit try: child_ldb.transaction_commit() except ldb.LdbError as err: # We print this here to see what went wrong in the child print(err) os._exit(1) os.write(w1, b"transaction") os._exit(0) self.assertEqual(os.read(r1, 5), b"added") # This should not turn up until the transaction is concluded res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE) self.assertEqual(len(res11), 0) os.write(w2, b"search") # Now wait for the transaction to be done. This should # deadlock, but the search doesn't hold a read lock for the # iterator lifetime currently. self.assertEqual(os.read(r1, 11), b"transaction") # This should now turn up, as the transaction is over res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE) self.assertEqual(len(res11), 1) self.assertFalse(found11) (got_pid, status) = os.waitpid(pid, 0) self.assertEqual(got_pid, pid) def test_search_iter_against_trans(self): found = False found11 = False # We need to hold this iterator open to hold the all-record # lock res = self.l.search_iterator() (r1, w1) = os.pipe() (r2, w2) = os.pipe() # For the first element, with the sequence open (which # means with ldb locks held), fork a child that will # write to the DB pid = os.fork() if pid == 0: # In the child, re-open del(res) del(self.l) gc.collect() child_ldb = ldb.Ldb(self.url(), flags=self.flags()) # start a transaction child_ldb.transaction_start() # write to it child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", "name": b"samba.org", "objectUUID": b"o123456789acbdef"}) os.write(w1, b"added") # Now wait for the search to be done os.read(r2, 6) # and commit try: child_ldb.transaction_commit() except ldb.LdbError as err: # We print this here to see what went wrong in the child print(err) os._exit(1) os.write(w1, b"transaction") os._exit(0) self.assertEqual(os.read(r1, 5), b"added") # This should not turn up until the transaction is concluded res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE) self.assertEqual(len(res11), 0) os.write(w2, b"search") # allow the transaction to start time.sleep(1) # This should not turn up until the search finishes and # removed the read lock, but for ldb_tdb that happened as soon # as we called the first res.next() res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE) self.assertEqual(len(res11), 0) # These results are all collected at the first next(res) call for l in res: if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": found = True if str(l.dn) == "OU=OU11,DC=SAMBA,DC=ORG": found11 = True # Now wait for the transaction to be done. self.assertEqual(os.read(r1, 11), b"transaction") # This should now turn up, as the transaction is over and all # read locks are gone res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE) self.assertEqual(len(res11), 1) self.assertTrue(found) self.assertFalse(found11) (got_pid, status) = os.waitpid(pid, 0) self.assertEqual(got_pid, pid) class LdbResultTestsLmdb(LdbResultTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") 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() self.assertRaises(TypeError, ldb.Control, '', 'relax:1') self.assertRaises(TypeError, ldb.Control, ldb, 1234) def test_modify(self): l = ldb.Ldb() dn = ldb.Dn(l, 'a=b') m = ldb.Message(dn) self.assertRaises(TypeError, l.modify, '') self.assertRaises(TypeError, l.modify, m, '') def test_add(self): l = ldb.Ldb() dn = ldb.Dn(l, 'a=b') m = ldb.Message(dn) self.assertRaises(TypeError, l.add, '') self.assertRaises(TypeError, l.add, m, '') def test_delete(self): l = ldb.Ldb() dn = ldb.Dn(l, 'a=b') self.assertRaises(TypeError, l.add, '') self.assertRaises(TypeError, l.add, dn, '') def test_rename(self): l = ldb.Ldb() dn = ldb.Dn(l, 'a=b') self.assertRaises(TypeError, l.add, '', dn) self.assertRaises(TypeError, l.add, dn, '') self.assertRaises(TypeError, l.add, dn, dn, '') def test_search(self): l = ldb.Ldb() self.assertRaises(TypeError, l.search, base=1234) self.assertRaises(TypeError, l.search, scope='') self.assertRaises(TypeError, l.search, expression=1234) self.assertRaises(TypeError, l.search, attrs='') self.assertRaises(TypeError, l.search, controls='') class VersionTests(TestCase): def test_version(self): self.assertTrue(isinstance(ldb.__version__, str)) class NestedTransactionTests(LdbBaseTest): def setUp(self): super(NestedTransactionTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "test.ldb") self.ldb = ldb.Ldb(self.url(), flags=self.flags()) self.ldb.add({"dn": "@INDEXLIST", "@IDXATTR": [b"x", b"y", b"ou"], "@IDXGUID": [b"objectUUID"], "@IDX_DN_GUID": [b"GUID"]}) super(NestedTransactionTests, self).setUp() # # This test documents that currently ldb does not support true nested # transactions. # # Note: The test is written so that it treats failure as pass. # It is done this way as standalone ldb builds do not use the samba # known fail mechanism # def test_nested_transactions(self): self.ldb.transaction_start() self.ldb.add({"dn": "x=x1,dc=samba,dc=org", "objectUUID": b"0123456789abcde1"}) res = self.ldb.search(expression="(objectUUID=0123456789abcde1)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) self.ldb.add({"dn": "x=x2,dc=samba,dc=org", "objectUUID": b"0123456789abcde2"}) res = self.ldb.search(expression="(objectUUID=0123456789abcde2)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) self.ldb.transaction_start() self.ldb.add({"dn": "x=x3,dc=samba,dc=org", "objectUUID": b"0123456789abcde3"}) res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) self.ldb.transaction_cancel() # # Check that we can not see the record added by the cancelled # transaction. # Currently this fails as ldb does not support true nested # transactions, and only the outer commits and cancels have an effect # res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", base="dc=samba,dc=org") # # FIXME this test currently passes on a failure, i.e. if nested # transaction support worked correctly the correct test would # be. # self.assertEqual(len(res), 0) # as the add of objectUUID=0123456789abcde3 would reverted when # the sub transaction it was nested in was rolled back. # # Currently this is not the case so the record is still present. self.assertEqual(len(res), 1) # Commit the outer transaction # self.ldb.transaction_commit() # # Now check we can still see the records added in the outer # transaction. # res = self.ldb.search(expression="(objectUUID=0123456789abcde1)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) res = self.ldb.search(expression="(objectUUID=0123456789abcde2)", base="dc=samba,dc=org") self.assertEqual(len(res), 1) # # And that we can't see the records added by the nested transaction. # res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", base="dc=samba,dc=org") # FIXME again if nested transactions worked correctly we would not # see this record. The test should be. # self.assertEqual(len(res), 0) self.assertEqual(len(res), 1) def tearDown(self): super(NestedTransactionTests, self).tearDown() class LmdbNestedTransactionTests(NestedTransactionTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX self.index = MDB_INDEX_OBJ super(LmdbNestedTransactionTests, self).setUp() def tearDown(self): super(LmdbNestedTransactionTests, self).tearDown() if __name__ == '__main__': import unittest unittest.TestProgram() ldb-2.0.8/tests/python/index.py0000770000000000000000000016343313573675413016414 0ustar rootroot00000000000000#!/usr/bin/env python3 # # Tests for truncated index keys # # Copyright (C) Andrew Bartlett 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 . # """Tests for truncated index keys Databases such as lmdb have a maximum key length, these tests ensure that ldb behaves correctly in those circumstances. """ import os from unittest import TestCase import sys import ldb import shutil PY3 = sys.version_info > (3, 0) TDB_PREFIX = "tdb://" MDB_PREFIX = "mdb://" def tempdir(): import tempfile try: dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") except KeyError: dir_prefix = None return tempfile.mkdtemp(dir=dir_prefix) def contains(result, dn): if result is None: return False for r in result: if str(r["dn"]) == dn: return True return False class LdbBaseTest(TestCase): def setUp(self): super(LdbBaseTest, self).setUp() try: if self.prefix is None: self.prefix = TDB_PREFIX except AttributeError: self.prefix = TDB_PREFIX def tearDown(self): super(LdbBaseTest, self).tearDown() def url(self): return self.prefix + self.filename def flags(self): if self.prefix == MDB_PREFIX: return ldb.FLG_NOSYNC else: return 0 class MaxIndexKeyLengthTests(LdbBaseTest): def checkGuids(self, key, guids): # # This check relies on the current implementation where the indexes # are in the same database as the data. # # It checks that the index record exists, unless guids is None then # the record must not exist. And the it contains the expected guid # entries. # # The caller needs to provide the GUID's in the expected order # res = self.l.search( base=key, scope=ldb.SCOPE_BASE) if guids is None: self.assertEqual(len(res), 0) return self.assertEqual(len(res), 1) # The GUID index format has only one value index = res[0]["@IDX"][0] self.assertEqual(len(guids), len(index)) self.assertEqual(guids, index) def tearDown(self): shutil.rmtree(self.testdir) super(MaxIndexKeyLengthTests, self).tearDown() # Ensure the LDB is closed now, so we close the FD del(self.l) def setUp(self): 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 # self.l = ldb.Ldb(self.url(), options=[ "modules:rdn_name", "max_key_len_for_self_test:54"]) 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"], "@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): # # For all entries the DN index key gets truncated to # @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") 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 self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", "objectUUID": b"0123456789abcde5"}) self.checkGuids( "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", b"0123456789abcde5") # This key should not get truncated, as it's one character less than # max, and will not be in the truncate name space self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", "objectUUID": b"0123456789abcde7"}) self.checkGuids( "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", b"0123456789abcde7") try: self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", "objectUUID": b"0123456789abcde2"}) except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) try: self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", "objectUUID": b"0123456789abcde3"}) except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) try: self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", "objectUUID": b"0123456789abcde4"}) except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) try: self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", "objectUUID": b"0123456789abcde6"}) except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) try: self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXX,DC=SAMBA", "objectUUID": b"0123456789abcde8"}) except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) def test_rename_truncated_dn_keys(self): # For all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @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: self.l.rename("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) def test_delete_truncated_dn_keys(self): # # For all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @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=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"}) self.checkGuids( "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", b"0123456789abcde5") # Try to delete a non existent DN with a truncated key try: self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") except ldb.LdbError as err: enum = err.args[0] self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) # Ensure that non of the other truncated DN's got deleted res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") self.assertEqual(len(res), 1) res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") self.assertEqual(len(res), 1) # Ensure that the non truncated DN did not get deleted res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") self.assertEqual(len(res), 1) # 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") # delete an existing entry self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") # Ensure it got deleted res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") self.assertEqual(len(res), 0) # Ensure that non of the other truncated DN's got deleted res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") self.assertEqual(len(res), 1) # Ensure the non truncated entry did not get deleted. res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") self.assertEqual(len(res), 1) # 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") # delete an existing entry self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") # Ensure it got deleted res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXX,DC=SAMBA,DC=GOV") self.assertEqual(len(res), 0) # Ensure that non of the non truncated DN's got deleted res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") 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") # delete an existing entry self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") # Ensure it got deleted res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBAxxx") self.assertEqual(len(res), 0) self.checkGuids( "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", None) def test_search_truncated_dn_keys(self): # # For all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @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=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"}) self.checkGuids( "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", b"0123456789abcde5") res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") self.assertEqual(len(res), 1) res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") self.assertEqual(len(res), 1) res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") self.assertEqual(len(res), 1) res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") self.assertEqual(len(res), 0) res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV") self.assertEqual(len(res), 0) # Non existent, key one less than truncation limit res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA") self.assertEqual(len(res), 0) def test_search_dn_filter_truncated_dn_keys(self): # # For all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @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=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"}) self.checkGuids( "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", b"0123456789abcde5") res = self.l.search( expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") self.assertEqual(len(res), 1) res = self.l.search( expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") self.assertEqual(len(res), 1) res = self.l.search( expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") self.assertEqual(len(res), 1) res = self.l.search( expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") self.assertEqual(len(res), 0) res = self.l.search( expression="dn=OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV") self.assertEqual(len(res), 0) # Non existent, key one less than truncation limit res = self.l.search( expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA") self.assertEqual(len(res), 0) def test_search_one_level_truncated_dn_keys(self): # # Except for the base DN's # all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:@IDXDN:OU=??,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA # The base DN-s truncate to # @INDEX:@IDXDN:OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR # self.l.add({"dn": "OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", "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", "objectUUID": b"0123456789abcde7"}) self.checkGuids( "@INDEX:@IDXDN:OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", b"0123456789abcde7") res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", scope=ldb.SCOPE_ONELEVEL) self.assertEqual(len(res), 3) self.assertTrue( contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) self.assertTrue( contains(res, "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) self.assertTrue( contains(res, "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", scope=ldb.SCOPE_ONELEVEL) self.assertEqual(len(res), 3) self.assertTrue( contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) self.assertTrue( contains(res, "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) self.assertTrue( contains(res, "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", scope=ldb.SCOPE_ONELEVEL) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA")) def test_search_sub_tree_truncated_dn_keys(self): # # Except for the base DN's # all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:@IDXDN:OU=??,OU=A_LONG_DN_SUB_TREE,DC=SAMBA # The base DN-s truncate to # @INDEX:@IDXDN:OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR # self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", "objectUUID": b"0123456789abcdef"}) self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", "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) self.assertEqual(len(res), 4) self.assertTrue( contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) self.assertTrue( contains(res, "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) self.assertTrue( contains(res, "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) self.assertTrue( contains(res, "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", scope=ldb.SCOPE_SUBTREE) self.assertEqual(len(res), 4) self.assertTrue( contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) self.assertTrue( contains(res, "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) self.assertTrue( contains(res, "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) self.assertTrue( contains(res, "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3", scope=ldb.SCOPE_SUBTREE) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3")) res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4", scope=ldb.SCOPE_SUBTREE) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4")) def test_search_base_truncated_dn_keys(self): # # For all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @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=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"}) self.checkGuids( "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", b"0123456789abcde5") res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_BASE) self.assertEqual(len(res), 1) res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", scope=ldb.SCOPE_BASE) self.assertEqual(len(res), 1) res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", scope=ldb.SCOPE_BASE) self.assertEqual(len(res), 1) res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", scope=ldb.SCOPE_BASE) self.assertEqual(len(res), 0) res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV", scope=ldb.SCOPE_BASE) self.assertEqual(len(res), 0) # Non existent, key one less than truncation limit res = self.l.search( base="OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", scope=ldb.SCOPE_BASE) self.assertEqual(len(res), 0) # # Test non unique index searched with truncated keys # def test_index_truncated_keys(self): # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa eq_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" lt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # > than max length and differs in values that will be truncated gt_max_b = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" # Add two entries with the same value, key length = max so no # truncation. self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", "notUnique": eq_max, "objectUUID": b"0123456789abcde0"}) self.checkGuids( "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", b"0123456789abcde0") self.l.add({"dn": "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", "notUnique": eq_max, "objectUUID": b"0123456789abcde1"}) self.checkGuids( "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", b"0123456789abcde0" + b"0123456789abcde1") # # An entry outside the tree # self.l.add({"dn": "OU=10,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", "notUnique": eq_max, "objectUUID": b"0123456789abcd11"}) self.checkGuids( "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", b"0123456789abcd11" + b"0123456789abcde0" + b"0123456789abcde1") # Key longer than max so should get truncated to same key as # the previous two entries 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 # self.l.add({"dn": "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", "notUnique": lt_max, "objectUUID": b"0123456789abcde3"}) self.checkGuids( "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", b"0123456789abcde3") # # An entry outside the tree # self.l.add({"dn": "OU=12,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", "notUnique": lt_max, "objectUUID": b"0123456789abcd13"}) self.checkGuids( "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", b"0123456789abcd13" + b"0123456789abcde3") # # search for target is max value not truncated # should return ou's 01, 02 # expression = "(notUnique=" + eq_max.decode('ascii') + ")" res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 2) self.assertTrue( contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) self.assertTrue( contains(res, "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) # # search for target is max value not truncated # search one level up the tree, scope is ONE_LEVEL # So should get no matches # expression = "(notUnique=" + eq_max.decode('ascii') + ")" res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 0) # # search for target is max value not truncated # search one level up the tree, scope is SUBTREE # So should get 3 matches # res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression=expression) self.assertEqual(len(res), 3) self.assertTrue( contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) self.assertTrue( contains(res, "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) self.assertTrue( contains(res, "OU=10,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) # # search for target is max value + 1 so truncated # should return ou 23 as it's gt_max_b being searched for # expression = "(notUnique=" + gt_max_b.decode('ascii') + ")" res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=23,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) # # search for target is max value + 1 so truncated # should return ou 03 as it's gt_max being searched for # expression = "(notUnique=" + gt_max.decode('ascii') + ")" res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) # # scope one level and one level up one level up should get no matches # res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 0) # # scope sub tree and one level up one level up should get 2 matches # res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression=expression) self.assertEqual(len(res), 2) self.assertTrue( contains(res, "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) self.assertTrue( contains(res, "OU=11,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) # # search for target is max value - 1 so not truncated # should return ou 04 # expression = "(notUnique=" + lt_max.decode('ascii') + ")" res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) # # scope one level and one level up one level up should get no matches # res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 0) # # scope sub tree and one level up one level up should get 2 matches # res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression=expression) self.assertEqual(len(res), 2) self.assertTrue( contains(res, "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) self.assertTrue( 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 # def test_index_multi_valued_identical_keys(self): # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa as_eq_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" bs_eq_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" try: self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", "notUnique": [bs_eq_max, as_eq_max, as_eq_max], "objectUUID": b"0123456789abcde0"}) self.fail("Exception not thrown") except ldb.LdbError as e: code = e.args[0] self.assertEqual(ldb.ERR_ATTRIBUTE_OR_VALUE_EXISTS, code) # # Test non unique index with multivalued index attributes # searched with non truncated keys # def test_search_index_multi_valued_truncated_keys(self): # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" 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", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) expression = "(notUnique=" + ab_gt_max.decode('ascii') + ")" res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) expression = "(notUnique=" + bb_gt_max.decode('ascii') + ")" res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", scope=ldb.SCOPE_ONELEVEL, expression=expression) self.assertEqual(len(res), 1) self.assertTrue( contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) # # Test deletion of records with non unique index with multivalued index # attributes # replicate this to test modify with modify flags i.e. DELETE, REPLACE # def test_delete_index_multi_valued_truncated_keys(self): # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" cc_gt_max = b"cccccccccccccccccccccccccccccccccc" self.l.add({"dn": "OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG", "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], "objectUUID": b"0123456789abcde0"}) 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", expression="(notUnique=" + aa_gt_max.decode("ascii") + ")") self.assertEqual(2, len(res)) self.assertTrue( contains(res, "OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG")) self.assertTrue( 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 # attributes # def test_modify_index_multi_valued_truncated_keys(self): # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" cc_gt_max = b"cccccccccccccccccccccccccccccccccc" self.l.add({"dn": "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG", "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], "objectUUID": b"0123456789abcde0"}) 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.assertTrue( contains(res, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG")) self.assertTrue( contains(res, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG")) # # Modify that does not change the indexed attribute # msg = ldb.Message() msg.dn = ldb.Dn(self.l, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") msg["notUnique"] = ldb.MessageElement( [aa_gt_max, ab_gt_max, bb_gt_max], ldb.FLAG_MOD_REPLACE, "notUnique") self.l.modify(msg) # # 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 # msg = ldb.Message() msg.dn = ldb.Dn(self.l, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") msg["notUnique"] = ldb.MessageElement( [aa_gt_max, bb_gt_max], ldb.FLAG_MOD_REPLACE, "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 # msg = ldb.Message() msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") msg["notUnique"] = ldb.MessageElement( [ab_gt_max], ldb.FLAG_MOD_DELETE, "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 # msg = ldb.Message() msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") msg["notUnique"] = ldb.MessageElement( [], ldb.FLAG_MOD_DELETE, "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 # msg = ldb.Message() msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") msg["notUnique"] = ldb.MessageElement( [cc_gt_max], ldb.FLAG_MOD_ADD, "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 # msg = ldb.Message() msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") msg["notUnique"] = ldb.MessageElement( [aa_gt_max, ab_gt_max], ldb.FLAG_MOD_ADD, "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. # def test_check_base_on_search_truncated_dn_keys(self): # # Except for the base DN's # all entries the DN index key gets truncated to # 0 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890 # @INDEX:@IDXDN:OU=??,OU=CHECK_BASE_DN_XXXX,DC=SAMBA # The base DN-s truncate to # @INDEX:@IDXDN:OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR # checkbaseonsearch = {"dn": "@OPTIONS", "checkBaseOnSearch": b"TRUE"} self.l.add(checkbaseonsearch) self.l.add({"dn": "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", "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"}) self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", "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"}) self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", "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) self.assertEqual(len(res), 3) self.assertTrue( contains(res, "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) self.assertTrue( contains(res, "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) self.assertTrue( contains(res, "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", scope=ldb.SCOPE_SUBTREE) self.assertEqual(len(res), 3) self.assertTrue( contains(res, "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) self.assertTrue( contains(res, "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) self.assertTrue( contains(res, "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) try: res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3", scope=ldb.SCOPE_SUBTREE) self.fail("Expected exception no thrown") except ldb.LdbError as e: 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): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX super(MaxIndexKeyLengthTestsLmdb, self).setUp() def tearDown(self): super(MaxIndexKeyLengthTestsLmdb, self).tearDown() class OrderedIntegerRangeTests(LdbBaseTest): def tearDown(self): shutil.rmtree(self.testdir) super(OrderedIntegerRangeTests, self).tearDown() # Ensure the LDB is closed now, so we close the FD del(self.l) def setUp(self): super(OrderedIntegerRangeTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "ordered_integer_test.ldb") self.l = ldb.Ldb(self.url(), options=self.options()) self.l.add({"dn": "@ATTRIBUTES", "int64attr": "ORDERED_INTEGER"}) self.l.add({"dn": "@INDEXLIST", "@IDXATTR": [b"int64attr"], "@IDXONE": [b"1"], "@IDXGUID": [b"objectUUID"], "@IDX_DN_GUID": [b"GUID"]}) def options(self): if self.prefix == MDB_PREFIX: return ['modules:rdn_name', 'disable_full_db_scan_for_self_test:1'] else: return ['modules:rdn_name'] def test_comparison_expression(self): int64_max = 2**63-1 int64_min = -2**63 test_nums = list(range(-5, 5)) test_nums += list(range(int64_max-5, int64_max+1)) test_nums += list(range(int64_min, int64_min+5)) test_nums = sorted(test_nums) for (i, num) in enumerate(test_nums): ouuid = 0x0123456789abcdef + i ouuid_s = bytes(('0' + hex(ouuid)[2:]).encode()) self.l.add({"dn": "OU=COMPTESTOU{},DC=SAMBA,DC=ORG".format(i), "objectUUID": ouuid_s, "int64attr": str(num)}) def assert_int64_expr(expr, py_expr=None): res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(int64attr%s)" % (expr)) if not py_expr: py_expr = expr expect = [n for n in test_nums if eval(str(n) + py_expr)] vals = sorted([int(r.get("int64attr")[0]) for r in res]) self.assertEqual(len(res), len(expect)) self.assertEqual(set(vals), set(expect)) self.assertEqual(expect, vals) assert_int64_expr(">=-2") assert_int64_expr("<=2") assert_int64_expr(">=" + str(int64_min)) assert_int64_expr("<=" + str(int64_min)) assert_int64_expr("<=" + str(int64_min+1)) assert_int64_expr("<=" + str(int64_max)) assert_int64_expr(">=" + str(int64_max)) assert_int64_expr(">=" + str(int64_max-1)) assert_int64_expr("=10", "==10") def test_comparison_expression_duplicates(self): int64_max = 2**63-1 int64_min = -2**63 test_nums = list(range(-5, 5)) * 3 test_nums += list(range(-20, 20, 5)) * 2 test_nums += list(range(-50, 50, 15)) test_nums = sorted(test_nums) for (i, num) in enumerate(test_nums): ouuid = 0x0123456789abcdef + i ouuid_s = bytes(('0' + hex(ouuid)[2:]).encode()) self.l.add({"dn": "OU=COMPTESTOU{},DC=SAMBA,DC=ORG".format(i), "objectUUID": ouuid_s, "int64attr": str(num)}) def assert_int64_expr(expr, py_expr=None): res = self.l.search(base="DC=SAMBA,DC=ORG", scope=ldb.SCOPE_SUBTREE, expression="(int64attr%s)" % (expr)) if not py_expr: py_expr = expr expect = [n for n in test_nums if eval(str(n) + py_expr)] vals = sorted([int(r.get("int64attr")[0]) for r in res]) self.assertEqual(len(res), len(expect)) self.assertEqual(set(vals), set(expect)) self.assertEqual(expect, vals) assert_int64_expr(">=-2") assert_int64_expr("<=2") assert_int64_expr(">=" + str(int64_min)) assert_int64_expr("<=" + str(int64_min)) assert_int64_expr("<=" + str(int64_min+1)) assert_int64_expr("<=" + str(int64_max)) assert_int64_expr(">=" + str(int64_max)) assert_int64_expr(">=" + str(int64_max-1)) assert_int64_expr("=-5", "==-5") assert_int64_expr("=5", "==5") # Run the ordered integer range tests against an lmdb backend class OrderedIntegerRangeTestsLmdb(OrderedIntegerRangeTests): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") self.prefix = MDB_PREFIX super(OrderedIntegerRangeTestsLmdb, self).setUp() def tearDown(self): super(OrderedIntegerRangeTestsLmdb, self).tearDown() # Run the index truncation tests against an lmdb backend class RejectSubDBIndex(LdbBaseTest): def setUp(self): if os.environ.get('HAVE_LMDB', '1') == '0': self.skipTest("No lmdb backend") 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"], "@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() ldb-2.0.8/tests/python/repack.py0000660000000000000000000001644413573675413016547 0ustar rootroot00000000000000import os from unittest import TestCase import shutil from subprocess import check_output import ldb TDB_PREFIX = "tdb://" MDB_PREFIX = "mdb://" def tempdir(): import tempfile try: dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") except KeyError: dir_prefix = None return tempfile.mkdtemp(dir=dir_prefix) # Check enabling and disabling GUID indexing works and that the database is # repacked at version 2 if GUID indexing is enabled, or version 1 if disabled. class GUIDIndexAndPackFormatTests(TestCase): prefix = TDB_PREFIX def setup_newdb(self): self.testdir = tempdir() self.filename = os.path.join(self.testdir, "guidpackformattest.ldb") url = self.prefix + self.filename self.l = ldb.Ldb(url, options=["modules:"]) self.num_recs_added = 0 #guidindexpackv1.ldb is a pre-made database packed with version 1 format #but with GUID indexing enabled, which is not allowed, so Samba should #repack the database on the first transaction. def setup_premade_v1_db(self): db_name = "guidindexpackv1.ldb" this_file_dir = os.path.dirname(os.path.abspath(__file__)) db_path = os.path.join(this_file_dir, "../", db_name) self.testdir = tempdir() self.filename = os.path.join(self.testdir, db_name) shutil.copy(db_path, self.filename) url = self.prefix + self.filename self.l = ldb.Ldb(url, options=["modules:"]) self.num_recs_added = 10 def tearDown(self): if hasattr(self, 'testdir'): shutil.rmtree(self.testdir) def add_one_rec(self): ouuid = 0x0123456789abcdef + self.num_recs_added ouuid_s = '0' + hex(ouuid)[2:] dn = "OU=GUIDPFTEST{},DC=SAMBA,DC=ORG".format(self.num_recs_added) rec = {"dn": dn, "objectUUID": ouuid_s, "distinguishedName": dn} self.l.add(rec) self.num_recs_added += 1 # Turn GUID back into a str for easier comparisons return rec def set_guid_indexing(self, enable=True): modmsg = ldb.Message() modmsg.dn = ldb.Dn(self.l, '@INDEXLIST') attrs = {"@IDXGUID": [b"objectUUID"], "@IDX_DN_GUID": [b"GUID"]} for attr, val in attrs.items(): replace = ldb.FLAG_MOD_REPLACE el = val if enable else [] el = ldb.MessageElement(elements=el, flags=replace, name=attr) modmsg.add(el) self.l.modify(modmsg) # Parse out the comments above each record that ldbdump produces # containing pack format version and KV level key for each record. # Return all GUID index keys and the set of all unique pack formats. def ldbdump_guid_keys_pack_formats(self): dump = check_output(["bin/ldbdump", "-i", self.filename]) dump = dump.decode("utf-8") dump = dump.split("\n") comments = [s for s in dump if s.startswith("#")] guid_key_tag = "# key: GUID=" guid_keys = {c[len(guid_key_tag):] for c in comments if c.startswith(guid_key_tag)} pack_format_tag = "# pack format: " pack_formats = {c[len(pack_format_tag):] for c in comments if c.startswith(pack_format_tag)} pack_formats = [int(s, 16) for s in pack_formats] return guid_keys, pack_formats # Put the whole database in a dict so we can easily check the database # hasn't changed def get_database(self): recs = self.l.search(base="", scope=ldb.SCOPE_SUBTREE, expression="") db = dict() for r in recs: dn = str(r.dn) self.assertNotIn(dn, db) db[dn] = dict() for k in r.keys(): k = str(k) db[dn][k] = str(r.get(k)) return db # Toggle GUID indexing on and off a few times, and check that when GUID # indexing is enabled, the database is repacked to pack format V2, and # when GUID indexing is disabled again, the database is repacked with # pack format V1. def toggle_guidindex_check_pack(self): expect_db = self.get_database() for enable in [False, False, True, False, True, True, False]: pf = ldb.PACKING_FORMAT_V2 if enable else ldb.PACKING_FORMAT self.set_guid_indexing(enable=enable) guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() num_guid_keys = self.num_recs_added if enable else 0 self.assertEqual(len(guid_keys), num_guid_keys) self.assertEqual(pack_formats, [pf]) self.assertEqual(self.get_database(), expect_db) rec = self.add_one_rec() expect_db[rec['dn']] = rec guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() num_guid_keys = self.num_recs_added if enable else 0 self.assertEqual(len(guid_keys), num_guid_keys) self.assertEqual(pack_formats, [pf]) self.assertEqual(self.get_database(), expect_db) # Check a newly created database is initially packed at V1, then is # repacked at V2 when GUID indexing is enabled. def test_repack(self): self.setup_newdb() guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() self.assertEqual(len(guid_keys), 0) self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) self.assertEqual(self.get_database(), {}) self.l.add({"dn": "@ATTRIBUTES"}) guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() self.assertEqual(len(guid_keys), 0) self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) self.assertEqual(self.get_database(), {}) self.l.add({"dn": "@INDEXLIST", "@IDXONE": [b"1"], "@IDXGUID": [b"objectUUID"], "@IDX_DN_GUID": [b"GUID"]}) guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() self.assertEqual(len(guid_keys), 0) self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) self.assertEqual(self.get_database(), {}) rec = self.add_one_rec() expect_db = {rec["dn"]: rec} guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() self.assertEqual(len(guid_keys), 1) self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) self.assertEqual(self.get_database(), expect_db) self.toggle_guidindex_check_pack() # Check a database with V1 format with GUID indexing enabled is repacked # with version 2 format. def test_guid_indexed_v1_db(self): self.setup_premade_v1_db() expect_db = self.get_database() guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() self.assertEqual(len(guid_keys), self.num_recs_added) self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) self.assertEqual(self.get_database(), expect_db) rec = self.add_one_rec() expect_db[rec['dn']] = rec guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() self.assertEqual(len(guid_keys), self.num_recs_added) self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) self.assertEqual(self.get_database(), expect_db) self.toggle_guidindex_check_pack() if __name__ == '__main__': import unittest unittest.TestProgram() ldb-2.0.8/tests/samba4.png0000660000000000000000000001413712406075657015257 0ustar rootroot00000000000000‰PNG  IHDRØOHÍÔÖbKGDÿÿÿ ½§“ pHYs  šœtIMEÕ S·ìEtEXtCommentCreated with The GIMPïd%nÃIDATxÚíyx ×Ç¿» jm- ZÔ–VÔÞÆÞREÑZ[[[µªª‹¢”ú¡–Zbi,APŠ ±54$¶ÚŠ’¢ö]ìmp~Lbfî:÷Þ9çNnÞÏóÌ“¹3“;ï¼sÞùžsî™÷AAŽÄ#/A„Áø‘ ‚ ‚– ‚ H` ‚ ‚– ‚ X‚ ‚ %‚ X‚ ‚ H` ‚ ‚– ‚ H` ‚ð9$&jY5^¢4q>@êqeƌ˱åî—cJ•HYN`q@&‘Ï©Ìd~Ü+ÇÔ‚%ˆ,ÂùuʃrT/@’Œ_¦Rη/ùÜ'¤e—ös6‰OÙ1ÓÒã ÕŸô¤jB-X‚Èr-‘þÀ9<Œ™çµ~ÂÜeçF!%°d´ÒÙ8‰Ï9º·T}ø‡|îK4ï4SBŠò¹ó×@ܾy­ ªÙî§.b‚È([$¸|Óø3P÷pÖ*G€»@¡bÀõ[¾s…ì€bÆ”cjÁDƒ‡¸Y ÁÉ\Kæ ó¡K,fÜW‘À„spײ'­Ž´í|ÎñJòsVÙc˵[º{0þˆ çϼWV®„Ñí}ê"&GéÖ«Z8p‚Ã#÷€²vZ9D–([¶ø;1ظ¸xxøØÜWsj%P:ý•sÞDëîË%ϼCKYæ!(q’>úý•ʘY,Ù7¨ÞÅåØë]ć÷®b¸e|z«CK)ûˆ˜ ÊÜ˶H÷ËÉÆŸ2\àdÛå—Së¡T°G ðÃ>ŠãÌ@Z’ý¬,T"™jÝ»†y¹Ô<™Øå¢øSf,©7.0‘'<ë½k5r¹µvüæ×§^>L3]¹]ÿ#<(·Êê므Æ/ËF‰óÅŠ±`f((¾Ûî•13,{£Ü+Ç‹¾U¾cË cÊ÷.âĸÿ±°ðAnýïé_€ÉÀãÀÑSÀ© r›;¤4P£P«Ш&³žëß½yåçhÔú;C»².o”Xð«¾ZGÕv—$Æÿ…½&ß׳«€’­ÍemΠP~ tQ fE Õ+À«­”ÒùÇ„xhÄ5àj2°ã°ç(p(8w ¸š ܸ dª>4¨ôn <ÕØµ{`–îá1@Ù·ô{a 0k%°upô$+P± ðj(е¨7CÐY%ÄuEg¥ØÖË¥ +ÒÄ:nò½Üyàž%/–uŠ¿$S– ô‡Ÿ9¸ ì•x‰½æä @³þòàFÿø]³°è[ |;ã –šm³%V÷=þ! ˜¼$/¦Ì½mú°;vCrà+åÁRøëlæ|´¼ÙX¾Åõÿ[6 úÛx›ü xm½oÖ0?ôùHr%Äy ìý€AÉ+Fõ~XܼãÙwW)lœ 5µ½Ãd I_>B›ucÛµr•Aßvž âWÝ᳕ϻ絺‹ñ‡€G™A`×NX‹vvjµv_ ^~ر@y•­ "Ðâ¹î9ò¼Ä½/u~5аKæýùèØ (ꨰñp‹¦_{`Ò¾X ¼ùðç)ñ6u np¯b˜¶Sbþ/ËëŸuÆ.ÊÜ÷ç…2ÀÁd…øT–)¶s$Fb--W€À2îW¦ü\“S0ªY?h6PŒO>VUhY2 …šR`mHhQˆM4Q‡Sº3â¢#J •mïúâÝšX¶f—Oˆó®ï lÙ? xÌÌ‘³7¸pé†;‚¢Ü#ÿlæEB/åJÇÏpYŠm—Ÿï_t¾›ç¾-¥‚Ó—lïkXØ*hF&^£à Elíüڕ凯™ÄUƒ ¿±EO¨%j´ À@H CH ó™tJªr¯Û6ô½Ëûï!ð Í< ñ/ßói·Íýڵѵ¾"®pâ¬ü\Ù6ÃbGŠ{#Ž)¶³mVƨnu÷ˆœrÓqhn_\qâʃVëüå£åØyÈWŠ˜Ä:Ü­Ýt1=øÊøÞ[Ë&+¸¥SmŒ {JY]±„nÞ:¨AuîøøÓ”˜\2Â7}R¯70ÿkÕ†²ÛǶ ÿÔí¡Ýòý‡€àYÊÍí3¹kµÛzµñŽOZ†ñT»ˆÖŽdõZ|ùäóÀŽÀÄÅ|’3h]øæ} ¤=€ô2óh;,Þü~Ðþo®uX׊C}ûÕ¼¬Ü=lvô—]åæó|°‘™¹³ÈÓЕ˜¦Øvæ§Õ$ÖÊÆïŸ%‹g/»þyåô6J¶„ãË#Ó« 0s¥ ˜z ‡«eGÀª éªq@ëÁüDuoP±ƒ;´j¬IÔÿºïrå~JsäŽÙ@Ä'üpÆ( >°¿Ã$ ß7Ì+A˜%±Ðô,)“ú~!Äé@í^® ¬¯W‚²ûiô ,Ŷ3?YWQl»ÛÖâºd”,tžˆk@v€ýe-®“Ô⺑r_¦瓤¹ÊúÁ]1Æ÷®õE=¿YT˜Ô®·“CJÛoy™E\&¡Õ G]&λnD’;’Õk.¯ŸüE¬%Lêôr|\ž\âlZð ÐùkÇÇ-ÄÙß/"HÂt n/×þ§NecmxL±íÑjYòP¹¬çIT^,ì;®ÏU;)냧ˆ»þܪq^•k½ex»Ù°ìÀN"‹…;…1½eëàú“«Ä`‘àX¨MZíUîZoª×\ÌÞOŒ…óËVêèx€ß½Ïßžœr Ì™¸ÀÅk|m9ó‡“.ó÷ûÓŽ¸î=JÓö*¥ªZ‡9ó7Ŷk±m=‚:~²ÜjõT\‡FX‹kêG Q=cÁÄ4 ¡RG¾†ÞÿÍZdWOpChƒmÏÀϾ¡¬G„÷à[ë?ÖBgÍÖºRÁëá ‘DZ='´Œò殤:¨,Yøì¬A¹ÿ¯~{¶0þüÕŸSÖoÅ8,'[ðõÅQ*ÚñE5&eËfÑA¦z½kÈ4ãí5Æþ>ŠmÅ„<…m7R^zÞ˜ŠóÅX`Ô\í¶Ä¸ñxª¡m?Dyö‰-û£ÄÕ3楬Ç|or€iƒù9#w`—ÅM“‡‘KlþºWNh¿cÇ®™Ü®åØ^ÉÅܶ̚h‘άõÕcåž}Ù¿=77j?oúI{ïάQìÙ2• 3‡(ë•k:îÒÚ¼›Ÿ/ÂCªï*Ÿ¯mr\Žïß»¥ùÌ#ñ…ÝœÒÛN­Ö~Þ5Wnµ&ÿéÙ÷– –{wŠ4³®t……l×]†œz²þú§âü®z ©Ýg|î“Ç;[é5DŸï.Íù9$´;P·ªõöw¿”…vö—m9e•û»pϺ€×7+×eù†àìMë'j?ïMüÃ.IöJ¯'eôðNSíl7Ë¿÷ÑÞ»’-•õ7‡ð±£F7˜‚ ój츫_‹žý‹b[CP]e½a ù¹jys9j¡;Zþ¹ì­íÜ6¯ì{#,†z¯æ}ÅÏ Ûȵ­®-lÙ";jùŒf.9æÂ™CÂKR¹ë˜¾ÿ)ØHÕÓŽ©ÛH1³B`ö¦ÐJ@“þÊç-?Õú8|Xñ̘ݘ¿Nµá$ÐÖI×+‰Ž+žYq¾í Zi¼ÊO£êÛzbûÞeŸ‘éïx8âÈÁñòH„lö‚©µÚ?]¸xïto Ì^mÇÒ¬rb;÷wâ\L´½?ZbU;ò¯›){“u‘´aOªÄ2DÿÝfÀ‚õüìÙø#и¯c{/–ØóoËë3>zÿ`¼Ö/êÛ)/êô¨1Ï Ë“ÏöË8‰µÉèúÛH¡|ìºð+P´•¥o(¶-í:{j+ñŒ\)œ¿ Âîódz®cƒµ6äÂ5yŽ?žÌY#?L>lk½/[6æíW[Ô*èzÕ]D:cßŇúó=×.:[Gª5OqÍ ׫—Rl—!®ð1§ìVñëŒ |wð¶ö³3q€6ªßÕ*¾Å϶¢­(¶õPâ™jOîYÛ$¨–•X#ñ3ö똴¡vËðÙ»ÇHô´²ÐŽè¥¯uí Sºö€<'Æî!(¦lžn½¿Ú;Êú°é|m­ê^5Þû÷,yŽösá"e¼÷šAaû»öª^ÔŸñ?LPMŸçú R'Êð%2klèI¢Ê³kø„ëŽDmt`ètþNò°{P­«v»ý.ãt[!õ½Ô¶yÖpÍÒ=ãôÖ½1Á„wíqdKÔ˜gYÆ»„û£€»š¥v¯øeß| zoÜ+ŠmÛ±M-XKÎý Kÿ?.¦?ÂÛMôN 6vQO†óÉ%o™®£„0é¶E&¦4A“±ÿ}xþYsÝHGxc“—¶ÄU ÏìMzÅuót1‰7}Yßq{£žØ“¶-Î&1ñ¢þG.Nš5,›¦à†½Ïï^  Øö4¶ E\"®n lóN³€bJ¡ ûh’Ø#_}&-Qÿ¾VhP]Œãþ<,WûôÛöz™Wopꉪ’Xf®ò*{\yx7RMòàéü”ŽX§êº‹ž`haõ0¥¹X“SˆUªÊÇ\'9y½¨?9ƵÖk‘JY2 xÀiàWÎmZ¾ä-¶»Ï)¶ GÈËç{Ýì"¶-PI?/uu|i;$æ_;ãiH¥Å8Ðñ€3 „°ðé $Œ÷½C›Tïš¶©¬Làcƒº&Ƈ£´j"º¶òçRïêïvkl8H•øˆ˜6³þܺ<ý,@-8+Šm­M—$†"üïOfañ·@‡ô¬„qS€ð˜wZ° G© Ëí¾—º¦¦#ö[´þµU† œ'QW¬Š8{έ—ØÎ-“m§ä:,(ã•[qÿ^ªuR½kÊK\_,§ýìH\£'Õzâ”c‹ùùe:I„ÎŒ<¸ÍOìõŠYíö|lx_=aûýöò´g¼û‘3q¥Ø¶Ûó"ƒ58¯,‚³Ziß–ª”¿F‰«[«1Y¼:PÛÖ¼Ž3M^ÎÇ*…ìâ3Êc„˜ËTù®)ðrCë©+VB^ä"UÏg®Üù½â’}‰Êú&ǃcѱ¿’½¾é@~6Õí£ú¢¯õÚ,œ-ê‘Ì;ç9>v'§q !¥´Bu5ÞF ß²“n-<ŸöÌÂO'k[…Ûúc;â‹KÞo·æ{ºÒoˆ¿D7ºˆmw‰…‡Z'wÊ@ s¡ì6€ô~öå3š¢m¯u6GÔÕ(ywî¼À¯fy]lí@ˆÒ@Ótïx#=â¾ËH01¡?ŸìDÙÓt¶@”=#i¬þ]¯M&êæhÃû¯³V¹ö?íË6‹´ÇùDæÛfAüæ ¥€#§!Ü'.µ`c£{*3?Äk÷Å%ËÎÊá|ÿ¡¾ï{º¥çŽýHWâªuöž3•¹ÚR!$ÐÆb'y1~¨rŽèÑÖûEdoRO½æ¬ÿÖÍ‹LDkE-®îd*2§ï‹ßPT›ð³#òWàº:>=ÅO\è犸RlÛŠmo’©”ÙèâλMõ ‹‹é/ì¼.¶`çT,9ÒžM,O£—ÁíßäÍŽ®mùh`èXïdW´€üb)ONù¯7x¦(Àî[‹ë£$×’Ûæ`éTå=©¯%ÏW¥Ñ\5AtuÂÍ,Ô­*O€n^©lÛ Ðzß•x è5½©½ÆµãGŠzÎ,5\óv·mÈgÂîÐJ@Òa}6Y'±’Íäõq}ÁSŒ·'¢90wmú‡ë ÚïÎáü÷Ã=z ‡¼~8x¡“˜X.S HI`cäÿ?)I(U6ÔÍRI±m–ÖkÙâr–=x«{Øu½"1ÙØž4~Ø¼Û ¢  ¸C÷Jž"T(˜Ʋs> -Í$û²߬Gz¿{˜]PP^Ÿ72Ã.éêΕƒO–"ow+ œ»b½½s`QŸ{ðñÛÀøhÛû®m 56âá˜ÕcÛ+ª{Øõ$)ÆâZ© bÒ¾…«ÖÙb{Y`Ó.í¦ ^cŒŒR0?п=ðÕ,Ý(É$Ë@°åÁú´Û>Œý§ÿœ‡–‚ñ¼¨¬ÛÞ^¼m‚ø“öE×â½à°]bœùU^ÿvÁH3œ·ÄÿN‚ÖüöœŽõ΃iþØJ|Ïóø‡`–ŠmØÌ+°ö–{Û øš`‘_š£ÐÈÁãÞòÛÚN¯áâz1—rv}&D‚± `ì1§e?ØšùºïçÂñU;ÌÑžû`—ãõ—¯u‹?`ìŽö<»ŸvåbŠ]›äßeó4û>9ñçÏÏqìáÃ4Ó@VˆmZÄ.‚&\'‚ ˆ¬…¹€ ‚ H` ‚ ‚– ‚ H` ‚ ‚ %‚ X‚ ‚ %‚ ‚– ‚ H` ‚ ‚– ‚ X‚ ‚ %‚ X‚ ‚ H` ‚ ‚ ‚ ‚ ‚ ]üJ~¦˜c£GIEND®B`‚ldb-2.0.8/tests/sample_module.c0000660000000000000000000000627412520121120016345 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij 2007 ** 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 . */ #include "replace.h" #include "ldb_module.h" static int sample_add_callback(struct ldb_request *down_req, struct ldb_reply *ares) { struct ldb_request *req = talloc_get_type_abort(down_req->context, struct ldb_request); if (ares == NULL) { return ldb_module_done(req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->type == LDB_REPLY_REFERRAL) { return ldb_module_send_referral(req, ares->referral); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { return ldb_module_done(req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } return ldb_module_done(req, ares->controls, ares->response, LDB_SUCCESS); } static int sample_add(struct ldb_module *mod, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(mod); struct ldb_control *control = NULL; struct ldb_message *msg = NULL; struct ldb_request *down_req = NULL; int ret; /* check if there's a relax control */ control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); if (control != NULL) { return LDB_ERR_UNWILLING_TO_PERFORM; } msg = ldb_msg_copy_shallow(req, req->op.add.message); if (msg == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_msg_add_fmt(msg, "touchedBy", "sample"); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_build_add_req(&down_req, ldb, req, msg, req->controls, req, sample_add_callback, req); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(down_req, msg); /* go on with the call chain */ return ldb_next_request(mod, down_req); } static int sample_modify(struct ldb_module *mod, struct ldb_request *req) { struct ldb_control *control; /* check if there's a relax control */ control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); if (control != NULL) { return LDB_ERR_UNWILLING_TO_PERFORM; } /* not found go on */ return ldb_next_request(mod, req); } static struct ldb_module_ops ldb_sample_module_ops = { .name = "sample", .add = sample_add, .del = sample_modify, .modify = sample_modify, }; int ldb_sample_init(const char *version) { LDB_MODULE_CHECK_VERSION(version); return ldb_register_module(&ldb_sample_module_ops); } ldb-2.0.8/tests/schema-tests/schema-add-test.ldif0000660000000000000000000000351512406075657021603 0ustar rootroot00000000000000dn: CN=Users,DC=schema,DC=test objectClass: top objectClass: container cn: Users description: Default container for upgraded user accounts instanceType: 4 whenCreated: 20050116175504.0Z whenChanged: 20050116175504.0Z uSNCreated: 1 uSNChanged: 1 showInAdvancedViewOnly: FALSE name: Users objectGUID: b847056a-9934-d87b-8a1a-99fabe0863c8 systemFlags: 0x8c000000 objectCategory: CN=Container,CN=Schema,CN=Configuration,DC=schema,DC=test isCriticalSystemObject: TRUE nTSecurityDescriptor: foo dn: CN=Administrator,CN=Users,DC=schema,DC=test objectClass: top objectClass: person objectClass: organizationalPerson objectClass: user cn: Administrator description: Built-in account for administering the computer/domain instanceType: 4 whenCreated: 20050116175504.0Z whenChanged: 20050116175504.0Z uSNCreated: 1 memberOf: CN=Group Policy Creator Owners,CN=Users,DC=schema,DC=test memberOf: CN=Domain Admins,CN=Users,DC=schema,DC=test memberOf: CN=Enterprise Admins,CN=Users,DC=schema,DC=test memberOf: CN=Schema Admins,CN=Users,DC=schema,DC=test memberOf: CN=Administrators,CN=Builtin,DC=schema,DC=test uSNChanged: 1 name: Administrator objectGUID: 6c02f98c-46c6-aa38-5f13-a510cac04e6c userAccountControl: 0x10200 badPwdCount: 0 codePage: 0 countryCode: 0 badPasswordTime: 0 lastLogoff: 0 lastLogon: 0 pwdLastSet: 0 primaryGroupID: 513 objectSid: S-1-5-21-43662522-77495566-38969261-500 adminCount: 1 accountExpires: 9223372036854775807 logonCount: 0 sAMAccountName: Administrator sAMAccountType: 0x30000000 objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=schema,DC=test isCriticalSystemObject: TRUE unicodePwd: samba nTSecurityDescriptor: foo dn: CN=Test,CN=Users,DC=schema,DC=test objectClass: top objectClass: test cn: Test description: This is a test objectCategory: CN=Test,CN=Schema,CN=Configuration,DC=schema,DC=test nTSecurityDescriptor: foo instanceType: 4 ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif0000660000000000000000000000016512406075657021766 0ustar rootroot00000000000000dn: CN=Test,CN=Users,DC=schema,DC=test changetype: modify replace: description description: this test must not fail ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif0000660000000000000000000000015112406075657021762 0ustar rootroot00000000000000dn: CN=Test,CN=Users,DC=schema,DC=test changetype: modify delete: description # this test must not fail ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif0000660000000000000000000000016112406075657021764 0ustar rootroot00000000000000dn: CN=Test,CN=Users,DC=schema,DC=test changetype: modify add: description description: this test must not fail ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif0000660000000000000000000000013512406075657021766 0ustar rootroot00000000000000dn: CN=Test,CN=Users,DC=schema,DC=test changetype: modify add: foo foo: this test must fail ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif0000660000000000000000000000015612406075657021772 0ustar rootroot00000000000000dn: CN=Test,CN=Users,DC=schema,DC=test changetype: modify delete: nTSecurityDescriptor # this test must fail ldb-2.0.8/tests/schema-tests/schema.ldif0000660000000000000000000000472612406075657020105 0ustar rootroot00000000000000dn: @INDEXLIST @IDXATTR: name @IDXATTR: sAMAccountName @IDXATTR: objectSid @IDXATTR: objectClass @IDXATTR: member @IDXATTR: uidNumber @IDXATTR: gidNumber @IDXATTR: unixName @IDXATTR: privilege @IDXATTR: lDAPDisplayName dn: @ATTRIBUTES realm: CASE_INSENSITIVE userPrincipalName: CASE_INSENSITIVE servicePrincipalName: CASE_INSENSITIVE name: CASE_INSENSITIVE dn: CASE_INSENSITIVE sAMAccountName: CASE_INSENSITIVE objectClass: CASE_INSENSITIVE unicodePwd: HIDDEN ntPwdHash: HIDDEN ntPwdHistory: HIDDEN lmPwdHash: HIDDEN lmPwdHistory: HIDDEN createTimestamp: HIDDEN modifyTimestamp: HIDDEN dn: @MODULES @LIST: timestamps,schema dn: CN=Top,CN=Schema,CN=Configuration,DC=schema,DC=test objectClass: top objectClass: classSchema lDAPDisplayName: top cn: Top uSNCreated: 1 uSNChanged: 1 subClassOf: top systemMustContain: objectClass systemMayContain: structuralObjectClass systemMayContain: createTimeStamp systemMayContain: modifyTimeStamp systemMayContain: creatorsName systemMayContain: modifiersName systemMayContain: hasSubordinates systemMayContain: subschemaSubentry systemMayContain: collectiveSubentry systemMayContain: entryUUID systemMayContain: entryCSN systemMayContain: namingCSN systemMayContain: superiorUUID systemMayContain: contextCSN systemMayContain: whenCreated systemMayContain: whenChanged systemMayContain: uSNCreated systemMayContain: uSNChanged systemMayContain: distinguishedName systemMayContain: name systemMayContain: cn systemMayContain: userPassword systemMayContain: labeledURI dn: CN=Class-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test objectClass: top objectClass: classSchema lDAPDisplayName: classSchema cn: Class-Schema uSNCreated: 2 uSNChanged: 2 lDAPDisplayName: classSchema subClassOf: top systemMustContain: cn systemMustContain: subClassOf systemMayContain: systemPossSuperiors systemMayContain: systemOnly systemMayContain: systemMustContain systemMayContain: systemMayContain systemMayContain: systemAuxiliaryClass systemMayContain: possSuperiors systemMayContain: mustContain systemMayContain: mayContain systemMayContain: lDAPDisplayName systemMayContain: auxiliaryClass dn: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test objectClass: top objectClass: classSchema cn: Attribute-Schema uSNCreated: 3 uSNChanged: 3 lDAPDisplayName: attributeSchema subClassOf: top systemMustContain: oMSyntax systemMustContain: lDAPDisplayName systemMustContain: isSingleValued systemMustContain: cn systemMustContain: attributeSyntax systemMustContain: attributeID ldb-2.0.8/tests/slapd.conf0000660000000000000000000000104212406075657015343 0ustar rootroot00000000000000loglevel 0 include tests/schema/core.schema include tests/schema/cosine.schema include tests/schema/inetorgperson.schema include tests/schema/openldap.schema include tests/schema/nis.schema pidfile tests/tmp/slapd.pid argsfile tests/tmp/slapd.args access to * by * write allow update_anon bind_anon_dn include tests/tmp/modules.conf defaultsearchbase "o=University of Michigan,c=TEST" backend bdb database bdb suffix "o=University of Michigan,c=TEST" directory tests/tmp/db index objectClass eq index uid eq ldb-2.0.8/tests/start_slapd.sh0000770000000000000000000000050312406075657016250 0ustar rootroot00000000000000#!/bin/sh if [ -z "$LDBDIR" ]; then LDBDIR=`dirname $0`/.. export LDBDIR fi mkdir -p $LDBDIR/tests/tmp/db # running slapd in the background (with &) means it stays in the same process group, so it can be # killed by timelimit slapd -d0 -f $LDBDIR/tests/slapd.conf -h "`$LDBDIR/tests/ldapi_url.sh`" $* & sleep 2 ldb-2.0.8/tests/test-attribs.ldif0000660000000000000000000000014612406075657016662 0ustar rootroot00000000000000dn: @ATTRIBUTES uid: CASE_INSENSITIVE cn: CASE_INSENSITIVE ou: CASE_INSENSITIVE dn: CASE_INSENSITIVE ldb-2.0.8/tests/test-config.ldif0000660000000000000000000000276312406075657016466 0ustar rootroot00000000000000############################## # global configuration options dn: cn=Global,cn=Config,cn=Samba objectclass: globalconfig LocalConfigCn: cn=%U,cn=Config,cn=Samba LocalConfigCn;1: cn=%U,cn=Config,cn=Samba LocalConfigCn;2: cn=%I,cn=Config,cn=Samba LocalConfigCn;3: cn=%M,cn=Config,cn=Samba ############# dn: cn=Protocol,cn=Global,cn=Config,cn=Samba maxXmit: 7000 ################################ dn: cn=Volker,cn=Config,cn=Samba Workgroup: VNET3 UnixCharset: UTF8 Security: user Interfaces: vmnet* eth* NetbiosName: blu GuestAccount: tridge ################################# dn: cn=Volker,cn=Config,cn=Samba Workgroup: VNET3 UnixCharset: UTF8 Security: user Interfaces: vmnet* eth* NetbiosName: blu GuestAccount: tridge Include: cn=%U,cn=MyConfig,cn=Config,cn=Samba #### ((objectClass=fileshare)(cn=test)) ############################## # [test] share dn: cn=test,cn=Shares,cn=Config,cn=Samba objectclass: fileshare cn: test Comment: a test share Path: /home/tridge/samba4/prefix/test ReadOnly: no ##################################### # [msdn] a remote proxy share, stored # on \\msdn\test dn: cn=msdn,cn=Shares,cn=Config,cn=Samba objectclass: fileshare cn: msdn NtvfsHandler: cifs ReadOnly: no _CifsServer: msdn _CifsUser: administrator _CifsPassword: penguin _CifsDomain: winxp _CifsShare: test ############################## # [VisualC] share dn: cn=visualc,cn=Shares,cn=Config,cn=Samba objectclass: fileshare cn: VisualC Comment: VisualC development Path: /home/tridge/VisualC ReadOnly: no NtvfsHandler: simple ldb-2.0.8/tests/test-controls.sh0000770000000000000000000000163712406075657016561 0ustar rootroot00000000000000#!/bin/sh if [ -n "$TEST_DATA_PREFIX" ]; then LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" else LDB_URL="tdbtest.ldb" fi export LDB_URL PATH=bin:$PATH export PATH rm -f $LDB_URL* echo "LDB_URL: $LDB_URL" cat </dev/null 2>&1 && exit 1 dn: dc=foobar dc: foobar someThing: someThingElse EOF cat </dev/null 2>&1 && exit 1 dn: dc=bar changetype: modify replace someThing someThing: someThingElseBetter EOF $VALGRIND ldbsearch --controls "bypassoperational:0" >/dev/null 2>&1 || exit 1 ldb-2.0.8/tests/test-default-config.ldif0000660000000000000000000000060312406075657020077 0ustar rootroot00000000000000############################## # global configuration options dn: cn=Global,cn=DefaultConfig,cn=Samba objectclass: globalconfig Workgroup: WORKGROUP UnixCharset: UTF8 Security: user NetbiosName: blu GuestAccount: nobody ############################## # [_default_] share dn: cn=_default_,cn=Shares,cn=DefaultConfig,cn=Samba objectclass: fileshare cn: _default_ Path: /tmp ReadOnly: yes ldb-2.0.8/tests/test-dup-2.ldif0000660000000000000000000000022712406075657016141 0ustar rootroot00000000000000dn: cn=Sentinel,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST objectclass: OpenLDAPperson cn: Sentinel sn: USER uid: USER, Sentinel ldb-2.0.8/tests/test-dup.ldif0000660000000000000000000000047112406075657016003 0ustar rootroot00000000000000dn: cn=Fred Bassett,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST objectclass: OpenLDAPperson cn: Fred Bassett sn: Bassett uid: Bassett, Fred dn: cn=Sentinel,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST objectclass: OpenLDAPperson cn: Sentinel sn: USER uid: USER, Sentinel ldb-2.0.8/tests/test-extended.sh0000770000000000000000000000323112406075657016506 0ustar rootroot00000000000000#!/bin/sh echo "Running extended search tests" mv $LDB_URL $LDB_URL.1 cat < /dev/null && { echo "Should have failed to add again - gave $?" exit 1 } echo "Adding LDIF with one already-existing user again - should fail" $VALGRIND ldbadd $LDBDIR/tests/test-dup.ldif 2> /dev/null && { echo "Should have failed to add again - gave $?" exit 1 } echo "Adding again - should succeed (as previous failed)" $VALGRIND ldbadd $LDBDIR/tests/test-dup-2.ldif || exit 1 echo "Modifying elements" $VALGRIND ldbmodify $LDBDIR/tests/test-modify.ldif || exit 1 echo "Modify LDIF with one un-met constraint - should fail" $VALGRIND ldbadd $LDBDIR/tests/test-modify-unmet.ldif 2> /dev/null && { echo "Should have failed to modify - gave $?" exit 1 } echo "Modify LDIF with after failure of un-met constraint - should also fail" $VALGRIND ldbadd $LDBDIR/tests/test-modify-unmet-2.ldif 2> /dev/null && { echo "Should have failed to modify - gave $?" exit 1 } echo "Showing modified record" $VALGRIND ldbsearch '(uid=uham)' || exit 1 echo "Rename entry with ldbmodify - modrdn" $VALGRIND ldbmodify $LDBDIR/tests/test-modify-modrdn.ldif || exit 1 echo "Rename entry with ldbrename" OLDDN="cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" NEWDN="cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" $VALGRIND ldbrename "$OLDDN" "$NEWDN" || exit 1 echo "Showing renamed record" $VALGRIND ldbsearch '(uid=uham)' || exit 1 echo "Starting ldbtest" $VALGRIND ldbtest --num-records 100 --num-searches 10 || exit 1 if [ $LDB_SPECIALS = 1 ]; then echo "Adding index" $VALGRIND ldbadd $LDBDIR/tests/test-index.ldif || exit 1 fi echo "Adding bad attributes - should fail" $VALGRIND ldbadd $LDBDIR/tests/test-wrong_attributes.ldif && { echo "Should fhave failed - gave $?" exit 1 } echo "Testing indexed search" $VALGRIND ldbsearch '(uid=uham)' || exit 1 $VALGRIND ldbsearch '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1 $VALGRIND ldbsearch '(&(uid=uham)(uid=uham))' || exit 1 $VALGRIND ldbsearch '(|(uid=uham)(uid=uham))' || exit 1 $VALGRIND ldbsearch '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1 $VALGRIND ldbsearch '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1 $VALGRIND ldbsearch '(&(objectclass=person)(uid=uham)(!(uid=uhamxx)))' uid \* \+ dn || exit 1 $VALGRIND ldbsearch '(&(uid=uham)(uid=uha*)(title=*))' uid || exit 1 echo "Testing invalid search expression" $VALGRIND ldbsearch '(&(uid=uham)(title=foo\blah))' uid && exit 1 # note that the "((" is treated as an attribute not an expression # this matches the openldap ldapsearch behaviour of looking for a '=' # to see if the first argument is an expression or not $VALGRIND ldbsearch '((' uid || exit 1 $VALGRIND ldbsearch '(objectclass=)' uid || exit 1 $VALGRIND ldbsearch -b 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' -s base "" sn || exit 1 echo "Test wildcard match" $VALGRIND ldbadd $LDBDIR/tests/test-wildcard.ldif || exit 1 $VALGRIND ldbsearch '(cn=test*multi)' || exit 1 $VALGRIND ldbsearch '(cn=*test*multi*)' || exit 1 $VALGRIND ldbsearch '(cn=*test_multi)' || exit 1 $VALGRIND ldbsearch '(cn=test_multi*)' || exit 1 $VALGRIND ldbsearch '(cn=test*multi*test*multi)' || exit 1 $VALGRIND ldbsearch '(cn=test*multi*test*multi*multi_*)' || exit 1 echo "Starting ldbtest indexed" $VALGRIND ldbtest --num-records 100 --num-searches 500 || exit 1 echo "Testing one level search" count=`$VALGRIND ldbsearch -b 'ou=Groups,o=University of Michigan,c=TEST' -s one 'objectclass=*' none |grep '^dn' | wc -l` if [ $count != 3 ]; then echo returned $count records - expected 3 exit 1 fi echo "Testing binary file attribute value" $VALGRIND ldbmodify $LDBDIR/tests/photo.ldif || exit 1 count=`$VALGRIND ldbsearch '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l` if [ $count != 1 ]; then echo returned $count records - expected 1 exit 1 fi echo "*TODO* Testing UTF8 upper lower case searches !!" echo "Testing compare" count=`$VALGRIND ldbsearch '(cn>=t)' cn | grep '^dn' | wc -l` if [ $count != 1 ]; then # only "cn: test_multi_test_multi_test_multi" (comes after "t") # upper-cased words come before "t" - hence excluded echo returned $count records - expected 1 exit 1 fi $VALGRIND ldbsearch '(cn>t)' cn && exit 1 # strictly greater should not work count=`$VALGRIND ldbsearch '(cn<=t)' cn | grep '^dn' | wc -l` if [ $count != 18 ]; then # everything except "cn: test_multi_test_multi_test_multi" (comes after "t") # upper-cased letters come before "t" - hence included echo returned $count records - expected 18 exit 1 fi $VALGRIND ldbsearch '(cn * * 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 . */ #include #include #include #include #include #include "ldb_private.h" static void test_ldb_dn_add_child_fmt(void **state) { struct ldb_context *ldb = ldb_init(NULL, NULL); struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); assert_true(ldb_dn_add_child_fmt(dn, "DC=X")); assert_string_equal("DC=X,dc=samba,dc=org", ldb_dn_get_linearized(dn)); assert_string_equal("DC=X,DC=SAMBA,DC=ORG", ldb_dn_get_casefold(dn)); } static void test_ldb_dn_add_child_fmt2(void **state) { struct ldb_context *ldb = ldb_init(NULL, NULL); struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); assert_true(ldb_dn_add_child_fmt(dn, "DC=X,DC=Y")); assert_string_equal("DC=X,DC=Y,dc=samba,dc=org", ldb_dn_get_linearized(dn)); assert_string_equal("DC=X,DC=Y,DC=SAMBA,DC=ORG", ldb_dn_get_casefold(dn)); assert_int_equal(4, ldb_dn_get_comp_num(dn)); } static void test_ldb_dn_add_child_val(void **state) { struct ldb_context *ldb = ldb_init(NULL, NULL); struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); struct ldb_val name = {.data = discard_const("X"), .length = 1 }; assert_true(ldb_dn_add_child_val(dn, "DC", name)); assert_string_equal("DC=X,dc=samba,dc=org", ldb_dn_get_linearized(dn)); assert_string_equal("DC=X,DC=SAMBA,DC=ORG", ldb_dn_get_casefold(dn)); } static void test_ldb_dn_add_child_val2(void **state) { struct ldb_context *ldb = ldb_init(NULL, NULL); struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); struct ldb_val name = {.data = discard_const("X,DC=Y"), .length = 6 }; assert_true(ldb_dn_add_child_val(dn, "DC", name)); assert_string_equal("DC=X\\,DC\\3DY,dc=samba,dc=org", ldb_dn_get_linearized(dn)); assert_string_equal("DC=X\\,DC\\3DY,DC=SAMBA,DC=ORG", ldb_dn_get_casefold(dn)); assert_int_equal(3, ldb_dn_get_comp_num(dn)); } struct explode_test { const char *strdn; int comp_num; int ext_comp_num; bool special; bool invalid; const char *linearized; const char *ext_linearized_1; bool explode_result; }; static int extended_dn_read_ID(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { /* Allow to check we can cope with validity checks */ if (in->length != 4) { return -1; } *out = *in; out->data = talloc_memdup(mem_ctx, in->data, in->length); if (out->data == NULL) { return -1; } return 0; } /* write out (resued for both HEX and clear for now) */ static int extended_dn_write_ID(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { *out = *in; out->data = talloc_memdup(mem_ctx, in->data, in->length); if (out->data == NULL) { return -1; } return 0; } static void test_ldb_dn_explode(void **state) { size_t i; struct ldb_context *ldb = ldb_init(NULL, NULL); struct explode_test tests[] = { {"A=B", 1, 0, false, false, "A=B", "A=B", true}, {"", 0, 0, false, false, "", "", true}, {" ", -1, -1, false, false, " ", " ", false}, {"<>", 0, 0, false, false, "", NULL, true}, {"<", 0, 0, false, false, "", NULL, true}, {"<><", 0, 0, false, false, "", NULL, true}, {"<><>", 0, 0, false, false, "", NULL, true}, {"A=B,C=D", 2, 0, false, false, "A=B,C=D", "A=B,C=D", true}, {"A=B,C=D", -1, -1, false, false, "", NULL, false}, {";A=B,C=D", -1, -1, false, false, "A=B,C=D", NULL, false}, {";A=B,C=D", -1, -1, false, true, "A=B,C=D", NULL, false}, {";A=B,C=D", 2, 1, false, false, "A=B,C=D", ";A=B,C=D", true}, {"x=🔥", 1, 0, false, false, "x=🔥", "x=🔥", true}, {"@FOO", 0, 0, true, false, "@FOO", "@FOO", true}, }; struct ldb_dn_extended_syntax syntax = { .name = "ID", .read_fn = extended_dn_read_ID, .write_clear_fn = extended_dn_write_ID, .write_hex_fn = extended_dn_write_ID }; ldb_dn_extended_add_syntax(ldb, 0, &syntax); for (i = 0; i < ARRAY_SIZE(tests); i++) { bool result; const char *linear; const char *ext_linear; struct ldb_dn *dn = ldb_dn_new(ldb, ldb, tests[i].strdn); /* * special, invalid, linear, and ext_linear are set before * explode */ fprintf(stderr, "%zu «%s»: ", i, tests[i].strdn); linear = ldb_dn_get_linearized(dn); assert_true((linear == NULL) == (tests[i].linearized == NULL)); assert_string_equal(linear, tests[i].linearized); ext_linear = ldb_dn_get_extended_linearized(ldb, dn, 1); assert_true((ext_linear == NULL) == (tests[i].ext_linearized_1 == NULL)); if (tests[i].ext_linearized_1 != NULL) { assert_string_equal(ext_linear, tests[i].ext_linearized_1); } assert_true(ldb_dn_is_special(dn) == tests[i].special); assert_true(ldb_dn_is_valid(dn) != tests[i].invalid); /* comp nums are set by explode */ result = ldb_dn_validate(dn); fprintf(stderr, "res %i lin «%s» ext «%s»\n", result, linear, ext_linear); assert_true(result == tests[i].explode_result); assert_int_equal(ldb_dn_get_comp_num(dn), tests[i].comp_num); assert_int_equal(ldb_dn_get_extended_comp_num(dn), tests[i].ext_comp_num); } } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_ldb_dn_add_child_fmt), cmocka_unit_test(test_ldb_dn_add_child_fmt2), cmocka_unit_test(test_ldb_dn_add_child_val), cmocka_unit_test(test_ldb_dn_add_child_val2), cmocka_unit_test(test_ldb_dn_explode), }; return cmocka_run_group_tests(tests, NULL, NULL); } ldb-2.0.8/tests/test_ldb_qsort.c0000660000000000000000000000276213573675413016601 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * * Copyright (C) 2018 Andreas Schneider * * 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 . */ #include #include #include #include #include #include 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); } ldb-2.0.8/tests/testdata.txt0000660000000000000000000000031612406075657015746 0ustar rootroot00000000000000foo=bar5 (&(|(a=b)(c=d))(e=f)) (&(|(a=b)(c=d)(g=h))(e=f)) name=firstname lastname (&(sid=S-1-2-3)(name = fred bloggs)) (&(|(a=b)(c=d))(g=f)) (&(sid=S-1-2-3)(!(name = fred bloggs))) (&(!(|(a=b)(c=d))(g=f))) ldb-2.0.8/tests/testsearch.txt0000660000000000000000000000020012406075657016272 0ustar rootroot00000000000000(blah=foo) (objectclass=person) (dn=*) (&(objectclass=person)(objectclass=person)) (&(objectclass=person)(objectclass=personx)) ldb-2.0.8/tools/cmdline.c0000660000000000000000000003607113100601766015144 0ustar rootroot00000000000000/* ldb database library - command line handling for ldb tools Copyright (C) Andrew Tridgell 2005 ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb.h" #include "ldb_module.h" #include "tools/cmdline.h" static struct ldb_cmdline options; /* needs to be static for older compilers */ enum ldb_cmdline_options { CMDLINE_RELAX=1 }; static struct poptOption builtin_popt_options[] = { POPT_AUTOHELP { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, { "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" }, { "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" }, { "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" }, { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL }, { "trace", 0, POPT_ARG_NONE, &options.tracing, 0, "enable tracing", NULL }, { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL }, { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL }, { "modules-path", 0, POPT_ARG_STRING, &options.modules_path, 0, "modules path", "PATH" }, { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL }, { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL }, { "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL }, { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL }, { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL }, { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL }, { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL }, { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL }, { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL }, { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, { NULL } }; void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) { poptContext pc; struct poptOption **popt_options = ldb_module_popt_options(ldb); pc = poptGetContext(cmdname, 0, NULL, *popt_options, POPT_CONTEXT_KEEP_FIRST); poptPrintHelp(pc, f, 0); } /* add a control to the options structure */ static bool add_control(TALLOC_CTX *mem_ctx, const char *control) { unsigned int i; /* count how many controls we already have */ for (i=0; options.controls && options.controls[i]; i++) ; options.controls = talloc_realloc(mem_ctx, options.controls, const char *, i + 2); if (options.controls == NULL) { return false; } options.controls[i] = control; options.controls[i+1] = NULL; return true; } /** process command line options */ static struct ldb_cmdline *ldb_cmdline_process_internal(struct ldb_context *ldb, int argc, const char **argv, void (*usage)(struct ldb_context *), bool search) { struct ldb_cmdline *ret=NULL; poptContext pc; int num_options = 0; int opt; unsigned int flags = 0; int rc; struct poptOption **popt_options; /* make the ldb utilities line buffered */ setlinebuf(stdout); ret = talloc_zero(ldb, struct ldb_cmdline); if (ret == NULL) { fprintf(stderr, "Out of memory!\n"); goto failed; } options = *ret; /* pull in URL */ options.url = getenv("LDB_URL"); /* and editor (used by ldbedit) */ options.editor = getenv("VISUAL"); if (!options.editor) { options.editor = getenv("EDITOR"); } if (!options.editor) { options.editor = "vi"; } options.scope = LDB_SCOPE_DEFAULT; popt_options = ldb_module_popt_options(ldb); (*popt_options) = builtin_popt_options; rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc)); goto failed; } pc = poptGetContext(argv[0], argc, argv, *popt_options, POPT_CONTEXT_KEEP_FIRST); while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 's': { const char *arg = poptGetOptArg(pc); if (strcmp(arg, "base") == 0) { options.scope = LDB_SCOPE_BASE; } else if (strcmp(arg, "sub") == 0) { options.scope = LDB_SCOPE_SUBTREE; } else if (strcmp(arg, "one") == 0) { options.scope = LDB_SCOPE_ONELEVEL; } else { fprintf(stderr, "Invalid scope '%s'\n", arg); goto failed; } break; } case 'v': options.verbose++; break; case 'o': options.options = talloc_realloc(ret, options.options, const char *, num_options+3); if (options.options == NULL) { fprintf(stderr, "Out of memory!\n"); goto failed; } options.options[num_options] = poptGetOptArg(pc); options.options[num_options+1] = NULL; num_options++; break; case 'c': { const char *cs = poptGetOptArg(pc); const char *p; for (p = cs; p != NULL; ) { const char *t, *c; t = strchr(p, ','); if (t == NULL) { c = talloc_strdup(options.controls, p); p = NULL; } else { c = talloc_strndup(options.controls, p, t-p); p = t + 1; } if (c == NULL || !add_control(ret, c)) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } } break; } case 'P': if (!add_control(ret, "paged_results:1:1024")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'D': if (!add_control(ret, "show_deleted:1")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'R': if (!add_control(ret, "show_recycled:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'd': if (!add_control(ret, "show_deactivated_link:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'r': if (!add_control(ret, "reveal_internals:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case CMDLINE_RELAX: if (!add_control(ret, "relax:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'N': if (!add_control(ret, "search_options:1:2")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'E': if (!add_control(ret, "extended_dn:1:1")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; default: fprintf(stderr, "Invalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); if (usage) usage(ldb); goto failed; } } /* setup the remaining options for the main program to use */ options.argv = poptGetArgs(pc); if (options.argv) { options.argv++; while (options.argv[options.argc]) options.argc++; } *ret = options; /* all utils need some option */ if (ret->url == NULL) { fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); if (usage) usage(ldb); goto failed; } if (strcmp(ret->url, "NONE") == 0) { return ret; } if (options.nosync) { flags |= LDB_FLG_NOSYNC; } if (search) { flags |= LDB_FLG_DONT_CREATE_DB; if (options.show_binary) { flags |= LDB_FLG_SHOW_BINARY; } } if (options.tracing) { flags |= LDB_FLG_ENABLE_TRACING; } if (options.modules_path != NULL) { ldb_set_modules_dir(ldb, options.modules_path); } rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc)); goto failed; } /* now connect to the ldb */ if (ldb_connect(ldb, ret->url, flags, ret->options) != LDB_SUCCESS) { fprintf(stderr, "Failed to connect to %s - %s\n", ret->url, ldb_errstring(ldb)); goto failed; } rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc)); goto failed; } return ret; failed: talloc_free(ret); exit(LDB_ERR_OPERATIONS_ERROR); return NULL; } struct ldb_cmdline *ldb_cmdline_process_search(struct ldb_context *ldb, int argc, const char **argv, void (*usage)(struct ldb_context *)) { return ldb_cmdline_process_internal(ldb, argc, argv, usage, true); } struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv, void (*usage)(struct ldb_context *)) { return ldb_cmdline_process_internal(ldb, argc, argv, usage, false); } /* this function check controls reply and determines if more * processing is needed setting up the request controls correctly * * returns: * -1 error * 0 all ok * 1 all ok, more processing required */ int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request) { unsigned int i, j; int ret = 0; if (reply == NULL || request == NULL) return -1; for (i = 0; reply[i]; i++) { if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) { struct ldb_vlv_resp_control *rep_control; rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control); /* check we have a matching control in the request */ for (j = 0; request[j]; j++) { if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0) break; } if (! request[j]) { fprintf(stderr, "Warning VLV reply received but no request have been made\n"); continue; } /* check the result */ if (rep_control->vlv_result != 0) { fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result); } else { fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount); } continue; } if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) { struct ldb_asq_control *rep_control; rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control); /* check the result */ if (rep_control->result != 0) { fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result); } continue; } if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) { struct ldb_paged_control *rep_control, *req_control; rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control); if (rep_control->cookie_len == 0) /* we are done */ break; /* more processing required */ /* let's fill in the request control with the new cookie */ for (j = 0; request[j]; j++) { if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0) break; } /* if there's a reply control we must find a request * control matching it */ if (! request[j]) return -1; req_control = talloc_get_type(request[j]->data, struct ldb_paged_control); if (req_control->cookie) talloc_free(req_control->cookie); req_control->cookie = (char *)talloc_memdup( req_control, rep_control->cookie, rep_control->cookie_len); req_control->cookie_len = rep_control->cookie_len; ret = 1; continue; } if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) { struct ldb_sort_resp_control *rep_control; rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control); /* check we have a matching control in the request */ for (j = 0; request[j]; j++) { if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0) break; } if (! request[j]) { fprintf(stderr, "Warning Server Sort reply received but no request found\n"); continue; } /* check the result */ if (rep_control->result != 0) { fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result); } continue; } if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) { struct ldb_dirsync_control *rep_control, *req_control; char *cookie; rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); if (rep_control->cookie_len == 0) /* we are done */ break; /* more processing required */ /* let's fill in the request control with the new cookie */ for (j = 0; request[j]; j++) { if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0) break; } /* if there's a reply control we must find a request * control matching it */ if (! request[j]) return -1; req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); if (req_control->cookie) talloc_free(req_control->cookie); req_control->cookie = (char *)talloc_memdup( req_control, rep_control->cookie, rep_control->cookie_len); req_control->cookie_len = rep_control->cookie_len; cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); printf("# DIRSYNC cookie returned was:\n# %s\n", cookie); continue; } if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, reply[i]->oid) == 0) { struct ldb_dirsync_control *rep_control, *req_control; char *cookie; rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); if (rep_control->cookie_len == 0) /* we are done */ break; /* more processing required */ /* let's fill in the request control with the new cookie */ for (j = 0; request[j]; j++) { if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, request[j]->oid) == 0) break; } /* if there's a reply control we must find a request * control matching it */ if (! request[j]) return -1; req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); if (req_control->cookie) talloc_free(req_control->cookie); req_control->cookie = (char *)talloc_memdup( req_control, rep_control->cookie, rep_control->cookie_len); req_control->cookie_len = rep_control->cookie_len; cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); printf("# DIRSYNC_EX cookie returned was:\n# %s\n", cookie); continue; } /* no controls matched, throw a warning */ fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid); } return ret; } ldb-2.0.8/tools/cmdline.h0000660000000000000000000000343413055076237015156 0ustar rootroot00000000000000/* ldb database library - command line handling for ldb tools Copyright (C) Andrew Tridgell 2005 ** 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 . */ #include struct ldb_cmdline { const char *url; enum ldb_scope scope; const char *basedn; const char *modules_path; int interactive; int sorted; const char *editor; int verbose; int recursive; int all_records; int nosync; const char **options; int argc; const char **argv; int num_records; int num_searches; const char *sasl_mechanism; const char **controls; int show_binary; int tracing; }; struct ldb_cmdline *ldb_cmdline_process_search(struct ldb_context *ldb, int argc, const char **argv, void (*usage)(struct ldb_context *)); struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv, void (*usage)(struct ldb_context *)); int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f); ldb-2.0.8/tools/ldbadd.c0000660000000000000000000001105112406075657014746 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldbadd * * Description: utility to add records - modelled on ldapadd * * Author: Andrew Tridgell */ #include "replace.h" #include "ldb.h" #include "tools/cmdline.h" #include "ldbutil.h" #include "include/ldb_private.h" static struct ldb_cmdline *options; static void usage(struct ldb_context *ldb) { printf("Usage: ldbadd \n"); printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); ldb_cmdline_help(ldb, "ldbadd", stdout); exit(LDB_ERR_OPERATIONS_ERROR); } /* add records from an opened file */ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) { struct ldb_ldif *ldif; int fun_ret = LDB_SUCCESS, ret; struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); struct ldif_read_file_state state = { .f = f }; if (options->controls != NULL && req_ctrls== NULL) { printf("parsing controls failed: %s\n", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } fun_ret = ldb_transaction_start(ldb); if (fun_ret != LDB_SUCCESS) { fprintf(stderr, "ERR: (%s) on transaction start\n", ldb_errstring(ldb)); return fun_ret; } while ((ldif = ldb_ldif_read_file_state(ldb, &state))) { if (ldif->changetype != LDB_CHANGETYPE_ADD && ldif->changetype != LDB_CHANGETYPE_NONE) { fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); break; } ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg); if (ret != LDB_SUCCESS) { fprintf(stderr, "ERR: Message canonicalize failed - %s\n", ldb_strerror(ret)); fun_ret = ret; ldb_ldif_read_free(ldb, ldif); continue; } ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); if (ret != LDB_SUCCESS) { fprintf(stderr, "ERR: %s : \"%s\" on DN %s at block before line %llu\n", ldb_strerror(ret), ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn), (unsigned long long)state.line_no); fun_ret = ret; } else { (*count)++; if (options->verbose) { printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn)); } } ldb_ldif_read_free(ldb, ldif); if (ret) { break; } } if (fun_ret == LDB_SUCCESS && !feof(f)) { fprintf(stderr, "Failed to parse ldif\n"); fun_ret = LDB_ERR_OPERATIONS_ERROR; } if (fun_ret == LDB_SUCCESS) { fun_ret = ldb_transaction_commit(ldb); if (fun_ret != LDB_SUCCESS) { fprintf(stderr, "ERR: (%s) on transaction commit\n", ldb_errstring(ldb)); } } else { ldb_transaction_cancel(ldb); } return fun_ret; } int main(int argc, const char **argv) { struct ldb_context *ldb; unsigned int i, count = 0; int ret = LDB_SUCCESS; TALLOC_CTX *mem_ctx = talloc_new(NULL); ldb = ldb_init(mem_ctx, NULL); if (ldb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } options = ldb_cmdline_process(ldb, argc, argv, usage); ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); return ret; } if (options->argc == 0) { ret = process_file(ldb, stdin, &count); } else { for (i=0;iargc;i++) { const char *fname = options->argv[i]; FILE *f; f = fopen(fname, "r"); if (!f) { perror(fname); return LDB_ERR_OPERATIONS_ERROR; } ret = process_file(ldb, f, &count); fclose(f); } } if (count != 0) { ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); return ret; } } else { ldb_transaction_cancel(ldb); } talloc_free(mem_ctx); if (ret) { printf("Add failed after processing %u records\n", count); } else { printf("Added %u records successfully\n", count); } return ret; } ldb-2.0.8/tools/ldbdel.c0000660000000000000000000000664412406075657014776 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldbdel * * Description: utility to delete records - modelled on ldapdelete * * Author: Andrew Tridgell */ #include "replace.h" #include "ldb.h" #include "tools/cmdline.h" #include "ldbutil.h" static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2) { return ldb_dn_compare((*msg1)->dn, (*msg2)->dn); } static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn,struct ldb_control **req_ctrls) { int ret; unsigned int i, total=0; const char *attrs[] = { NULL }; struct ldb_result *res; ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); if (ret != LDB_SUCCESS) return ret; /* sort the DNs, deepest first */ TYPESAFE_QSORT(res->msgs, res->count, dn_cmp); for (i = 0; i < res->count; i++) { if (ldb_delete_ctrl(ldb, res->msgs[i]->dn,req_ctrls) == LDB_SUCCESS) { total++; } else { printf("Failed to delete '%s' - %s\n", ldb_dn_get_linearized(res->msgs[i]->dn), ldb_errstring(ldb)); } } talloc_free(res); if (total == 0) { return LDB_ERR_OPERATIONS_ERROR; } printf("Deleted %u records\n", total); return LDB_SUCCESS; } static void usage(struct ldb_context *ldb) { printf("Usage: ldbdel \n"); printf("Deletes records from a ldb\n\n"); ldb_cmdline_help(ldb, "ldbdel", stdout); exit(LDB_ERR_OPERATIONS_ERROR); } int main(int argc, const char **argv) { struct ldb_control **req_ctrls; struct ldb_cmdline *options; struct ldb_context *ldb; int ret = 0, i; TALLOC_CTX *mem_ctx = talloc_new(NULL); ldb = ldb_init(mem_ctx, NULL); if (ldb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } options = ldb_cmdline_process(ldb, argc, argv, usage); if (options->argc < 1) { usage(ldb); } req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); if (options->controls != NULL && req_ctrls== NULL) { printf("parsing controls failed: %s\n", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } for (i=0;iargc;i++) { struct ldb_dn *dn; dn = ldb_dn_new(ldb, ldb, options->argv[i]); if (dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } if (options->recursive) { ret = ldb_delete_recursive(ldb, dn,req_ctrls); } else { ret = ldb_delete_ctrl(ldb, dn,req_ctrls); if (ret == LDB_SUCCESS) { printf("Deleted 1 record\n"); } } if (ret != LDB_SUCCESS) { printf("delete of '%s' failed - (%s) %s\n", ldb_dn_get_linearized(dn), ldb_strerror(ret), ldb_errstring(ldb)); } } talloc_free(mem_ctx); return ret; } ldb-2.0.8/tools/ldbdump.c0000660000000000000000000002076213573675413015176 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. simple ldb tdb dump util Copyright (C) Andrew Tridgell 2001 Copyright (C) Andrew Bartlett 2012 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 . */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include #include #include #ifdef HAVE_LMDB #include #endif /* ifdef HAVE_LMDB */ static struct ldb_context *ldb; bool show_index = false; bool validate_contents = false; static void print_data(TDB_DATA d) { unsigned char *p = (unsigned char *)d.dptr; int len = d.dsize; while (len--) { if (isprint(*p) && !strchr("\"\\", *p)) { fputc(*p, stdout); } else { printf("\\%02X", *p); } p++; } } static unsigned int pull_uint32(uint8_t *p) { return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); } static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *state) { int ret, i, j; struct ldb_dn *dn = state; struct ldb_message *msg = ldb_msg_new(NULL); struct ldb_val dbuf = { .data = _dbuf.dptr, .length = _dbuf.dsize, }; struct ldb_ldif ldif = { .msg = msg, .changetype = LDB_CHANGETYPE_NONE }; if (!msg) { return -1; } ret = ldb_unpack_data(ldb, &dbuf, msg); if (ret != 0) { fprintf(stderr, "Failed to parse record %*.*s as an LDB record\n", (int)key.dsize, (int)key.dsize, (char *)key.dptr); TALLOC_FREE(msg); return 0; } if (dn && ldb_dn_compare(msg->dn, dn) != 0) { TALLOC_FREE(msg); return 0; } if (!show_index && ldb_dn_is_special(msg->dn)) { const char *dn_lin = ldb_dn_get_linearized(msg->dn); if ((strcmp(dn_lin, "@BASEINFO") == 0) || (strncmp(dn_lin, "@INDEX:", strlen("@INDEX:")) == 0)) { /* the user has asked not to show index records. Also exclude BASEINFO as it contains meta-data which will be re-created if this database is restored */ TALLOC_FREE(msg); return 0; } } printf("# key: "); print_data(key); printf("\n# pack format: %#010x\n", pull_uint32(_dbuf.dptr)); if (!validate_contents || ldb_dn_is_special(msg->dn)) { ldb_ldif_write_file(ldb, stdout, &ldif); TALLOC_FREE(msg); return 0; } for (i=0;inum_elements;i++) { const struct ldb_schema_attribute *a; a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); for (j=0;jelements[i].num_values;j++) { struct ldb_val v; ret = a->syntax->ldif_write_fn(ldb, msg, &msg->elements[i].values[j], &v); if (ret != 0) { v = msg->elements[i].values[j]; if (ldb_should_b64_encode(ldb, &v)) { v.data = (uint8_t *)ldb_base64_encode(ldb, (char *)v.data, v.length); v.length = strlen((char *)v.data); } fprintf(stderr, "On %s element %s value %d (%*.*s) failed to convert to LDIF correctly, skipping possibly corrupt record\n", ldb_dn_get_linearized(msg->dn), msg->elements[i].name, j, (int)v.length, (int)v.length, v.data); TALLOC_FREE(msg); return 0; } } } ldb_ldif_write_file(ldb, stdout, &ldif); TALLOC_FREE(msg); return 0; } static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; const char *name = tdb_name(tdb); const char *prefix = ""; if (!name) name = "unnamed"; switch (level) { case TDB_DEBUG_ERROR: prefix = "ERROR: "; break; case TDB_DEBUG_WARNING: prefix = "WARNING: "; break; case TDB_DEBUG_TRACE: return; default: case TDB_DEBUG_FATAL: prefix = "FATAL: "; break; } va_start(ap, fmt); fprintf(stderr, "tdb(%s): %s", name, prefix); vfprintf(stderr, fmt, ap); va_end(ap); } static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) { traverse_fn(NULL, key, dbuf, keyname); } static int dump_tdb(const char *fname, struct ldb_dn *dn, bool emergency) { TDB_CONTEXT *tdb; struct tdb_logging_context logfn = { .log_fn = log_stderr, }; tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL); if (!tdb) { fprintf(stderr, "Failed to open %s\n", fname); return 1; } if (emergency) { return tdb_rescue(tdb, emergency_walk, dn) == 0; } 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] \n\n"); printf( " -h this help message\n"); printf( " -d DN dumps DN only\n"); printf( " -e emergency dump, for corrupt databases\n"); printf( " -i include index and @BASEINFO records in dump\n"); printf( " -c validate contents of the records\n"); } int main(int argc, char *argv[]) { bool emergency = false; int c, rc; char *fname; struct ldb_dn *dn = NULL; ldb = ldb_init(NULL, NULL); if (ldb == NULL) { fprintf(stderr, "ldb: ldb_init failed()"); exit(1); } rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run preconnect hooks (needed to get Samba LDIF handlers): %s\n", ldb_strerror(rc)); exit(1); } if (argc < 2) { printf("Usage: ldbdump \n"); exit(1); } while ((c = getopt( argc, argv, "hd:eic")) != -1) { switch (c) { case 'h': usage(); exit( 0); case 'd': dn = ldb_dn_new(ldb, ldb, optarg); if (!dn) { fprintf(stderr, "ldb failed to parse %s as a DN\n", optarg); exit(1); } break; case 'e': emergency = true; break; case 'i': show_index = true; break; case 'c': validate_contents = true; break; default: usage(); exit( 1); } } 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; } ldb-2.0.8/tools/ldbedit.c0000660000000000000000000002226013055076237015143 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldbedit * * Description: utility for ldb database editing * * Author: Andrew Tridgell */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "system/filesys.h" #include "ldb.h" #include "tools/cmdline.h" #include "tools/ldbutil.h" static struct ldb_cmdline *options; /* debug routine */ static void ldif_write_msg(struct ldb_context *ldb, FILE *f, enum ldb_changetype changetype, struct ldb_message *msg) { struct ldb_ldif ldif; ldif.changetype = changetype; ldif.msg = msg; ldb_ldif_write_file(ldb, f, &ldif); } /* modify a database record so msg1 becomes msg2 returns the number of modified elements */ static int modify_record(struct ldb_context *ldb, struct ldb_message *msg1, struct ldb_message *msg2, struct ldb_control **req_ctrls) { int ret; struct ldb_message *mod; if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) { fprintf(stderr, "Failed to calculate message differences\n"); return -1; } ret = mod->num_elements; if (ret == 0) { goto done; } if (options->verbose > 0) { ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); } if (ldb_modify_ctrl(ldb, mod, req_ctrls) != LDB_SUCCESS) { fprintf(stderr, "failed to modify %s - %s\n", ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb)); ret = -1; goto done; } done: talloc_free(mod); return ret; } /* find dn in msgs[] */ static struct ldb_message *msg_find(struct ldb_context *ldb, struct ldb_message **msgs, unsigned int count, struct ldb_dn *dn) { unsigned int i; for (i=0;idn) == 0) { return msgs[i]; } } return NULL; } /* merge the changes in msgs2 into the messages from msgs1 */ static int merge_edits(struct ldb_context *ldb, struct ldb_message **msgs1, unsigned int count1, struct ldb_message **msgs2, unsigned int count2) { unsigned int i; struct ldb_message *msg; int ret; unsigned int adds=0, modifies=0, deletes=0; struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); if (options->controls != NULL && req_ctrls == NULL) { fprintf(stderr, "parsing controls failed: %s\n", ldb_errstring(ldb)); return -1; } if (ldb_transaction_start(ldb) != LDB_SUCCESS) { fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb)); return -1; } /* do the adds and modifies */ for (i=0;idn); if (!msg) { if (options->verbose > 0) { ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]); } if (ldb_add_ctrl(ldb, msgs2[i], req_ctrls) != LDB_SUCCESS) { fprintf(stderr, "failed to add %s - %s\n", ldb_dn_get_linearized(msgs2[i]->dn), ldb_errstring(ldb)); ldb_transaction_cancel(ldb); return -1; } adds++; } else { ret = modify_record(ldb, msg, msgs2[i], req_ctrls); if (ret != -1) { modifies += (unsigned int) ret; } else { ldb_transaction_cancel(ldb); return -1; } } } /* do the deletes */ for (i=0;idn); if (!msg) { if (options->verbose > 0) { ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]); } if (ldb_delete_ctrl(ldb, msgs1[i]->dn, req_ctrls) != LDB_SUCCESS) { fprintf(stderr, "failed to delete %s - %s\n", ldb_dn_get_linearized(msgs1[i]->dn), ldb_errstring(ldb)); ldb_transaction_cancel(ldb); return -1; } deletes++; } } if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb)); return -1; } printf("# %u adds %u modifies %u deletes\n", adds, modifies, deletes); return 0; } /* save a set of messages as ldif to a file */ static int save_ldif(struct ldb_context *ldb, FILE *f, struct ldb_message **msgs, unsigned int count) { unsigned int i; fprintf(f, "# editing %u records\n", count); for (i=0;imsg; } /* the feof() test works here, even for the last line of the * file, as we parse ldif files character by character, and * feof() is only true if we have failed to read a character * from the file. So if the last line is bad, we don't get * feof() set, so we know the record was bad. Only if we * attempt to go to the next record will we get feof() and * thus consider that the ldif has ended without errors */ if (!feof(f)) { fprintf(stderr, "Error parsing ldif - aborting\n"); fclose(f); unlink(file_template); return -1; } fclose(f); unlink(file_template); return merge_edits(ldb, msgs1, count1, msgs2, count2); } static void usage(struct ldb_context *ldb) { printf("Usage: ldbedit \n"); ldb_cmdline_help(ldb, "ldbedit", stdout); exit(LDB_ERR_OPERATIONS_ERROR); } int main(int argc, const char **argv) { struct ldb_context *ldb; struct ldb_result *result = NULL; struct ldb_dn *basedn = NULL; int ret; const char *expression = "(|(objectClass=*)(distinguishedName=*))"; const char * const * attrs = NULL; TALLOC_CTX *mem_ctx = talloc_new(NULL); struct ldb_control **req_ctrls; unsigned int i; ldb = ldb_init(mem_ctx, NULL); if (ldb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } options = ldb_cmdline_process(ldb, argc, argv, usage); /* the check for '=' is for compatibility with ldapsearch */ if (options->argc > 0 && strchr(options->argv[0], '=')) { expression = options->argv[0]; options->argv++; options->argc--; } if (options->argc > 0) { attrs = (const char * const *)(options->argv); } if (options->basedn != NULL) { basedn = ldb_dn_new(ldb, ldb, options->basedn); if (basedn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } } for (i = 0; options->controls != NULL && options->controls[i] != NULL; i++) { if (strncmp(options->controls[i], "reveal_internals:", 17) == 0) { printf("Using reveal internals has unintended consequences.\n"); printf("If this is your intent, manually perform the search," " and use ldbmodify directly.\n"); return LDB_ERR_OPERATIONS_ERROR; } } req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); if (options->controls != NULL && req_ctrls== NULL) { printf("parsing controls failed: %s\n", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_search_ctrl(ldb, ldb, &result, basedn, options->scope, attrs, req_ctrls, "%s", expression); if (ret != LDB_SUCCESS) { printf("search failed - %s\n", ldb_errstring(ldb)); return ret; } if (result->count == 0) { printf("no matching records - cannot edit\n"); talloc_free(mem_ctx); return LDB_SUCCESS; } ret = do_edit(ldb, result->msgs, result->count, options->editor); talloc_free(mem_ctx); return ret == 0 ? LDB_SUCCESS : LDB_ERR_OPERATIONS_ERROR; } ldb-2.0.8/tools/ldbmodify.c0000660000000000000000000001110112406075657015501 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldbmodify * * Description: utility to modify records - modelled on ldapmodify * * Author: Andrew Tridgell */ #include "replace.h" #include "ldb.h" #include "tools/cmdline.h" #include "ldbutil.h" #include "include/ldb_private.h" static struct ldb_cmdline *options; static void usage(struct ldb_context *ldb) { printf("Usage: ldbmodify \n"); printf("Modifies a ldb based upon ldif change records\n\n"); ldb_cmdline_help(ldb, "ldbmodify", stdout); exit(LDB_ERR_OPERATIONS_ERROR); } /* process modifies for one file */ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) { struct ldb_ldif *ldif; int fun_ret = LDB_SUCCESS, ret; struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); struct ldif_read_file_state state = { .f = f }; if (options->controls != NULL && req_ctrls== NULL) { printf("parsing controls failed: %s\n", ldb_errstring(ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } fun_ret = ldb_transaction_start(ldb); if (fun_ret != LDB_SUCCESS) { fprintf(stderr, "ERR: (%s) on transaction start\n", ldb_errstring(ldb)); return fun_ret; } while ((ldif = ldb_ldif_read_file_state(ldb, &state))) { struct ldb_dn *olddn; bool deleteoldrdn = false; struct ldb_dn *newdn; const char *errstr = NULL; switch (ldif->changetype) { case LDB_CHANGETYPE_NONE: case LDB_CHANGETYPE_ADD: ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); break; case LDB_CHANGETYPE_DELETE: ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls); break; case LDB_CHANGETYPE_MODIFY: ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls); break; case LDB_CHANGETYPE_MODRDN: ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, &olddn, NULL, &deleteoldrdn, NULL, &newdn); if (ret == LDB_SUCCESS) { if (deleteoldrdn) { ret = ldb_rename(ldb, olddn, newdn); } else { errstr = "modrdn: deleteoldrdn=0 " "not supported."; ret = LDB_ERR_CONSTRAINT_VIOLATION; } } break; } if (ret != LDB_SUCCESS) { if (errstr == NULL) { errstr = ldb_errstring(ldb); } fprintf(stderr, "ERR: (%s) \"%s\" on DN %s at block before line %llu\n", ldb_strerror(ret), errstr, ldb_dn_get_linearized(ldif->msg->dn), (unsigned long long)state.line_no); fun_ret = ret; } else { (*count)++; if (options->verbose) { printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn)); } } ldb_ldif_read_free(ldb, ldif); if (ret) { break; } } if (fun_ret == LDB_SUCCESS && !feof(f)) { fprintf(stderr, "Failed to parse ldif\n"); fun_ret = LDB_ERR_OPERATIONS_ERROR; } if (fun_ret == LDB_SUCCESS) { fun_ret = ldb_transaction_commit(ldb); if (fun_ret != LDB_SUCCESS) { fprintf(stderr, "ERR: (%s) on transaction commit\n", ldb_errstring(ldb)); } } else { ldb_transaction_cancel(ldb); } return fun_ret; } int main(int argc, const char **argv) { struct ldb_context *ldb; unsigned int i, count = 0; int ret = LDB_SUCCESS; TALLOC_CTX *mem_ctx = talloc_new(NULL); ldb = ldb_init(mem_ctx, NULL); if (ldb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } options = ldb_cmdline_process(ldb, argc, argv, usage); if (options->argc == 0) { ret = process_file(ldb, stdin, &count); } else { for (i=0;iargc;i++) { const char *fname = options->argv[i]; FILE *f; f = fopen(fname, "r"); if (!f) { perror(fname); return LDB_ERR_OPERATIONS_ERROR; } ret = process_file(ldb, f, &count); fclose(f); } } talloc_free(mem_ctx); if (ret) { printf("Modify failed after processing %u records\n", count); } else { printf("Modified %u records successfully\n", count); } return ret; } ldb-2.0.8/tools/ldbrename.c0000660000000000000000000000423212406075657015470 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 Copyright (C) Stefan Metzmacher 2004 ** 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 . */ /* * Name: ldb * * Component: ldbrename * * Description: utility to rename records - modelled on ldapmodrdn * * Author: Andrew Tridgell * Author: Stefan Metzmacher */ #include "replace.h" #include "ldb.h" #include "tools/cmdline.h" static void usage(struct ldb_context *ldb) { printf("Usage: ldbrename [] \n"); printf("Renames records in a ldb\n\n"); ldb_cmdline_help(ldb, "ldbmodify", stdout); exit(LDB_ERR_OPERATIONS_ERROR); } int main(int argc, const char **argv) { struct ldb_context *ldb; int ret; struct ldb_cmdline *options; struct ldb_dn *dn1, *dn2; TALLOC_CTX *mem_ctx = talloc_new(NULL); ldb = ldb_init(mem_ctx, NULL); if (ldb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } options = ldb_cmdline_process(ldb, argc, argv, usage); if (options->argc < 2) { usage(ldb); } dn1 = ldb_dn_new(ldb, ldb, options->argv[0]); dn2 = ldb_dn_new(ldb, ldb, options->argv[1]); if ((dn1 == NULL) || (dn2 == NULL)) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_rename(ldb, dn1, dn2); if (ret == LDB_SUCCESS) { printf("Renamed 1 record\n"); } else { printf("rename of '%s' to '%s' failed - %s\n", options->argv[0], options->argv[1], ldb_errstring(ldb)); } talloc_free(mem_ctx); return ret; } ldb-2.0.8/tools/ldbsearch.c0000660000000000000000000002026613573675413015475 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldbsearch * * Description: utility for ldb search - modelled on ldapsearch * * Author: Andrew Tridgell */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb.h" #include "tools/cmdline.h" static void usage(struct ldb_context *ldb) { printf("Usage: ldbsearch \n"); ldb_cmdline_help(ldb, "ldbsearch", stdout); exit(LDB_ERR_OPERATIONS_ERROR); } static int do_compare_msg(struct ldb_message **el1, struct ldb_message **el2, void *opaque) { return ldb_dn_compare((*el1)->dn, (*el2)->dn); } struct search_context { struct ldb_context *ldb; struct ldb_control **req_ctrls; int sort; unsigned int num_stored; struct ldb_message **store; unsigned int refs_stored; char **refs_store; unsigned int entries; unsigned int refs; unsigned int pending; int status; }; static int store_message(struct ldb_message *msg, struct search_context *sctx) { sctx->store = talloc_realloc(sctx, sctx->store, struct ldb_message *, sctx->num_stored + 2); if (!sctx->store) { fprintf(stderr, "talloc_realloc failed while storing messages\n"); return -1; } sctx->store[sctx->num_stored] = talloc_move(sctx->store, &msg); sctx->num_stored++; sctx->store[sctx->num_stored] = NULL; return 0; } static int store_referral(char *referral, struct search_context *sctx) { sctx->refs_store = talloc_realloc(sctx, sctx->refs_store, char *, sctx->refs_stored + 2); if (!sctx->refs_store) { fprintf(stderr, "talloc_realloc failed while storing referrals\n"); return -1; } sctx->refs_store[sctx->refs_stored] = talloc_move(sctx->refs_store, &referral); sctx->refs_stored++; sctx->refs_store[sctx->refs_stored] = NULL; return 0; } static int display_message(struct ldb_message *msg, struct search_context *sctx) { struct ldb_ldif ldif; sctx->entries++; printf("# record %d\n", sctx->entries); ldif.changetype = LDB_CHANGETYPE_NONE; ldif.msg = msg; if (sctx->sort) { /* * Ensure attributes are always returned in the same * order. For testing, this makes comparison of old * vs. new much easier. */ ldb_msg_sort_elements(ldif.msg); } ldb_ldif_write_file(sctx->ldb, stdout, &ldif); return 0; } static int display_referral(char *referral, struct search_context *sctx) { sctx->refs++; printf("# Referral\nref: %s\n\n", referral); return 0; } static int search_callback(struct ldb_request *req, struct ldb_reply *ares) { struct search_context *sctx; int ret = LDB_SUCCESS; sctx = talloc_get_type(req->context, struct search_context); if (!ares) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_request_done(req, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: if (sctx->sort) { ret = store_message(ares->message, sctx); } else { ret = display_message(ares->message, sctx); } break; case LDB_REPLY_REFERRAL: if (sctx->sort) { ret = store_referral(ares->referral, sctx); } else { ret = display_referral(ares->referral, sctx); } if (ret) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } break; case LDB_REPLY_DONE: if (ares->controls) { if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1) sctx->pending = 1; } talloc_free(ares); return ldb_request_done(req, LDB_SUCCESS); } talloc_free(ares); if (ret != LDB_SUCCESS) { return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); } return LDB_SUCCESS; } static int do_search(struct ldb_context *ldb, struct ldb_dn *basedn, struct ldb_cmdline *options, const char *expression, const char * const *attrs) { struct ldb_request *req; struct search_context *sctx; int ret; req = NULL; sctx = talloc_zero(ldb, struct search_context); if (!sctx) return LDB_ERR_OPERATIONS_ERROR; sctx->ldb = ldb; sctx->sort = options->sorted; sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls); if (options->controls != NULL && sctx->req_ctrls== NULL) { printf("parsing controls failed: %s\n", ldb_errstring(ldb)); return LDB_ERR_OPERATIONS_ERROR; } again: /* free any previous requests */ if (req) talloc_free(req); ret = ldb_build_search_req(&req, ldb, ldb, basedn, options->scope, expression, attrs, sctx->req_ctrls, sctx, search_callback, NULL); if (ret != LDB_SUCCESS) { talloc_free(sctx); printf("allocating request failed: %s\n", ldb_errstring(ldb)); return ret; } if (basedn == NULL) { /* we need to use a NULL base DN when doing a cross-ncs search so we find results on all partitions in a forest. When doing a domain-local search, default to the default basedn */ struct ldb_control *ctrl; struct ldb_search_options_control *search_options = NULL; ctrl = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID); if (ctrl) { search_options = talloc_get_type(ctrl->data, struct ldb_search_options_control); } if (ctrl == NULL || search_options == NULL || !(search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) { struct ldb_dn *base = ldb_get_default_basedn(ldb); if (base != NULL) { req->op.search.base = base; } } } sctx->pending = 0; ret = ldb_request(ldb, req); if (ret != LDB_SUCCESS) { talloc_free(sctx); talloc_free(req); printf("search failed - %s\n", ldb_errstring(ldb)); return ret; } ret = ldb_wait(req->handle, LDB_WAIT_ALL); if (ret != LDB_SUCCESS) { talloc_free(sctx); talloc_free(req); printf("search error - %s\n", ldb_errstring(ldb)); return ret; } if (sctx->pending) goto again; if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) { unsigned int i; if (sctx->num_stored) { LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg); } for (i = 0; i < sctx->num_stored; i++) { display_message(sctx->store[i], sctx); } for (i = 0; i < sctx->refs_stored; i++) { display_referral(sctx->refs_store[i], sctx); } } printf("# returned %u records\n# %u entries\n# %u referrals\n", sctx->entries + sctx->refs, sctx->entries, sctx->refs); talloc_free(sctx); talloc_free(req); return LDB_SUCCESS; } int main(int argc, const char **argv) { struct ldb_context *ldb; struct ldb_dn *basedn = NULL; const char * const * attrs = NULL; struct ldb_cmdline *options; int ret = -1; const char *expression = "(|(objectClass=*)(distinguishedName=*))"; TALLOC_CTX *mem_ctx = talloc_new(NULL); ldb = ldb_init(mem_ctx, NULL); if (ldb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } options = ldb_cmdline_process_search(ldb, argc, argv, usage); /* the check for '=' is for compatibility with ldapsearch */ if (!options->interactive && options->argc > 0 && strpbrk(options->argv[0], "=<>~:")) { expression = options->argv[0]; options->argv++; options->argc--; } if (options->argc > 0) { attrs = (const char * const *)(options->argv); } if (options->basedn != NULL) { basedn = ldb_dn_new(ldb, ldb, options->basedn); if (basedn == NULL) { talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } } if (options->interactive) { char line[1024]; while (fgets(line, sizeof(line), stdin)) { ret = do_search(ldb, basedn, options, line, attrs); } } else { ret = do_search(ldb, basedn, options, expression, attrs); } talloc_free(mem_ctx); return ret; } ldb-2.0.8/tools/ldbtest.c0000660000000000000000000002617613573675413015215 0ustar rootroot00000000000000/* ldb database library Copyright (C) Andrew Tridgell 2004 ** 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 . */ /* * Name: ldb * * Component: ldbtest * * Description: utility to test ldb * * Author: Andrew Tridgell */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "ldb.h" #include "tools/cmdline.h" static struct timespec tp1,tp2; static struct ldb_cmdline *options; static void _start_timer(void) { if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) { clock_gettime(CLOCK_REALTIME, &tp1); } } static double _end_timer(void) { if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) { clock_gettime(CLOCK_REALTIME, &tp2); } return((tp2.tv_sec - tp1.tv_sec) + (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); } static void add_records(struct ldb_context *ldb, struct ldb_dn *basedn, unsigned int count) { struct ldb_message msg = {0}; unsigned int i; #if 0 if (ldb_lock(ldb, "transaction") != 0) { printf("transaction lock failed\n"); exit(LDB_ERR_OPERATIONS_ERROR); } #endif for (i=0;icount != 1)) { printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } if (uid >= nrecords && res->count > 0) { printf("Found %s !? - %d\n", expr, ret); exit(LDB_ERR_OPERATIONS_ERROR); } printf("Testing uid %d/%d - %d \r", i, uid, res->count); fflush(stdout); talloc_free(res); talloc_free(expr); } printf("\n"); } static void start_test(struct ldb_context *ldb, unsigned int nrecords, unsigned int nsearches) { struct ldb_dn *basedn; basedn = ldb_dn_new(ldb, ldb, options->basedn); if ( ! ldb_dn_validate(basedn)) { printf("Invalid base DN format\n"); exit(LDB_ERR_INVALID_DN_SYNTAX); } printf("Adding %d records\n", nrecords); add_records(ldb, basedn, nrecords); printf("Starting search on uid\n"); _start_timer(); search_uid(ldb, basedn, nrecords, nsearches); printf("uid search took %.2f seconds\n", _end_timer()); printf("Modifying records\n"); modify_records(ldb, basedn, nrecords); printf("Deleting records\n"); delete_records(ldb, basedn, nrecords); } /* 2) Store an @indexlist record 3) Store a record that contains fields that should be index according to @index 4) disconnection from database 5) connect to same database 6) search for record added in step 3 using a search key that should be indexed */ static void start_test_index(struct ldb_context **ldb) { struct ldb_message *msg; struct ldb_result *res = NULL; struct ldb_dn *indexlist; struct ldb_dn *basedn; int ret; unsigned int flags = 0; const char *specials; specials = getenv("LDB_SPECIALS"); if (specials && atoi(specials) == 0) { printf("LDB_SPECIALS disabled - skipping index test\n"); return; } if (options->nosync) { flags |= LDB_FLG_NOSYNC; } printf("Starting index test\n"); indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); ldb_delete(*ldb, indexlist); msg = ldb_msg_new(NULL); if (msg == NULL) { printf("ldb_msg_new failed\n"); exit(LDB_ERR_OPERATIONS_ERROR); } msg->dn = indexlist; ldb_msg_add_string(msg, "@IDXATTR", strdup("uid")); if (ldb_add(*ldb, msg) != 0) { printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } basedn = ldb_dn_new(*ldb, *ldb, options->basedn); memset(msg, 0, sizeof(*msg)); msg->dn = ldb_dn_copy(msg, basedn); ldb_dn_add_child_fmt(msg->dn, "cn=test"); ldb_msg_add_string(msg, "cn", strdup("test")); ldb_msg_add_string(msg, "sn", strdup("test")); ldb_msg_add_string(msg, "uid", strdup("test")); ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson")); if (ldb_add(*ldb, msg) != LDB_SUCCESS) { printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } if (talloc_free(*ldb) != 0) { printf("failed to free/close ldb database"); exit(LDB_ERR_OPERATIONS_ERROR); } (*ldb) = ldb_init(options, NULL); ret = ldb_connect(*ldb, options->url, flags, NULL); if (ret != LDB_SUCCESS) { printf("failed to connect to %s\n", options->url); exit(LDB_ERR_OPERATIONS_ERROR); } basedn = ldb_dn_new(*ldb, *ldb, options->basedn); msg->dn = basedn; ldb_dn_add_child_fmt(msg->dn, "cn=test"); ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test"); if (ret != LDB_SUCCESS) { printf("Search with (uid=test) filter failed!\n"); exit(LDB_ERR_OPERATIONS_ERROR); } if(res->count != 1) { printf("Should have found 1 record - found %d\n", res->count); exit(LDB_ERR_OPERATIONS_ERROR); } indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); if (ldb_delete(*ldb, msg->dn) != 0 || ldb_delete(*ldb, indexlist) != 0) { printf("cleanup failed - %s\n", ldb_errstring(*ldb)); exit(LDB_ERR_OPERATIONS_ERROR); } printf("Finished index test\n"); } static void usage(struct ldb_context *ldb) { printf("Usage: ldbtest \n"); printf("Options:\n"); printf(" -H ldb_url choose the database (or $LDB_URL)\n"); printf(" --num-records nrecords database size to use\n"); printf(" --num-searches nsearches number of searches to do\n"); printf("\n"); printf("tests ldb API\n\n"); exit(LDB_ERR_OPERATIONS_ERROR); } int main(int argc, const char **argv) { TALLOC_CTX *mem_ctx = talloc_new(NULL); struct ldb_context *ldb; ldb = ldb_init(mem_ctx, NULL); if (ldb == NULL) { return LDB_ERR_OPERATIONS_ERROR; } options = ldb_cmdline_process(ldb, argc, argv, usage); talloc_steal(mem_ctx, options); if (options->basedn == NULL) { options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST"; } srandom(1); printf("Testing with num-records=%d and num-searches=%d\n", options->num_records, options->num_searches); start_test(ldb, (unsigned int) options->num_records, (unsigned int) options->num_searches); start_test_index(&ldb); talloc_free(mem_ctx); return LDB_SUCCESS; } ldb-2.0.8/tools/ldbutil.c0000660000000000000000000001144412406075657015201 0ustar rootroot00000000000000/* ldb database library utility Copyright (C) Matthieu Patou 2009 ** 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 . */ /* * Name: ldb * * Description: Common function used by ldb_add/ldb_modify/ldb_delete * * Author: Matthieu Patou */ #include "replace.h" #include "ldb.h" #include "ldb_module.h" #include "ldbutil.h" /* autostarts a transacion if none active */ static int ldb_do_autotransaction(struct ldb_context *ldb, struct ldb_request *req) { int ret; ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_request(ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret == LDB_SUCCESS) { return ldb_transaction_commit(ldb); } ldb_transaction_cancel(ldb); if (ldb_errstring(ldb) == NULL) { /* no error string was setup by the backend */ ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); } return ret; } /* Same as ldb_add but accept control */ int ldb_add_ctrl(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_control **controls) { struct ldb_request *req; int ret; ret = ldb_msg_sanity_check(ldb, message); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_build_add_req(&req, ldb, ldb, message, controls, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) return ret; /* do request and autostart a transaction */ ret = ldb_do_autotransaction(ldb, req); talloc_free(req); return ret; } /* same as ldb_delete but accept control */ int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, struct ldb_control **controls) { struct ldb_request *req; int ret; ret = ldb_build_del_req(&req, ldb, ldb, dn, controls, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) return ret; /* do request and autostart a transaction */ ret = ldb_do_autotransaction(ldb, req); talloc_free(req); return ret; } /* same as ldb_modify, but accepts controls */ int ldb_modify_ctrl(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_control **controls) { struct ldb_request *req; int ret; ret = ldb_msg_sanity_check(ldb, message); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_build_mod_req(&req, ldb, ldb, message, controls, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) return ret; /* do request and autostart a transaction */ ret = ldb_do_autotransaction(ldb, req); talloc_free(req); return ret; } /* ldb_search with controls */ int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result **result, struct ldb_dn *base, enum ldb_scope scope, const char * const *attrs, struct ldb_control **controls, const char *exp_fmt, ...) { struct ldb_request *req; struct ldb_result *res; char *expression; va_list ap; int ret; expression = NULL; *result = NULL; req = NULL; res = talloc_zero(mem_ctx, struct ldb_result); if (!res) { return LDB_ERR_OPERATIONS_ERROR; } if (exp_fmt) { va_start(ap, exp_fmt); expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); va_end(ap); if (!expression) { talloc_free(res); return LDB_ERR_OPERATIONS_ERROR; } } ret = ldb_build_search_req(&req, ldb, mem_ctx, base?base:ldb_get_default_basedn(ldb), scope, expression, attrs, controls, res, ldb_search_default_callback, NULL); ldb_req_set_location(req, "ldb_search_ctrl"); if (ret != LDB_SUCCESS) goto done; ret = ldb_request(ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } done: if (ret != LDB_SUCCESS) { talloc_free(res); res = NULL; } talloc_free(expression); talloc_free(req); *result = res; return ret; } ldb-2.0.8/tools/ldbutil.h0000660000000000000000000000320612761221116015166 0ustar rootroot00000000000000/* ldb database library utility header file Copyright (C) Matthieu Patou 2009 ** 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 . */ /* * Name: ldb * * Description: Common function used by ldb_add/ldb_modify/ldb_delete * * Author: Matthieu Patou */ #include "ldb.h" int ldb_add_ctrl(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_control **controls); int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, struct ldb_control **controls); int ldb_modify_ctrl(struct ldb_context *ldb, const struct ldb_message *message, struct ldb_control **controls); int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result **result, struct ldb_dn *base, enum ldb_scope scope, const char * const *attrs, struct ldb_control **controls, const char *exp_fmt, ...) PRINTF_ATTRIBUTE(8,9); ldb-2.0.8/web/index.html0000660000000000000000000000512012406075657015002 0ustar rootroot00000000000000 ldb

ldb

ldb is a LDAP-like embedded database. It is not at all LDAP standards compliant, so if you want a standards compliant database then please see the excellent OpenLDAP project.

What ldb does is provide a fast database with an LDAP-like API designed to be used within an application. In some ways it can be seen as a intermediate solution between key-value pair databases and a real LDAP database.

ldb is the database engine used in Samba4.

Features

The main features that separate ldb from other solutions are:
  • Safe multi-reader, multi-writer, using byte range locking
  • LDAP-like API
  • fast operation
  • choice of local tdb or remote LDAP backends
  • integration with talloc
  • schema-less operation, for trivial setup
  • modules for extensions (such as schema support)
  • easy setup of indexes and attribute properties
  • LDIF for import/export
  • ldbedit tool for database (via LDIF) editing (reminiscent of 'vipw')

Documentation

Currently ldb is completely lacking in programmer or user documentation. This is your opportunity to make a contribution! Start with the public functions declared in ldb.h and the example code in the tools directory. Documentation in the same docbook format used by Samba would be preferred.

Discussion and bug reports

ldb does not have its own mailing list or bug tracking system. Please use the samba-technical mailing list, and the Samba bugzilla bug tracking system.

Download

You can download the latest release here:
http://samba.org/ftp/pub/ldb Alternatively, you can fetch via git. See the following guide:
Using Git for Samba Development

Andrew Tridgell
ldb AT tridgell.net
ldb-2.0.8/wscript0000660000000000000000000006474613573675413013673 0ustar rootroot00000000000000#!/usr/bin/env python APPNAME = 'ldb' VERSION = '2.0.8' import sys, os # find the buildtools directory top = '.' while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: top = top + '/..' sys.path.insert(0, top + '/buildtools/wafsamba') out = 'bin' import wafsamba from wafsamba import samba_dist, samba_utils from waflib import Errors, Options, Logs, Context import shutil 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 third_party/popt:third_party/popt third_party/cmocka:third_party/cmocka buildtools:buildtools third_party/waf:third_party/waf''') samba_dist.DIST_FILES('''lib/util/binsearch.h:lib/util/binsearch.h lib/util/attr.h:lib/util/attr.h''') def options(opt): opt.BUILTIN_DEFAULT('replace') opt.PRIVATE_EXTENSION_DEFAULT('ldb', noextension='ldb') opt.RECURSE('lib/tdb') opt.RECURSE('lib/tevent') opt.RECURSE('lib/replace') opt.load('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') if conf.CHECK_FOR_THIRD_PARTY(): conf.RECURSE('third_party/popt') conf.RECURSE('third_party/cmocka') else: if not conf.CHECK_POPT(): raise Errors.WafError('popt development packages have not been found.\nIf third_party is installed, check that it is in the proper place.') else: conf.define('USING_SYSTEM_POPT', 1) if not conf.CHECK_CMOCKA(): raise Errors.WafError('cmocka development package have not been found.\nIf third_party is installed, check that it is in the proper place.') else: conf.define('USING_SYSTEM_CMOCKA', 1) conf.RECURSE('lib/replace') conf.find_program('xsltproc', var='XSLTPROC') conf.SAMBA_CHECK_PYTHON() conf.SAMBA_CHECK_PYTHON_HEADERS() # where does the default LIBDIR end up? in conf.env somewhere? # conf.CONFIG_PATH('LDB_MODULESDIR', conf.SUBST_ENV_VAR('MODULESDIR') + '/ldb') conf.env.standalone_ldb = conf.IN_LAUNCH_DIR() if not conf.env.standalone_ldb: max_ldb_version = [int(x) for x in VERSION.split(".")] max_ldb_version[2] = 999 max_ldb_version_dots = "%d.%d.%d" % tuple(max_ldb_version) if conf.env.disable_python: if conf.CHECK_BUNDLED_SYSTEM_PKG('ldb', minversion=VERSION, maxversion=max_ldb_version_dots, onlyif='talloc tdb tevent', implied_deps='replace talloc tdb tevent'): conf.define('USING_SYSTEM_LDB', 1) else: using_system_pyldb_util = True dflt_name = 'pyldb-util' + conf.all_envs['default']['PYTHON_SO_ABI_FLAG'] if not conf.CHECK_BUNDLED_SYSTEM_PKG(dflt_name, minversion=VERSION, maxversion=max_ldb_version_dots, onlyif='talloc tdb tevent', implied_deps='replace talloc tdb tevent ldb'): using_system_pyldb_util = False if using_system_pyldb_util: conf.define('USING_SYSTEM_PYLDB_UTIL', 1) if conf.CHECK_BUNDLED_SYSTEM_PKG('ldb', minversion=VERSION, maxversion=max_ldb_version_dots, onlyif='talloc tdb tevent %s' % dflt_name, 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 Errors.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])) conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_MINOR', int(v[1])) conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_RELEASE', int(v[2])) if conf.env.standalone_ldb: conf.CHECK_XSLTPROC_MANPAGES() # we need this for the ldap backend if conf.CHECK_FUNCS_IN('ber_flush ldap_open ldap_initialize', 'lber ldap', headers='lber.h ldap.h'): conf.env.ENABLE_LDAP_BACKEND = True # we don't want any libraries or modules to rely on runtime # resolution of symbols 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 Errors.WafError('ldb build (unless --without-ldb-lmdb) ' 'requires ' 'lmdb 0.9.16 or later') elif not Options.options.without_ad_dc: raise Errors.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.env.HAVE_LMDB = True conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True) conf.SAMBA_CONFIG_H() conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() def build(bld): bld.RECURSE('lib/tevent') if bld.CHECK_FOR_THIRD_PARTY(): bld.RECURSE('third_party/popt') bld.RECURSE('third_party/cmocka') bld.RECURSE('lib/replace') 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') COMMON_SRC = bld.SUBDIR('common', '''ldb_modules.c ldb_ldif.c ldb_parse.c ldb_msg.c ldb_utf8.c ldb_debug.c ldb_dn.c ldb_match.c ldb_options.c ldb_pack.c ldb_attributes.c attrib_handlers.c ldb_controls.c qsort.c''') bld.SAMBA_MODULE('ldb_ldap', 'ldb_ldap/ldb_ldap.c', init_function='ldb_ldap_init', module_init_name='ldb_init_module', deps='talloc lber ldap ldb', enabled=bld.env.ENABLE_LDAP_BACKEND, internal_module=False, subsystem='ldb') if bld.PYTHON_BUILD_IS_ENABLED(): if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): name = bld.pyembed_libname('pyldb-util') bld.SAMBA_LIBRARY(name, deps='replace ldb', source='pyldb_util.c', public_headers=('' if private_library else 'pyldb.h'), public_headers_install=not private_library, vnum=VERSION, private_library=private_library, pc_files='pyldb-util.pc', pyembed=True, enabled=bld.PYTHON_BUILD_IS_ENABLED(), abi_directory='ABI', abi_match='pyldb_*') if not bld.CONFIG_SET('USING_SYSTEM_LDB'): bld.SAMBA_PYTHON('pyldb', 'pyldb.c', deps='replace ldb ' + name, realname='ldb.so', cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) # Do only install this file as part of the Samba build if we do not # use the system libldb! if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): bld.SAMBA_SCRIPT('_ldb_text.py', pattern='_ldb_text.py', installdir='python') bld.INSTALL_FILES('${PYTHONARCHDIR}', '_ldb_text.py') if not bld.CONFIG_SET('USING_SYSTEM_LDB'): if bld.is_install: modules_dir = bld.EXPAND_VARIABLES('${LDB_MODULESDIR}') else: # when we run from the source directory, we want to use # the current modules, not the installed ones modules_dir = os.path.join(os.getcwd(), 'bin/modules/ldb') abi_match = '!ldb_*module_ops !ldb_*backend_ops ldb_*' ldb_headers = ('include/ldb.h include/ldb_errors.h ' 'include/ldb_module.h include/ldb_handlers.h') bld.SAMBA_LIBRARY('ldb', COMMON_SRC + ' ' + LDB_MAP_SRC, deps='tevent LIBLDB_MAIN replace', includes='include', public_headers=('' if private_library else ldb_headers), public_headers_install=not private_library, pc_files='ldb.pc', vnum=VERSION, private_library=private_library, manpages='man/ldb.3', abi_directory='ABI', abi_match = abi_match) # generate a include/ldb_version.h def generate_ldb_version_h(t): '''generate a vscript file for our public libraries''' tgt = t.outputs[0].bldpath(t.env) v = t.env.LDB_VERSION.split('.') f = open(tgt, mode='w') try: f.write('#define LDB_VERSION "%s"\n' % t.env.LDB_VERSION) f.write('#define LDB_VERSION_MAJOR %d\n' % int(v[0])) f.write('#define LDB_VERSION_MINOR %d\n' % int(v[1])) f.write('#define LDB_VERSION_RELEASE %d\n' % int(v[2])) finally: f.close() return t = bld.SAMBA_GENERATOR('ldb_version.h', rule=generate_ldb_version_h, dep_vars=['LDB_VERSION'], target='include/ldb_version.h', public_headers='include/ldb_version.h', public_headers_install=not private_library) t.env.LDB_VERSION = VERSION bld.SAMBA_MODULE('ldb_asq', 'modules/asq.c', init_function='ldb_asq_init', module_init_name='ldb_init_module', internal_module=False, deps='ldb', subsystem='ldb') bld.SAMBA_MODULE('ldb_server_sort', 'modules/sort.c', init_function='ldb_server_sort_init', internal_module=False, module_init_name='ldb_init_module', deps='ldb', subsystem='ldb') bld.SAMBA_MODULE('ldb_paged_searches', 'modules/paged_searches.c', init_function='ldb_paged_searches_init', internal_module=False, module_init_name='ldb_init_module', deps='ldb', subsystem='ldb') bld.SAMBA_MODULE('ldb_rdn_name', 'modules/rdn_name.c', init_function='ldb_rdn_name_init', internal_module=False, module_init_name='ldb_init_module', deps='ldb', subsystem='ldb') bld.SAMBA_MODULE('ldb_sample', 'tests/sample_module.c', init_function='ldb_sample_init', internal_module=False, module_init_name='ldb_init_module', deps='ldb', subsystem='ldb') bld.SAMBA_MODULE('ldb_skel', 'modules/skel.c', init_function='ldb_skel_init', internal_module=False, module_init_name='ldb_init_module', deps='ldb', subsystem='ldb') bld.SAMBA_MODULE('ldb_sqlite3', 'sqlite3/ldb_sqlite3.c', init_function='ldb_sqlite3_init', internal_module=False, module_init_name='ldb_init_module', enabled=False, deps='ldb', subsystem='ldb') 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='ldb ldb_tdb_int ldb_key_value', subsystem='ldb') bld.SAMBA_LIBRARY('ldb_tdb_int', bld.SUBDIR('ldb_tdb', '''ldb_tdb_wrap.c ldb_tdb.c'''), private_library=True, deps='ldb tdb ldb_key_value ldb_tdb_err_map') bld.SAMBA_LIBRARY('ldb_tdb_err_map', bld.SUBDIR('ldb_tdb', '''ldb_tdb_err_map.c '''), private_library=True, deps='ldb tdb') bld.SAMBA_LIBRARY('ldb_key_value', bld.SUBDIR('ldb_key_value', '''ldb_kv.c ldb_kv_search.c ldb_kv_index.c ldb_kv_cache.c'''), private_library=True, deps='tdb ldb ldb_tdb_err_map') 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', module_init_name='ldb_init_module', internal_module=False, deps='ldb ldb_tdb_int ldb_key_value' + lmdb_deps, subsystem='ldb') # have a separate subsystem for common/ldb.c, so it can rebuild # for install with a different -DLDB_MODULESDIR= bld.SAMBA_SUBSYSTEM('LIBLDB_MAIN', 'common/ldb.c', deps='tevent tdb', includes='include', cflags=['-DLDB_MODULESDIR=\"%s\"' % modules_dir]) LDB_TOOLS='ldbadd ldbsearch ldbdel ldbmodify ldbedit ldbrename' for t in LDB_TOOLS.split(): bld.SAMBA_BINARY(t, 'tools/%s.c' % t, deps='ldb-cmdline ldb', manpages='man/%s.1' % t) # ldbtest doesn't get installed 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, install=False) bld.SAMBA_LIBRARY('ldb-cmdline', source='tools/ldbutil.c tools/cmdline.c', deps='ldb dl popt', private_library=True) bld.SAMBA_BINARY('ldb_tdb_mod_op_test', source='tests/ldb_mod_op_test.c', cflags='-DTEST_BE=\"tdb\"', 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) bld.SAMBA_BINARY('test_ldb_dn', source='tests/test_ldb_dn.c', deps='cmocka ldb', install=False) bld.SAMBA_BINARY('ldb_match_test', source='tests/ldb_match_test.c', deps='cmocka ldb', install=False) bld.SAMBA_BINARY('ldb_key_value_test', source='tests/ldb_key_value_test.c', deps='cmocka ldb ldb_tdb_err_map', install=False) bld.SAMBA_BINARY('ldb_parse_test', source='tests/ldb_parse_test.c', deps='cmocka ldb ldb_tdb_err_map', install=False) bld.SAMBA_BINARY('ldb_filter_attrs_test', source='tests/ldb_filter_attrs_test.c', deps='cmocka ldb ldb_tdb_err_map', install=False) bld.SAMBA_BINARY('ldb_key_value_sub_txn_tdb_test', bld.SUBDIR('ldb_key_value', '''ldb_kv_search.c ldb_kv_index.c ldb_kv_cache.c''') + 'tests/ldb_key_value_sub_txn_test.c', cflags='-DTEST_BE=\"tdb\"', deps='cmocka ldb ldb_tdb_err_map', 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\" -DTEST_LMDB=1', deps='cmocka ldb', install=False) # # We rely on the versions of the ldb_key_value functions included # in ldb_key_value_sub_txn_test.c taking priority over the versions # in the ldb_key_value shared library. # If this turns out to not be the case, the dependencies will # need to be unrolled, and all the source files included and the # ldb_tdb module initialization code will need to be called # manually. bld.SAMBA_BINARY('ldb_key_value_sub_txn_mdb_test', bld.SUBDIR('ldb_key_value', '''ldb_kv_search.c ldb_kv_index.c ldb_kv_cache.c''') + 'tests/ldb_key_value_sub_txn_test.c', cflags='-DTEST_BE=\"mdb\"', deps='cmocka ldb ldb_tdb_err_map', install=False) else: bld.SAMBA_BINARY('ldb_no_lmdb_test', source='tests/ldb_no_lmdb_test.c', deps='cmocka ldb', install=False) def test(ctx): '''run ldb testsuite''' env = samba_utils.LOAD_ENVIRONMENT() ctx.env = env test_prefix = "%s/st" % (Context.g_module.out) shutil.rmtree(test_prefix, ignore_errors=True) os.makedirs(test_prefix) os.environ['TEST_DATA_PREFIX'] = test_prefix os.environ['LDB_MODULES_PATH'] = Context.g_module.out + "/modules/ldb" if env.HAVE_LMDB: os.environ['HAVE_LMDB'] = '1' else: os.environ['HAVE_LMDB'] = '0' samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') cmd = 'tests/test-tdb.sh %s' % Context.g_module.out ret = samba_utils.RUN_COMMAND(cmd) print("testsuite returned %d" % ret) tmp_dir = os.path.join(test_prefix, 'tmp') if not os.path.exists(tmp_dir): os.mkdir(tmp_dir) pyret = samba_utils.RUN_PYTHON_TESTS( ['tests/python/api.py', 'tests/python/index.py', 'tests/python/repack.py'], extra_env={'SELFTEST_PREFIX': test_prefix}) print("Python testsuite returned %d" % pyret) cmocka_ret = 0 test_exes = ['test_ldb_qsort', 'test_ldb_dn', '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_match_test', 'ldb_key_value_test', # we currently don't run ldb_key_value_sub_txn_tdb_test as it # tests the nested/sub transaction handling # on operations which the TDB backend does not currently # support # 'ldb_key_value_sub_txn_tdb_test' 'ldb_parse_test'] if env.HAVE_LMDB: test_exes += ['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', 'ldb_key_value_sub_txn_mdb_test'] else: test_exes += ['ldb_no_lmdb_test'] for test_exe in test_exes: cmd = os.path.join(Context.g_module.out, test_exe) cmocka_ret = cmocka_ret or samba_utils.RUN_COMMAND(cmd) sys.exit(ret or pyret or cmocka_ret) def dist(): '''makes a tarball for distribution''' samba_dist.dist() def reconfigure(ctx): '''reconfigure if config scripts have changed''' import samba_utils samba_utils.reconfigure(ctx) ldb-2.0.8/lib/replace/.checker_innocent0000660000000000000000000000024612406075657017717 0ustar rootroot00000000000000>>>MISTAKE21_create_files_6a9e68ada99a97cb >>>MISTAKE21_os2_delete_9b2bfa7f38711d09 >>>MISTAKE21_os2_delete_2fcc29aaa99a97cb >>>SECURITY2_os2_delete_9b2bfa7f1c9396ca ldb-2.0.8/lib/replace/Makefile0000660000000000000000000000153413573675413016060 0ustar rootroot00000000000000# simple makefile wrapper to run waf WAF_BINARY=$(PYTHON) ../../buildtools/bin/waf WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) all: $(WAF) build install: $(WAF) install uninstall: $(WAF) uninstall test: $(WAF) test $(TEST_OPTIONS) testenv: $(WAF) test --testenv $(TEST_OPTIONS) quicktest: $(WAF) test --quick $(TEST_OPTIONS) dist: touch .tmplock WAFLOCK=.tmplock $(WAF) dist distcheck: touch .tmplock WAFLOCK=.tmplock $(WAF) distcheck clean: $(WAF) clean distclean: $(WAF) distclean reconfigure: configure $(WAF) reconfigure show_waf_options: $(WAF) --help # some compatibility make targets everything: all testsuite: all check: test torture: all # this should do an install as well, once install is finished installcheck: test etags: $(WAF) etags ctags: $(WAF) ctags bin/%:: FORCE $(WAF) --targets=`basename $@` FORCE: ldb-2.0.8/lib/replace/README0000660000000000000000000000305113573675413015274 0ustar rootroot00000000000000This subsystem ensures that we can always use a certain core set of functions and types, that are either provided by the OS or by replacement functions / definitions in this subsystem. The aim is to try to stick to POSIX functions in here as much as possible. Convenience functions that are available on no platform at all belong in other subsystems (such as LIBUTIL). The following functions are guaranteed: ftruncate strlcpy strlcat mktime rename initgroups memmove strdup setlinebuf vsyslog timegm setenv unsetenv strndup strnlen waitpid seteuid setegid asprintf snprintf vasprintf vsnprintf opendir readdir telldir seekdir clock_gettime closedir dlopen dlclose dlsym dlerror chroot bzero strerror errno mkdtemp mkstemp (a secure one!) pread pwrite chown lchown readline (the library) inet_ntoa inet_ntop inet_pton inet_aton strtoll strtoull socketpair strptime getaddrinfo freeaddrinfo getnameinfo gai_strerror getifaddrs freeifaddrs utime utimes dup2 link readlink symlink realpath poll setproctitle memset_s Types: bool socklen_t uint{8,16,32,64}_t int{8,16,32,64}_t intptr_t sig_atomic_t blksize_t blkcnt_t Constants: PATH_NAME_MAX UINT{16,32,64}_MAX INT32_MAX RTLD_LAZY HOST_NAME_MAX UINT16_MAX UINT32_MAX UINT64_MAX CHAR_BIT Macros: va_copy __FUNCTION__ __FILE__ __LINE__ __LINESTR__ __location__ __STRING __STRINGSTRING MIN MAX QSORT_CAST ZERO_STRUCT ZERO_STRUCTP ZERO_STRUCTPN ZERO_ARRAY ARRAY_SIZE PTR_DIFF Headers: stdint.h stdbool.h Optional C keywords: volatile Prerequisites: memset (for bzero) syslog (for vsyslog) mktemp (for mkstemp and mkdtemp) ldb-2.0.8/lib/replace/closefrom.c0000660000000000000000000000515712746330636016556 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * Samba utility functions * Copyright (C) Volker Lendecke 2016 * * ** NOTE! The following LGPL license applies to the replace * ** 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 * Library 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 . */ #include "replace.h" #include #include #include static int closefrom_sysconf(int lower) { long max_files, fd; max_files = sysconf(_SC_OPEN_MAX); if (max_files == -1) { max_files = 65536; } for (fd=lower; fdd_name, &endptr, 10); if ((fd == 0) && (errno == EINVAL)) { continue; } if ((fd == ULLONG_MAX) && (errno == ERANGE)) { continue; } if (*endptr != '\0') { continue; } if (fd == dir_fd) { continue; } if (fd > INT_MAX) { continue; } if (fd < lower) { continue; } if (num_fds >= (fd_array_size / sizeof(int))) { void *tmp; if (fd_array_size == 0) { fd_array_size = 16 * sizeof(int); } else { if (fd_array_size + fd_array_size < fd_array_size) { /* overflow */ goto fail; } fd_array_size = fd_array_size + fd_array_size; } tmp = realloc(fds, fd_array_size); if (tmp == NULL) { goto fail; } fds = tmp; } fds[num_fds++] = fd; } for (i=0; i that this crypt routine may sometimes get the wrong answer. Only use UFC_CRYT if you really need it. */ #include "replace.h" #ifndef HAVE_CRYPT /* * UFC-crypt: ultra fast crypt(3) implementation * * Copyright (C) 1991-1998, Free Software Foundation, Inc. * * 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 * Library 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 . * * @(#)crypt_util.c 2.31 02/08/92 * * Support routines * */ #ifndef long32 #define long32 int32_t #endif #ifndef long64 #define long64 int64_t #endif #ifndef ufc_long #define ufc_long unsigned #endif #ifndef _UFC_64_ #define _UFC_32_ #endif /* * Permutation done once on the 56 bit * key derived from the original 8 byte ASCII key. */ static int pc1[56] = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 }; /* * How much to rotate each 28 bit half of the pc1 permutated * 56 bit key before using pc2 to give the i' key */ static int rots[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; /* * Permutation giving the key * of the i' DES round */ static int pc2[48] = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 }; /* * The E expansion table which selects * bits from the 32 bit intermediate result. */ static int esel[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 }; static int e_inverse[64]; /* * Permutation done on the * result of sbox lookups */ static int perm32[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; /* * The sboxes */ static int sbox[8][4][16]= { { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } }, { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } }, { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } }, { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } }, { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } }, { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } }, { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } }, { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } } }; /* * This is the final * permutation matrix */ static int final_perm[64] = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 }; /* * The 16 DES keys in BITMASK format */ #ifdef _UFC_32_ long32 _ufc_keytab[16][2]; #endif #ifdef _UFC_64_ long64 _ufc_keytab[16]; #endif #define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') /* Macro to set a bit (0..23) */ #define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) ) /* * sb arrays: * * Workhorses of the inner loop of the DES implementation. * They do sbox lookup, shifting of this value, 32 bit * permutation and E permutation for the next round. * * Kept in 'BITMASK' format. */ #ifdef _UFC_32_ long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192]; static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; #endif #ifdef _UFC_64_ long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096]; static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; #endif /* * eperm32tab: do 32 bit permutation and E selection * * The first index is the byte number in the 32 bit value to be permuted * - second - is the value of this byte * - third - selects the two 32 bit values * * The table is used and generated internally in init_des to speed it up */ static ufc_long eperm32tab[4][256][2]; /* * do_pc1: permform pc1 permutation in the key schedule generation. * * The first index is the byte number in the 8 byte ASCII key * - second - - the two 28 bits halfs of the result * - third - selects the 7 bits actually used of each byte * * The result is kept with 28 bit per 32 bit with the 4 most significant * bits zero. */ static ufc_long do_pc1[8][2][128]; /* * do_pc2: permform pc2 permutation in the key schedule generation. * * The first index is the septet number in the two 28 bit intermediate values * - second - - - septet values * * Knowledge of the structure of the pc2 permutation is used. * * The result is kept with 28 bit per 32 bit with the 4 most significant * bits zero. */ static ufc_long do_pc2[8][128]; /* * efp: undo an extra e selection and do final * permutation giving the DES result. * * Invoked 6 bit a time on two 48 bit values * giving two 32 bit longs. */ static ufc_long efp[16][64][2]; static unsigned char bytemask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; static ufc_long longmask[32] = { 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; /* * Silly rewrite of 'bzero'. I do so * because some machines don't have * bzero and some don't have memset. */ static void clearmem(char *start, int cnt) { while(cnt--) *start++ = '\0'; } static int initialized = 0; /* lookup a 6 bit value in sbox */ #define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf]; /* * Initialize unit - may be invoked directly * by fcrypt users. */ static void ufc_init_des(void) { int comes_from_bit; int bit, sg; ufc_long j; ufc_long mask1, mask2; /* * Create the do_pc1 table used * to affect pc1 permutation * when generating keys */ for(bit = 0; bit < 56; bit++) { comes_from_bit = pc1[bit] - 1; mask1 = bytemask[comes_from_bit % 8 + 1]; mask2 = longmask[bit % 28 + 4]; for(j = 0; j < 128; j++) { if(j & mask1) do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2; } } /* * Create the do_pc2 table used * to affect pc2 permutation when * generating keys */ for(bit = 0; bit < 48; bit++) { comes_from_bit = pc2[bit] - 1; mask1 = bytemask[comes_from_bit % 7 + 1]; mask2 = BITMASK(bit % 24); for(j = 0; j < 128; j++) { if(j & mask1) do_pc2[comes_from_bit / 7][j] |= mask2; } } /* * Now generate the table used to do combined * 32 bit permutation and e expansion * * We use it because we have to permute 16384 32 bit * longs into 48 bit in order to initialize sb. * * Looping 48 rounds per permutation becomes * just too slow... * */ clearmem((char*)eperm32tab, sizeof(eperm32tab)); for(bit = 0; bit < 48; bit++) { ufc_long inner_mask1,comes_from; comes_from = perm32[esel[bit]-1]-1; inner_mask1 = bytemask[comes_from % 8]; for(j = 256; j--;) { if(j & inner_mask1) eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24); } } /* * Create the sb tables: * * For each 12 bit segment of an 48 bit intermediate * result, the sb table precomputes the two 4 bit * values of the sbox lookups done with the two 6 * bit halves, shifts them to their proper place, * sends them through perm32 and finally E expands * them so that they are ready for the next * DES round. * */ for(sg = 0; sg < 4; sg++) { int j1, j2; int s1, s2; for(j1 = 0; j1 < 64; j1++) { s1 = s_lookup(2 * sg, j1); for(j2 = 0; j2 < 64; j2++) { ufc_long to_permute, inx; s2 = s_lookup(2 * sg + 1, j2); to_permute = ((s1 << 4) | s2) << (24 - 8 * sg); #ifdef _UFC_32_ inx = ((j1 << 6) | j2) << 1; sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0]; sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1]; sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0]; sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1]; sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0]; sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1]; sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0]; sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1]; #endif #ifdef _UFC_64_ inx = ((j1 << 6) | j2); sb[sg][inx] = ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) | (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1]; sb[sg][inx] |= ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) | (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1]; sb[sg][inx] |= ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) | (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1]; sb[sg][inx] |= ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) | (long64)eperm32tab[3][(to_permute) & 0xff][1]; #endif } } } /* * Create an inverse matrix for esel telling * where to plug out bits if undoing it */ for(bit=48; bit--;) { e_inverse[esel[bit] - 1 ] = bit; e_inverse[esel[bit] - 1 + 32] = bit + 48; } /* * create efp: the matrix used to * undo the E expansion and effect final permutation */ clearmem((char*)efp, sizeof efp); for(bit = 0; bit < 64; bit++) { int o_bit, o_long; ufc_long word_value, inner_mask1, inner_mask2; int comes_from_f_bit, comes_from_e_bit; int comes_from_word, bit_within_word; /* See where bit i belongs in the two 32 bit long's */ o_long = bit / 32; /* 0..1 */ o_bit = bit % 32; /* 0..31 */ /* * And find a bit in the e permutated value setting this bit. * * Note: the e selection may have selected the same bit several * times. By the initialization of e_inverse, we only look * for one specific instance. */ comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */ comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */ comes_from_word = comes_from_e_bit / 6; /* 0..15 */ bit_within_word = comes_from_e_bit % 6; /* 0..5 */ inner_mask1 = longmask[bit_within_word + 26]; inner_mask2 = longmask[o_bit]; for(word_value = 64; word_value--;) { if(word_value & inner_mask1) efp[comes_from_word][word_value][o_long] |= inner_mask2; } } initialized++; } /* * Process the elements of the sb table permuting the * bits swapped in the expansion by the current salt. */ #ifdef _UFC_32_ static void shuffle_sb(long32 *k, ufc_long saltbits) { ufc_long j; long32 x; for(j=4096; j--;) { x = (k[0] ^ k[1]) & (long32)saltbits; *k++ ^= x; *k++ ^= x; } } #endif #ifdef _UFC_64_ static void shuffle_sb(long64 *k, ufc_long saltbits) { ufc_long j; long64 x; for(j=4096; j--;) { x = ((*k >> 32) ^ *k) & (long64)saltbits; *k++ ^= (x << 32) | x; } } #endif /* * Setup the unit for a new salt * Hopefully we'll not see a new salt in each crypt call. */ static unsigned char current_salt[3] = "&&"; /* invalid value */ static ufc_long current_saltbits = 0; static int direction = 0; static void setup_salt(const char *s1) { ufc_long i, j, saltbits; const unsigned char *s2 = (const unsigned char *)s1; if(!initialized) ufc_init_des(); if(s2[0] == current_salt[0] && s2[1] == current_salt[1]) return; current_salt[0] = s2[0]; current_salt[1] = s2[1]; /* * This is the only crypt change to DES: * entries are swapped in the expansion table * according to the bits set in the salt. */ saltbits = 0; for(i = 0; i < 2; i++) { long c=ascii_to_bin(s2[i]); if(c < 0 || c > 63) c = 0; for(j = 0; j < 6; j++) { if((c >> j) & 0x1) saltbits |= BITMASK(6 * i + j); } } /* * Permute the sb table values * to reflect the changed e * selection table */ shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits); shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits); shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits); shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits); current_saltbits = saltbits; } static void ufc_mk_keytab(char *key) { ufc_long v1, v2, *k1; int i; #ifdef _UFC_32_ long32 v, *k2 = &_ufc_keytab[0][0]; #endif #ifdef _UFC_64_ long64 v, *k2 = &_ufc_keytab[0]; #endif v1 = v2 = 0; k1 = &do_pc1[0][0][0]; for(i = 8; i--;) { v1 |= k1[*key & 0x7f]; k1 += 128; v2 |= k1[*key++ & 0x7f]; k1 += 128; } for(i = 0; i < 16; i++) { k1 = &do_pc2[0][0]; v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i])); v = k1[(v1 >> 21) & 0x7f]; k1 += 128; v |= k1[(v1 >> 14) & 0x7f]; k1 += 128; v |= k1[(v1 >> 7) & 0x7f]; k1 += 128; v |= k1[(v1 ) & 0x7f]; k1 += 128; #ifdef _UFC_32_ *k2++ = v; v = 0; #endif #ifdef _UFC_64_ v <<= 32; #endif v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i])); v |= k1[(v2 >> 21) & 0x7f]; k1 += 128; v |= k1[(v2 >> 14) & 0x7f]; k1 += 128; v |= k1[(v2 >> 7) & 0x7f]; k1 += 128; v |= k1[(v2 ) & 0x7f]; *k2++ = v; } direction = 0; } /* * Undo an extra E selection and do final permutations */ ufc_long *_ufc_dofinalperm(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2) { ufc_long v1, v2, x; static ufc_long ary[2]; x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x; x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x; v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3; v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1]; v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1]; v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1]; v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1]; v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1]; v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1]; v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1]; v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1]; v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1]; v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1]; v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1]; v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1]; v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1]; v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1]; v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1]; v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1]; ary[0] = v1; ary[1] = v2; return ary; } /* * crypt only: convert from 64 bit to 11 bit ASCII * prefixing with the salt */ static char *output_conversion(ufc_long v1, ufc_long v2, const char *salt) { static char outbuf[14]; int i, s; outbuf[0] = salt[0]; outbuf[1] = salt[1] ? salt[1] : salt[0]; for(i = 0; i < 5; i++) outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f); s = (v2 & 0xf) << 2; v2 = (v2 >> 2) | ((v1 & 0x3) << 30); for(i = 5; i < 10; i++) outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f); outbuf[12] = bin_to_ascii(s); outbuf[13] = 0; return outbuf; } /* * UNIX crypt function */ static ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long); char *ufc_crypt(const char *key,const char *salt) { ufc_long *s; char ktab[9]; /* * Hack DES tables according to salt */ setup_salt(salt); /* * Setup key schedule */ clearmem(ktab, sizeof ktab); strncpy(ktab, key, 8); ufc_mk_keytab(ktab); /* * Go for the 25 DES encryptions */ s = _ufc_doit((ufc_long)0, (ufc_long)0, (ufc_long)0, (ufc_long)0, (ufc_long)25); /* * And convert back to 6 bit ASCII */ return output_conversion(s[0], s[1], salt); } #ifdef _UFC_32_ /* * 32 bit version */ extern long32 _ufc_keytab[16][2]; extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; #define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) { int i; long32 s, *k; while(itr--) { k = &_ufc_keytab[0][0]; for(i=8; i--; ) { s = *k++ ^ r1; l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4); s = *k++ ^ r2; l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4); s = *k++ ^ l1; r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4); s = *k++ ^ l2; r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4); } s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s; } return _ufc_dofinalperm(l1, l2, r1, r2); } #endif #ifdef _UFC_64_ /* * 64 bit version */ extern long64 _ufc_keytab[16]; extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; #define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) { int i; long64 l, r, s, *k; l = (((long64)l1) << 32) | ((long64)l2); r = (((long64)r1) << 32) | ((long64)r2); while(itr--) { k = &_ufc_keytab[0]; for(i=8; i--; ) { s = *k++ ^ r; l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); s = *k++ ^ l; r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); } s=l; l=r; r=s; } l1 = l >> 32; l2 = l & 0xffffffff; r1 = r >> 32; r2 = r & 0xffffffff; return _ufc_dofinalperm(l1, l2, r1, r2); } #endif #else int ufc_dummy_procedure(void); int ufc_dummy_procedure(void) {return 0;} #endif ldb-2.0.8/lib/replace/cwrap.c0000660000000000000000000000226212406075657015675 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * * Replaceable functions by cwrap * * Copyright (c) 2014 Andreas Schneider * * ** NOTE! The following LGPL license applies to the replace * ** 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 . */ #include "replace.h" bool nss_wrapper_enabled(void) { return false; } bool nss_wrapper_hosts_enabled(void) { return false; } bool socket_wrapper_enabled(void) { return false; } bool uid_wrapper_enabled(void) { return false; } ldb-2.0.8/lib/replace/dlfcn.c0000660000000000000000000000354312406075657015652 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Samba system utilities Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jeremy Allison 1998-2002 Copyright (C) Jelmer Vernooij 2006 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #include "replace.h" #ifdef HAVE_DL_H #include #endif #ifndef HAVE_DLOPEN #ifdef DLOPEN_TAKES_UNSIGNED_FLAGS void *rep_dlopen(const char *name, unsigned int flags) #else void *rep_dlopen(const char *name, int flags) #endif { #ifdef HAVE_SHL_LOAD if (name == NULL) return PROG_HANDLE; return (void *)shl_load(name, flags, 0); #else return NULL; #endif } #endif #ifndef HAVE_DLSYM void *rep_dlsym(void *handle, const char *symbol) { #ifdef HAVE_SHL_FINDSYM void *sym_addr; if (!shl_findsym((shl_t *)&handle, symbol, TYPE_UNDEFINED, &sym_addr)) return sym_addr; #endif return NULL; } #endif #ifndef HAVE_DLERROR char *rep_dlerror(void) { return "dynamic loading of objects not supported on this platform"; } #endif #ifndef HAVE_DLCLOSE int rep_dlclose(void *handle) { #ifdef HAVE_SHL_CLOSE return shl_unload((shl_t)handle); #else return 0; #endif } #endif ldb-2.0.8/lib/replace/getaddrinfo.c0000660000000000000000000002454412406075657017056 0ustar rootroot00000000000000/* PostgreSQL Database Management System (formerly known as Postgres, then as Postgres95) Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of California Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ /*------------------------------------------------------------------------- * * getaddrinfo.c * Support getaddrinfo() on platforms that don't have it. * * We also supply getnameinfo() here, assuming that the platform will have * it if and only if it has getaddrinfo(). If this proves false on some * platform, we'll need to split this file and provide a separate configure * test for getnameinfo(). * * Copyright (c) 2003-2007, PostgreSQL Global Development Group * * Copyright (C) 2007 Jeremy Allison. * Modified to return multiple IPv4 addresses for Samba. * *------------------------------------------------------------------------- */ #include "replace.h" #include "system/network.h" #ifndef SMB_MALLOC #define SMB_MALLOC(s) malloc(s) #endif #ifndef SMB_STRDUP #define SMB_STRDUP(s) strdup(s) #endif static int check_hostent_err(struct hostent *hp) { if (!hp) { switch (h_errno) { case HOST_NOT_FOUND: case NO_DATA: return EAI_NONAME; case TRY_AGAIN: return EAI_AGAIN; case NO_RECOVERY: default: return EAI_FAIL; } } if (!hp->h_name || hp->h_addrtype != AF_INET) { return EAI_FAIL; } return 0; } static char *canon_name_from_hostent(struct hostent *hp, int *perr) { char *ret = NULL; *perr = check_hostent_err(hp); if (*perr) { return NULL; } ret = SMB_STRDUP(hp->h_name); if (!ret) { *perr = EAI_MEMORY; } return ret; } static char *get_my_canon_name(int *perr) { char name[HOST_NAME_MAX+1]; if (gethostname(name, HOST_NAME_MAX) == -1) { *perr = EAI_FAIL; return NULL; } /* Ensure null termination. */ name[HOST_NAME_MAX] = '\0'; return canon_name_from_hostent(gethostbyname(name), perr); } static char *get_canon_name_from_addr(struct in_addr ip, int *perr) { return canon_name_from_hostent( gethostbyaddr(&ip, sizeof(ip), AF_INET), perr); } static struct addrinfo *alloc_entry(const struct addrinfo *hints, struct in_addr ip, unsigned short port) { struct sockaddr_in *psin = NULL; struct addrinfo *ai = SMB_MALLOC(sizeof(*ai)); if (!ai) { return NULL; } memset(ai, '\0', sizeof(*ai)); psin = SMB_MALLOC(sizeof(*psin)); if (!psin) { free(ai); return NULL; } memset(psin, '\0', sizeof(*psin)); psin->sin_family = AF_INET; psin->sin_port = htons(port); psin->sin_addr = ip; ai->ai_flags = 0; ai->ai_family = AF_INET; ai->ai_socktype = hints->ai_socktype; ai->ai_protocol = hints->ai_protocol; ai->ai_addrlen = sizeof(*psin); ai->ai_addr = (struct sockaddr *) psin; ai->ai_canonname = NULL; ai->ai_next = NULL; return ai; } /* * get address info for a single ipv4 address. * * Bugs: - servname can only be a number, not text. */ static int getaddr_info_single_addr(const char *service, uint32_t addr, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo *ai = NULL; struct in_addr ip; unsigned short port = 0; if (service) { port = (unsigned short)atoi(service); } ip.s_addr = htonl(addr); ai = alloc_entry(hints, ip, port); if (!ai) { return EAI_MEMORY; } /* If we're asked for the canonical name, * make sure it returns correctly. */ if (!(hints->ai_flags & AI_NUMERICSERV) && hints->ai_flags & AI_CANONNAME) { int err; if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) { ai->ai_canonname = get_my_canon_name(&err); } else { ai->ai_canonname = get_canon_name_from_addr(ip,&err); } if (ai->ai_canonname == NULL) { freeaddrinfo(ai); return err; } } *res = ai; return 0; } /* * get address info for multiple ipv4 addresses. * * Bugs: - servname can only be a number, not text. */ static int getaddr_info_name(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo *listp = NULL, *prevp = NULL; char **pptr = NULL; int err; struct hostent *hp = NULL; unsigned short port = 0; if (service) { port = (unsigned short)atoi(service); } hp = gethostbyname(node); err = check_hostent_err(hp); if (err) { return err; } for(pptr = hp->h_addr_list; *pptr; pptr++) { struct in_addr ip = *(struct in_addr *)*pptr; struct addrinfo *ai = alloc_entry(hints, ip, port); if (!ai) { freeaddrinfo(listp); return EAI_MEMORY; } if (!listp) { listp = ai; prevp = ai; ai->ai_canonname = SMB_STRDUP(hp->h_name); if (!ai->ai_canonname) { freeaddrinfo(listp); return EAI_MEMORY; } } else { prevp->ai_next = ai; prevp = ai; } } *res = listp; return 0; } /* * get address info for ipv4 sockets. * * Bugs: - servname can only be a number, not text. */ int rep_getaddrinfo(const char *node, const char *service, const struct addrinfo * hintp, struct addrinfo ** res) { struct addrinfo hints; /* Setup the hints struct. */ if (hintp == NULL) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; } else { memcpy(&hints, hintp, sizeof(hints)); } if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) { return EAI_FAMILY; } if (hints.ai_socktype == 0) { hints.ai_socktype = SOCK_STREAM; } if (!node && !service) { return EAI_NONAME; } if (node) { if (node[0] == '\0') { return getaddr_info_single_addr(service, INADDR_ANY, &hints, res); } else if (hints.ai_flags & AI_NUMERICHOST) { struct in_addr ip; if (!inet_aton(node, &ip)) { return EAI_FAIL; } return getaddr_info_single_addr(service, ntohl(ip.s_addr), &hints, res); } else { return getaddr_info_name(node, service, &hints, res); } } else if (hints.ai_flags & AI_PASSIVE) { return getaddr_info_single_addr(service, INADDR_ANY, &hints, res); } return getaddr_info_single_addr(service, INADDR_LOOPBACK, &hints, res); } void rep_freeaddrinfo(struct addrinfo *res) { struct addrinfo *next = NULL; for (;res; res = next) { next = res->ai_next; free(res->ai_canonname); free(res->ai_addr); free(res); } } const char *rep_gai_strerror(int errcode) { #ifdef HAVE_HSTRERROR int hcode; switch (errcode) { case EAI_NONAME: hcode = HOST_NOT_FOUND; break; case EAI_AGAIN: hcode = TRY_AGAIN; break; case EAI_FAIL: default: hcode = NO_RECOVERY; break; } return hstrerror(hcode); #else /* !HAVE_HSTRERROR */ switch (errcode) { case EAI_NONAME: return "Unknown host"; case EAI_AGAIN: return "Host name lookup failure"; #ifdef EAI_BADFLAGS case EAI_BADFLAGS: return "Invalid argument"; #endif #ifdef EAI_FAMILY case EAI_FAMILY: return "Address family not supported"; #endif #ifdef EAI_MEMORY case EAI_MEMORY: return "Not enough memory"; #endif #ifdef EAI_NODATA case EAI_NODATA: return "No host data of that type was found"; #endif #ifdef EAI_SERVICE case EAI_SERVICE: return "Class type not found"; #endif #ifdef EAI_SOCKTYPE case EAI_SOCKTYPE: return "Socket type not supported"; #endif default: return "Unknown server error"; } #endif /* HAVE_HSTRERROR */ } static int gethostnameinfo(const struct sockaddr *sa, char *node, size_t nodelen, int flags) { int ret = -1; char *p = NULL; if (!(flags & NI_NUMERICHOST)) { struct hostent *hp = gethostbyaddr( &((struct sockaddr_in *)sa)->sin_addr, sizeof(struct in_addr), sa->sa_family); ret = check_hostent_err(hp); if (ret == 0) { /* Name looked up successfully. */ ret = snprintf(node, nodelen, "%s", hp->h_name); if (ret < 0 || (size_t)ret >= nodelen) { return EAI_MEMORY; } if (flags & NI_NOFQDN) { p = strchr(node,'.'); if (p) { *p = '\0'; } } return 0; } if (flags & NI_NAMEREQD) { /* If we require a name and didn't get one, * automatically fail. */ return ret; } /* Otherwise just fall into the numeric host code... */ } p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); ret = snprintf(node, nodelen, "%s", p); if (ret < 0 || (size_t)ret >= nodelen) { return EAI_MEMORY; } return 0; } static int getservicenameinfo(const struct sockaddr *sa, char *service, size_t servicelen, int flags) { int ret = -1; int port = ntohs(((struct sockaddr_in *)sa)->sin_port); if (!(flags & NI_NUMERICSERV)) { struct servent *se = getservbyport( port, (flags & NI_DGRAM) ? "udp" : "tcp"); if (se && se->s_name) { /* Service name looked up successfully. */ ret = snprintf(service, servicelen, "%s", se->s_name); if (ret < 0 || (size_t)ret >= servicelen) { return EAI_MEMORY; } return 0; } /* Otherwise just fall into the numeric service code... */ } ret = snprintf(service, servicelen, "%d", port); if (ret < 0 || (size_t)ret >= servicelen) { return EAI_MEMORY; } return 0; } /* * Convert an ipv4 address to a hostname. * * Bugs: - No IPv6 support. */ int rep_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, size_t nodelen, char *service, size_t servicelen, int flags) { /* Invalid arguments. */ if (sa == NULL || (node == NULL && service == NULL)) { return EAI_FAIL; } if (sa->sa_family != AF_INET) { return EAI_FAIL; } if (salen < sizeof(struct sockaddr_in)) { return EAI_FAIL; } if (node) { return gethostnameinfo(sa, node, nodelen, flags); } if (service) { return getservicenameinfo(sa, service, servicelen, flags); } return 0; } ldb-2.0.8/lib/replace/getaddrinfo.h0000660000000000000000000000614112406075657017054 0ustar rootroot00000000000000/* PostgreSQL Database Management System (formerly known as Postgres, then as Postgres95) Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of California Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ /*------------------------------------------------------------------------- * * getaddrinfo.h * Support getaddrinfo() on platforms that don't have it. * * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, * whether or not the library routine getaddrinfo() can be found. This * policy is needed because on some platforms a manually installed libbind.a * may provide getaddrinfo(), yet the system headers may not provide the * struct definitions needed to call it. To avoid conflict with the libbind * definition in such cases, we rename our routines to pg_xxx() via macros. * in lib/replace we use rep_xxx() * This code will also work on platforms where struct addrinfo is defined * in the system headers but no getaddrinfo() can be located. * * Copyright (c) 2003-2007, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ #ifndef GETADDRINFO_H #define GETADDRINFO_H #ifndef HAVE_GETADDRINFO /* Rename private copies per comments above */ #ifdef getaddrinfo #undef getaddrinfo #endif #define getaddrinfo rep_getaddrinfo #define HAVE_GETADDRINFO #ifdef freeaddrinfo #undef freeaddrinfo #endif #define freeaddrinfo rep_freeaddrinfo #define HAVE_FREEADDRINFO #ifdef gai_strerror #undef gai_strerror #endif #define gai_strerror rep_gai_strerror #define HAVE_GAI_STRERROR #ifdef getnameinfo #undef getnameinfo #endif #define getnameinfo rep_getnameinfo #ifndef HAVE_GETNAMEINFO #define HAVE_GETNAMEINFO #endif extern int rep_getaddrinfo(const char *node, const char *service, const struct addrinfo * hints, struct addrinfo ** res); extern void rep_freeaddrinfo(struct addrinfo * res); extern const char *rep_gai_strerror(int errcode); extern int rep_getnameinfo(const struct sockaddr * sa, socklen_t salen, char *node, size_t nodelen, char *service, size_t servicelen, int flags); #endif /* HAVE_GETADDRINFO */ #endif /* GETADDRINFO_H */ ldb-2.0.8/lib/replace/getifaddrs.c0000660000000000000000000002046013573675413016677 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Andrew Tridgell 1998 Copyright (C) Jeremy Allison 2007 Copyright (C) Jelmer Vernooij 2007 ** NOTE! The following LGPL license applies to the replace ** 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 Library 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 . */ #include "replace.h" #include "system/network.h" #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #ifndef SIOCGIFCONF #ifdef HAVE_SYS_SOCKIO_H #include #endif #endif #ifdef HAVE_IFACE_GETIFADDRS #define _FOUND_IFACE_ANY #else void rep_freeifaddrs(struct ifaddrs *ifp) { if (ifp != NULL) { free(ifp->ifa_name); free(ifp->ifa_addr); free(ifp->ifa_netmask); free(ifp->ifa_dstaddr); freeifaddrs(ifp->ifa_next); free(ifp); } } static struct sockaddr *sockaddr_dup(struct sockaddr *sa) { struct sockaddr *ret; socklen_t socklen; #ifdef HAVE_SOCKADDR_SA_LEN socklen = sa->sa_len; #else socklen = sizeof(struct sockaddr_storage); #endif ret = calloc(1, socklen); if (ret == NULL) return NULL; memcpy(ret, sa, socklen); return ret; } #endif #ifdef HAVE_IFACE_IFCONF /* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. It probably also works on any BSD style system. */ int rep_getifaddrs(struct ifaddrs **ifap) { struct ifconf ifc; char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; *ifap = NULL; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { return -1; } ifc.ifc_len = sizeof(buff); ifc.ifc_buf = buff; if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { close(fd); return -1; } ifr = ifc.ifc_req; n = ifc.ifc_len / sizeof(struct ifreq); /* Loop through interfaces, looking for given IP address */ for (i=n-1; i>=0; i--) { if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) == -1) { freeifaddrs(*ifap); close(fd); return -1; } curif = calloc(1, sizeof(struct ifaddrs)); if (curif == NULL) { freeifaddrs(*ifap); close(fd); return -1; } curif->ifa_name = strdup(ifr[i].ifr_name); if (curif->ifa_name == NULL) { free(curif); freeifaddrs(*ifap); close(fd); return -1; } curif->ifa_flags = ifr[i].ifr_flags; curif->ifa_dstaddr = NULL; curif->ifa_data = NULL; curif->ifa_next = NULL; curif->ifa_addr = NULL; if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != -1) { curif->ifa_addr = sockaddr_dup(&ifr[i].ifr_addr); if (curif->ifa_addr == NULL) { free(curif->ifa_name); free(curif); freeifaddrs(*ifap); close(fd); return -1; } } curif->ifa_netmask = NULL; if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != -1) { curif->ifa_netmask = sockaddr_dup(&ifr[i].ifr_addr); if (curif->ifa_netmask == NULL) { if (curif->ifa_addr != NULL) { free(curif->ifa_addr); } free(curif->ifa_name); free(curif); freeifaddrs(*ifap); close(fd); return -1; } } if (lastif == NULL) { *ifap = curif; } else { lastif->ifa_next = curif; } lastif = curif; } close(fd); return 0; } #define _FOUND_IFACE_ANY #endif /* HAVE_IFACE_IFCONF */ #ifdef HAVE_IFACE_IFREQ #ifndef I_STR #include #endif /**************************************************************************** this should cover most of the streams based systems Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code ****************************************************************************/ int rep_getifaddrs(struct ifaddrs **ifap) { struct ifreq ifreq; struct strioctl strioctl; char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; *ifap = NULL; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { return -1; } strioctl.ic_cmd = SIOCGIFCONF; strioctl.ic_dp = buff; strioctl.ic_len = sizeof(buff); if (ioctl(fd, I_STR, &strioctl) < 0) { close(fd); return -1; } /* we can ignore the possible sizeof(int) here as the resulting number of interface structures won't change */ n = strioctl.ic_len / sizeof(struct ifreq); /* we will assume that the kernel returns the length as an int at the start of the buffer if the offered size is a multiple of the structure size plus an int */ if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { ifr = (struct ifreq *)(buff + sizeof(int)); } else { ifr = (struct ifreq *)buff; } /* Loop through interfaces */ for (i = 0; iifa_next = curif; } strioctl.ic_cmd = SIOCGIFFLAGS; strioctl.ic_dp = (char *)&ifreq; strioctl.ic_len = sizeof(struct ifreq); if (ioctl(fd, I_STR, &strioctl) != 0) { freeifaddrs(*ifap); return -1; } curif->ifa_flags = ifreq.ifr_flags; strioctl.ic_cmd = SIOCGIFADDR; strioctl.ic_dp = (char *)&ifreq; strioctl.ic_len = sizeof(struct ifreq); if (ioctl(fd, I_STR, &strioctl) != 0) { freeifaddrs(*ifap); return -1; } curif->ifa_name = strdup(ifreq.ifr_name); curif->ifa_addr = sockaddr_dup(&ifreq.ifr_addr); curif->ifa_dstaddr = NULL; curif->ifa_data = NULL; curif->ifa_next = NULL; curif->ifa_netmask = NULL; strioctl.ic_cmd = SIOCGIFNETMASK; strioctl.ic_dp = (char *)&ifreq; strioctl.ic_len = sizeof(struct ifreq); if (ioctl(fd, I_STR, &strioctl) != 0) { freeifaddrs(*ifap); return -1; } curif->ifa_netmask = sockaddr_dup(&ifreq.ifr_addr); lastif = curif; } close(fd); return 0; } #define _FOUND_IFACE_ANY #endif /* HAVE_IFACE_IFREQ */ #ifdef HAVE_IFACE_AIX /**************************************************************************** this one is for AIX (tested on 4.2) ****************************************************************************/ int rep_getifaddrs(struct ifaddrs **ifap) { char buff[8192]; int fd, i; struct ifconf ifc; struct ifreq *ifr=NULL; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; *ifap = NULL; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { return -1; } ifc.ifc_len = sizeof(buff); ifc.ifc_buf = buff; if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { close(fd); return -1; } ifr = ifc.ifc_req; /* Loop through interfaces */ i = ifc.ifc_len; while (i > 0) { unsigned int inc; inc = ifr->ifr_addr.sa_len; if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { freeaddrinfo(*ifap); return -1; } curif = calloc(1, sizeof(struct ifaddrs)); if (lastif == NULL) { *ifap = curif; } else { lastif->ifa_next = curif; } curif->ifa_name = strdup(ifr->ifr_name); curif->ifa_addr = sockaddr_dup(&ifr->ifr_addr); curif->ifa_dstaddr = NULL; curif->ifa_data = NULL; curif->ifa_netmask = NULL; curif->ifa_next = NULL; if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { freeaddrinfo(*ifap); return -1; } curif->ifa_flags = ifr->ifr_flags; if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { freeaddrinfo(*ifap); return -1; } curif->ifa_netmask = sockaddr_dup(&ifr->ifr_addr); lastif = curif; next: /* * Patch from Archie Cobbs (archie@whistle.com). The * addresses in the SIOCGIFCONF interface list have a * minimum size. Usually this doesn't matter, but if * your machine has tunnel interfaces, etc. that have * a zero length "link address", this does matter. */ if (inc < sizeof(ifr->ifr_addr)) inc = sizeof(ifr->ifr_addr); inc += IFNAMSIZ; ifr = (struct ifreq*) (((char*) ifr) + inc); i -= inc; } close(fd); return 0; } #define _FOUND_IFACE_ANY #endif /* HAVE_IFACE_AIX */ #ifndef _FOUND_IFACE_ANY int rep_getifaddrs(struct ifaddrs **ifap) { errno = ENOSYS; return -1; } #endif ldb-2.0.8/lib/replace/hdr_replace.h0000660000000000000000000000012412406075657017031 0ustar rootroot00000000000000/* this is a replacement header for a missing system header */ #include "replace.h" ldb-2.0.8/lib/replace/inet_aton.c0000660000000000000000000000223212406075657016536 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * replacement functions * Copyright (C) Michael Adam 2008 * * ** NOTE! The following LGPL license applies to the replace * ** 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 . */ #include "replace.h" #include "system/network.h" /** * We know that we have inet_pton from earlier libreplace checks. */ int rep_inet_aton(const char *src, struct in_addr *dst) { return (inet_pton(AF_INET, src, dst) > 0) ? 1 : 0; } ldb-2.0.8/lib/replace/inet_ntoa.c0000660000000000000000000000247512406075657016547 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * replacement routines for broken systems * Copyright (C) Andrew Tridgell 2003 * Copyright (C) Michael Adam 2008 * * ** NOTE! The following LGPL license applies to the replace * ** 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 . */ #include "replace.h" #include "system/network.h" /** * NOTE: this is not thread safe, but it can't be, either * since it returns a pointer to static memory. */ char *rep_inet_ntoa(struct in_addr ip) { uint8_t *p = (uint8_t *)&ip.s_addr; static char buf[18]; slprintf(buf, 17, "%d.%d.%d.%d", (int)p[0], (int)p[1], (int)p[2], (int)p[3]); return buf; } ldb-2.0.8/lib/replace/inet_ntop.c0000660000000000000000000001163212406075657016561 0ustar rootroot00000000000000/* * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "replace.h" #include "system/network.h" #define NS_INT16SZ 2 #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const unsigned char *src, char *dst, socklen_t size); #ifdef AF_INET6 static const char *inet_ntop6(const unsigned char *src, char *dst, socklen_t size); #endif /* char * * isc_net_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * author: * Paul Vixie, 1996. */ const char * rep_inet_ntop(int af, const void *src, char *dst, socklen_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); #ifdef AF_INET6 case AF_INET6: return (inet_ntop6(src, dst, size)); #endif default: errno = EAFNOSUPPORT; return (NULL); } /* NOTREACHED */ } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a unsigned char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const unsigned char *src, char *dst, socklen_t size) { static const char *fmt = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; size_t len; len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); if (len >= size) { errno = ENOSPC; return (NULL); } memcpy(dst, tmp, len + 1); return (dst); } /* const char * * isc_inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ #ifdef AF_INET6 static const char * inet_ntop6(const unsigned char *src, char *dst, socklen_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; struct { int base, len; } best, cur; unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i, inc; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; best.len = 0; cur.base = -1; cur.len = 0; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) return (NULL); tp += strlen(tp); break; } inc = snprintf(tp, 5, "%x", words[i]); if (inc >= 5) { abort(); } tp += inc; } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } memcpy(dst, tmp, tp - tmp); return (dst); } #endif /* AF_INET6 */ ldb-2.0.8/lib/replace/inet_pton.c0000660000000000000000000001201012406075657016550 0ustar rootroot00000000000000/* * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "replace.h" #include "system/network.h" #define NS_INT16SZ 2 #define NS_INADDRSZ 4 #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4(const char *src, unsigned char *dst); #ifdef AF_INET6 static int inet_pton6(const char *src, unsigned char *dst); #endif /* int * inet_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * author: * Paul Vixie, 1996. */ int rep_inet_pton(int af, const char *src, void *dst) { switch (af) { case AF_INET: return (inet_pton4(src, dst)); #ifdef AF_INET6 case AF_INET6: return (inet_pton6(src, dst)); #endif default: errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ } /* int * inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int inet_pton4(src, dst) const char *src; unsigned char *dst; { static const char digits[] = "0123456789"; int saw_digit, octets, ch; unsigned char tmp[NS_INADDRSZ], *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr(digits, ch)) != NULL) { unsigned int new = *tp * 10 + (pch - digits); if (new > 255) return (0); *tp = new; if (! saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); *++tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); memcpy(dst, tmp, NS_INADDRSZ); return (1); } /* int * inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: * (1) does not touch `dst' unless it's returning 1. * (2) :: in a full address is silently ignored. * credit: * inspired by Mark Andrews. * author: * Paul Vixie, 1996. */ #ifdef AF_INET6 static int inet_pton6(src, dst) const char *src; unsigned char *dst; { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; unsigned int val; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; saw_xdigit = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (val > 0xffff) return (0); saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) return (0); colonp = tp; continue; } if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; saw_xdigit = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += NS_INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (saw_xdigit) { if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } #endif ldb-2.0.8/lib/replace/poll.c0000660000000000000000000000640512406075657015532 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. poll.c - poll wrapper This file is based on code from libssh (LGPLv2.1+ at the time it was downloaded), thus the following copyrights: Copyright (c) 2009-2010 by Andreas Schneider Copyright (c) 2003-2009 by Aris Adamantiadis Copyright (c) 2009 Aleksandar Kanchev Copyright (C) Volker Lendecke 2011 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #include "replace.h" #include "system/select.h" #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif int rep_poll(struct pollfd *fds, nfds_t nfds, int timeout) { fd_set rfds, wfds, efds; struct timeval tv, *ptv; int max_fd; int rc; nfds_t i; if ((fds == NULL) && (nfds != 0)) { errno = EFAULT; return -1; } FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); rc = 0; max_fd = 0; /* compute fd_sets and find largest descriptor */ for (i = 0; i < nfds; i++) { if ((fds[i].fd < 0) || (fds[i].fd >= FD_SETSIZE)) { fds[i].revents = POLLNVAL; continue; } if (fds[i].events & (POLLIN | POLLRDNORM)) { FD_SET(fds[i].fd, &rfds); } if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) { FD_SET(fds[i].fd, &wfds); } if (fds[i].events & (POLLPRI | POLLRDBAND)) { FD_SET(fds[i].fd, &efds); } if (fds[i].fd > max_fd && (fds[i].events & (POLLIN | POLLOUT | POLLPRI | POLLRDNORM | POLLRDBAND | POLLWRNORM | POLLWRBAND))) { max_fd = fds[i].fd; } } if (timeout < 0) { ptv = NULL; } else { ptv = &tv; if (timeout == 0) { tv.tv_sec = 0; tv.tv_usec = 0; } else { tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; } } rc = select(max_fd + 1, &rfds, &wfds, &efds, ptv); if (rc < 0) { return -1; } for (rc = 0, i = 0; i < nfds; i++) { if ((fds[i].fd < 0) || (fds[i].fd >= FD_SETSIZE)) { continue; } fds[i].revents = 0; if (FD_ISSET(fds[i].fd, &rfds)) { int err = errno; int available = 0; int ret; /* support for POLLHUP */ ret = ioctl(fds[i].fd, FIONREAD, &available); if ((ret == -1) || (available == 0)) { fds[i].revents |= POLLHUP; } else { fds[i].revents |= fds[i].events & (POLLIN | POLLRDNORM); } errno = err; } if (FD_ISSET(fds[i].fd, &wfds)) { fds[i].revents |= fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND); } if (FD_ISSET(fds[i].fd, &efds)) { fds[i].revents |= fds[i].events & (POLLPRI | POLLRDBAND); } if (fds[i].revents & ~POLLHUP) { rc++; } } return rc; } ldb-2.0.8/lib/replace/replace-test.h0000660000000000000000000000033712406075657017157 0ustar rootroot00000000000000#ifndef __LIB_REPLACE_REPLACE_TEST_H__ #define __LIB_REPLACE_REPLACE_TEST_H__ int libreplace_test_strptime(void); int test_readdir_os2_delete(void); int getifaddrs_test(void); #endif /* __LIB_REPLACE_REPLACE_TEST_H__ */ ldb-2.0.8/lib/replace/replace-testsuite.h0000660000000000000000000000036312406075657020230 0ustar rootroot00000000000000#ifndef __LIB_REPLACE_REPLACE_TESTSUITE_H__ #define __LIB_REPLACE_REPLACE_TESTSUITE_H__ #include struct torture_context; bool torture_local_replace(struct torture_context *ctx); #endif /* __LIB_REPLACE_REPLACE_TESTSUITE_H__ */ ldb-2.0.8/lib/replace/replace.c0000660000000000000000000005247513573675413016211 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. replacement routines for broken systems Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jelmer Vernooij 2005-2008 Copyright (C) Matthieu Patou 2010 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include "system/network.h" #include "system/passwd.h" #include "system/syslog.h" #include "system/locale.h" #include "system/wait.h" #ifdef _WIN32 #define mkdir(d,m) _mkdir(d) #endif void replace_dummy(void); void replace_dummy(void) {} #ifndef HAVE_FTRUNCATE /******************************************************************* ftruncate for operating systems that don't have it ********************************************************************/ int rep_ftruncate(int f, off_t l) { #ifdef HAVE_CHSIZE return chsize(f,l); #elif defined(F_FREESP) struct flock fl; fl.l_whence = 0; fl.l_len = 0; fl.l_start = l; fl.l_type = F_WRLCK; return fcntl(f, F_FREESP, &fl); #else #error "you must have a ftruncate function" #endif } #endif /* HAVE_FTRUNCATE */ #ifndef HAVE_STRLCPY /* * Like strncpy but does not 0 fill the buffer and always null * terminates. bufsize is the size of the destination buffer. * Returns the length of s. */ size_t rep_strlcpy(char *d, const char *s, size_t bufsize) { size_t len = strlen(s); size_t ret = len; if (bufsize <= 0) { return 0; } if (len >= bufsize) { len = bufsize - 1; } memcpy(d, s, len); d[len] = 0; return ret; } #endif #ifndef HAVE_STRLCAT /* like strncat but does not 0 fill the buffer and always null terminates. bufsize is the length of the buffer, which should be one more than the maximum resulting string length */ size_t rep_strlcat(char *d, const char *s, size_t bufsize) { size_t len1 = strnlen(d, bufsize); size_t len2 = strlen(s); size_t ret = len1 + len2; if (len1+len2 >= bufsize) { if (bufsize < (len1+1)) { return ret; } len2 = bufsize - (len1+1); } if (len2 > 0) { memcpy(d+len1, s, len2); d[len1+len2] = 0; } return ret; } #endif #ifndef HAVE_MKTIME /******************************************************************* a mktime() replacement for those who don't have it - contributed by C.A. Lademann Corrections by richard.kettlewell@kewill.com ********************************************************************/ #define MINUTE 60 #define HOUR 60*MINUTE #define DAY 24*HOUR #define YEAR 365*DAY time_t rep_mktime(struct tm *t) { struct tm *u; time_t epoch = 0; int n; int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, y, m, i; if(t->tm_year < 70) return((time_t)-1); n = t->tm_year + 1900 - 1; epoch = (t->tm_year - 70) * YEAR + ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY; y = t->tm_year + 1900; m = 0; for(i = 0; i < t->tm_mon; i++) { epoch += mon [m] * DAY; if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) epoch += DAY; if(++m > 11) { m = 0; y++; } } epoch += (t->tm_mday - 1) * DAY; epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; if((u = localtime(&epoch)) != NULL) { t->tm_sec = u->tm_sec; t->tm_min = u->tm_min; t->tm_hour = u->tm_hour; t->tm_mday = u->tm_mday; t->tm_mon = u->tm_mon; t->tm_year = u->tm_year; t->tm_wday = u->tm_wday; t->tm_yday = u->tm_yday; t->tm_isdst = u->tm_isdst; } return(epoch); } #endif /* !HAVE_MKTIME */ #ifndef HAVE_INITGROUPS /**************************************************************************** some systems don't have an initgroups call ****************************************************************************/ int rep_initgroups(char *name, gid_t id) { #ifndef HAVE_SETGROUPS /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ errno = ENOSYS; return -1; #else /* HAVE_SETGROUPS */ #include gid_t *grouplst = NULL; int max_gr = NGROUPS_MAX; int ret; int i,j; struct group *g; char *gr; if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) { errno = ENOMEM; return -1; } grouplst[0] = id; i = 1; while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) { if (g->gr_gid == id) continue; j = 0; gr = g->gr_mem[0]; while (gr && (*gr != (char)NULL)) { if (strcmp(name,gr) == 0) { grouplst[i] = g->gr_gid; i++; gr = (char *)NULL; break; } gr = g->gr_mem[++j]; } } endgrent(); ret = setgroups(i, grouplst); free(grouplst); return ret; #endif /* HAVE_SETGROUPS */ } #endif /* HAVE_INITGROUPS */ #ifndef HAVE_MEMMOVE /******************************************************************* safely copies memory, ensuring no overlap problems. this is only used if the machine does not have its own memmove(). this is not the fastest algorithm in town, but it will do for our needs. ********************************************************************/ void *rep_memmove(void *dest,const void *src,int size) { unsigned long d,s; int i; if (dest==src || !size) return(dest); d = (unsigned long)dest; s = (unsigned long)src; if ((d >= (s+size)) || (s >= (d+size))) { /* no overlap */ memcpy(dest,src,size); return(dest); } if (d < s) { /* we can forward copy */ if (s-d >= sizeof(int) && !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) { /* do it all as words */ int *idest = (int *)dest; int *isrc = (int *)src; size /= sizeof(int); for (i=0;i= sizeof(int) && !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) { /* do it all as words */ int *idest = (int *)dest; int *isrc = (int *)src; size /= sizeof(int); for (i=size-1;i>=0;i--) idest[i] = isrc[i]; } else { /* simplest */ char *cdest = (char *)dest; char *csrc = (char *)src; for (i=size-1;i>=0;i--) cdest[i] = csrc[i]; } } return(dest); } #endif /* HAVE_MEMMOVE */ #ifndef HAVE_STRDUP /**************************************************************************** duplicate a string ****************************************************************************/ char *rep_strdup(const char *s) { size_t len; char *ret; if (!s) return(NULL); len = strlen(s)+1; ret = (char *)malloc(len); if (!ret) return(NULL); memcpy(ret,s,len); return(ret); } #endif /* HAVE_STRDUP */ #ifndef HAVE_SETLINEBUF void rep_setlinebuf(FILE *stream) { setvbuf(stream, (char *)NULL, _IOLBF, 0); } #endif /* HAVE_SETLINEBUF */ #ifndef HAVE_VSYSLOG #ifdef HAVE_SYSLOG void rep_vsyslog (int facility_priority, const char *format, va_list arglist) { char *msg = NULL; vasprintf(&msg, format, arglist); if (!msg) return; syslog(facility_priority, "%s", msg); free(msg); } #endif /* HAVE_SYSLOG */ #endif /* HAVE_VSYSLOG */ #ifndef HAVE_STRNLEN /** Some platforms don't have strnlen **/ size_t rep_strnlen(const char *s, size_t max) { size_t len; for (len = 0; len < max; len++) { if (s[len] == '\0') { break; } } return len; } #endif #ifndef HAVE_STRNDUP /** Some platforms don't have strndup. **/ char *rep_strndup(const char *s, size_t n) { char *ret; n = strnlen(s, n); ret = malloc(n+1); if (!ret) return NULL; memcpy(ret, s, n); ret[n] = 0; return ret; } #endif #if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4) int rep_waitpid(pid_t pid,int *status,int options) { return wait4(pid, status, options, NULL); } #endif #ifndef HAVE_SETEUID int rep_seteuid(uid_t euid) { #ifdef HAVE_SETRESUID return setresuid(-1, euid, -1); #else errno = ENOSYS; return -1; #endif } #endif #ifndef HAVE_SETEGID int rep_setegid(gid_t egid) { #ifdef HAVE_SETRESGID return setresgid(-1, egid, -1); #else errno = ENOSYS; return -1; #endif } #endif /******************************************************************* os/2 also doesn't have chroot ********************************************************************/ #ifndef HAVE_CHROOT int rep_chroot(const char *dname) { errno = ENOSYS; return -1; } #endif /***************************************************************** Possibly replace mkstemp if it is broken. *****************************************************************/ #ifndef HAVE_SECURE_MKSTEMP int rep_mkstemp(char *template) { /* have a reasonable go at emulating it. Hope that the system mktemp() isn't completely hopeless */ mktemp(template); if (template[0] == 0) return -1; return open(template, O_CREAT|O_EXCL|O_RDWR, 0600); } #endif #ifndef HAVE_MKDTEMP char *rep_mkdtemp(char *template) { char *dname; if ((dname = mktemp(template))) { if (mkdir(dname, 0700) >= 0) { return dname; } } return NULL; } #endif /***************************************************************** Watch out: this is not thread safe. *****************************************************************/ #ifndef HAVE_PREAD ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) { if (lseek(__fd, __offset, SEEK_SET) != __offset) { return -1; } return read(__fd, __buf, __nbytes); } #endif /***************************************************************** Watch out: this is not thread safe. *****************************************************************/ #ifndef HAVE_PWRITE ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) { if (lseek(__fd, __offset, SEEK_SET) != __offset) { return -1; } return write(__fd, __buf, __nbytes); } #endif #ifndef HAVE_STRCASESTR char *rep_strcasestr(const char *haystack, const char *needle) { const char *s; size_t nlen = strlen(needle); for (s=haystack;*s;s++) { if (toupper(*needle) == toupper(*s) && strncasecmp(s, needle, nlen) == 0) { return (char *)((uintptr_t)s); } } return NULL; } #endif #ifndef HAVE_STRSEP char *rep_strsep(char **pps, const char *delim) { char *ret = *pps; char *p = *pps; if (p == NULL) { return NULL; } p += strcspn(p, delim); if (*p == '\0') { *pps = NULL; } else { *p = '\0'; *pps = p + 1; } return ret; } #endif #ifndef HAVE_STRTOK_R /* based on GLIBC version, copyright Free Software Foundation */ char *rep_strtok_r(char *s, const char *delim, char **save_ptr) { char *token; if (s == NULL) s = *save_ptr; s += strspn(s, delim); if (*s == '\0') { *save_ptr = s; return NULL; } token = s; s = strpbrk(token, delim); if (s == NULL) { *save_ptr = token + strlen(token); } else { *s = '\0'; *save_ptr = s + 1; } return token; } #endif #ifndef HAVE_STRTOLL long long int rep_strtoll(const char *str, char **endptr, int base) { #ifdef HAVE_STRTOQ return strtoq(str, endptr, base); #elif defined(HAVE___STRTOLL) return __strtoll(str, endptr, base); #elif SIZEOF_LONG == SIZEOF_LONG_LONG return (long long int) strtol(str, endptr, base); #else # error "You need a strtoll function" #endif } #else #ifdef HAVE_BSD_STRTOLL #undef strtoll long long int rep_strtoll(const char *str, char **endptr, int base) { int saved_errno = errno; long long int nb = strtoll(str, endptr, base); /* With glibc EINVAL is only returned if base is not ok */ if (errno == EINVAL) { if (base == 0 || (base >1 && base <37)) { /* Base was ok so it's because we were not * able to make the convertion. * Let's reset errno. */ errno = saved_errno; } } return nb; } #endif /* HAVE_BSD_STRTOLL */ #endif /* HAVE_STRTOLL */ #ifndef HAVE_STRTOULL unsigned long long int rep_strtoull(const char *str, char **endptr, int base) { #ifdef HAVE_STRTOUQ return strtouq(str, endptr, base); #elif defined(HAVE___STRTOULL) return __strtoull(str, endptr, base); #elif SIZEOF_LONG == SIZEOF_LONG_LONG return (unsigned long long int) strtoul(str, endptr, base); #else # error "You need a strtoull function" #endif } #else #ifdef HAVE_BSD_STRTOLL #undef strtoull unsigned long long int rep_strtoull(const char *str, char **endptr, int base) { int saved_errno = errno; unsigned long long int nb = strtoull(str, endptr, base); /* With glibc EINVAL is only returned if base is not ok */ if (errno == EINVAL) { if (base == 0 || (base >1 && base <37)) { /* Base was ok so it's because we were not * able to make the convertion. * Let's reset errno. */ errno = saved_errno; } } return nb; } #endif /* HAVE_BSD_STRTOLL */ #endif /* HAVE_STRTOULL */ #ifndef HAVE_SETENV int rep_setenv(const char *name, const char *value, int overwrite) { char *p; size_t l1, l2; int ret; if (!overwrite && getenv(name)) { return 0; } l1 = strlen(name); l2 = strlen(value); p = malloc(l1+l2+2); if (p == NULL) { return -1; } memcpy(p, name, l1); p[l1] = '='; memcpy(p+l1+1, value, l2); p[l1+l2+1] = 0; ret = putenv(p); if (ret != 0) { free(p); } return ret; } #endif #ifndef HAVE_UNSETENV int rep_unsetenv(const char *name) { extern char **environ; size_t len = strlen(name); size_t i, count; if (environ == NULL || getenv(name) == NULL) { return 0; } for (i=0;environ[i];i++) /* noop */ ; count=i; for (i=0;i= needlelen) { char *p = (char *)memchr(haystack, *(const char *)needle, haystacklen-(needlelen-1)); if (!p) return NULL; if (memcmp(p, needle, needlelen) == 0) { return p; } haystack = p+1; haystacklen -= (p - (const char *)haystack) + 1; } return NULL; } #endif #if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_vdprintf(int fd, const char *format, va_list ap) { char *s = NULL; int ret; vasprintf(&s, format, ap); if (s == NULL) { errno = ENOMEM; return -1; } ret = write(fd, s, strlen(s)); free(s); return ret; } #endif #if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_dprintf(int fd, const char *format, ...) { int ret; va_list ap; va_start(ap, format); ret = vdprintf(fd, format, ap); va_end(ap); return ret; } #endif #ifndef HAVE_GET_CURRENT_DIR_NAME char *rep_get_current_dir_name(void) { char buf[PATH_MAX+1]; char *p; p = getcwd(buf, sizeof(buf)); if (p == NULL) { return NULL; } return strdup(p); } #endif #ifndef HAVE_STRERROR_R int rep_strerror_r(int errnum, char *buf, size_t buflen) { char *s = strerror(errnum); if (strlen(s)+1 > buflen) { errno = ERANGE; return -1; } strncpy(buf, s, buflen); return 0; } #elif (!defined(STRERROR_R_XSI_NOT_GNU)) #undef strerror_r int rep_strerror_r(int errnum, char *buf, size_t buflen) { char *s = strerror_r(errnum, buf, buflen); if (s == NULL) { /* Shouldn't happen, should always get a string */ return EINVAL; } if (s != buf) { strlcpy(buf, s, buflen); if (strlen(s) > buflen - 1) { return ERANGE; } } return 0; } #endif #ifndef HAVE_CLOCK_GETTIME int rep_clock_gettime(clockid_t clk_id, struct timespec *tp) { struct timeval tval; switch (clk_id) { case 0: /* CLOCK_REALTIME :*/ #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID) gettimeofday(&tval,NULL); #else gettimeofday(&tval); #endif tp->tv_sec = tval.tv_sec; tp->tv_nsec = tval.tv_usec * 1000; break; default: errno = EINVAL; return -1; } return 0; } #endif #ifndef HAVE_MEMALIGN void *rep_memalign( size_t align, size_t size ) { #if defined(HAVE_POSIX_MEMALIGN) void *p = NULL; int ret = posix_memalign( &p, align, size ); if ( ret == 0 ) return p; return NULL; #else /* On *BSD systems memaligns doesn't exist, but memory will * be aligned on allocations of > pagesize. */ #if defined(SYSCONF_SC_PAGESIZE) size_t pagesize = (size_t)sysconf(_SC_PAGESIZE); #elif defined(HAVE_GETPAGESIZE) size_t pagesize = (size_t)getpagesize(); #else size_t pagesize = (size_t)-1; #endif if (pagesize == (size_t)-1) { errno = ENOSYS; return NULL; } if (size < pagesize) { size = pagesize; } return malloc(size); #endif } #endif #ifndef HAVE_GETPEEREID int rep_getpeereid(int s, uid_t *uid, gid_t *gid) { #if defined(HAVE_PEERCRED) struct ucred cred; socklen_t cred_len = sizeof(struct ucred); int ret; #undef getsockopt ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len); if (ret != 0) { return -1; } if (cred_len != sizeof(struct ucred)) { errno = EINVAL; return -1; } *uid = cred.uid; *gid = cred.gid; return 0; #else errno = ENOSYS; return -1; #endif } #endif #ifndef HAVE_USLEEP int rep_usleep(useconds_t sec) { struct timeval tval; /* * Fake it with select... */ tval.tv_sec = 0; tval.tv_usec = usecs/1000; select(0,NULL,NULL,NULL,&tval); return 0; } #endif /* HAVE_USLEEP */ #ifndef HAVE_SETPROCTITLE void rep_setproctitle(const char *fmt, ...) { } #endif #ifndef HAVE_SETPROCTITLE_INIT void rep_setproctitle_init(int argc, char *argv[], char *envp[]) { } #endif #ifndef HAVE_MEMSET_S # ifndef RSIZE_MAX # define RSIZE_MAX (SIZE_MAX >> 1) # endif int rep_memset_s(void *dest, size_t destsz, int ch, size_t count) { if (dest == NULL) { return EINVAL; } if (destsz > RSIZE_MAX || count > RSIZE_MAX || count > destsz) { return ERANGE; } #if defined(HAVE_MEMSET_EXPLICIT) memset_explicit(dest, destsz, ch, count); #else /* HAVE_MEMSET_EXPLICIT */ memset(dest, ch, count); # if defined(HAVE_GCC_VOLATILE_MEMORY_PROTECTION) /* See http://llvm.org/bugs/show_bug.cgi?id=15495 */ __asm__ volatile("" : : "g"(dest) : "memory"); # endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */ #endif /* HAVE_MEMSET_EXPLICIT */ return 0; } #endif /* HAVE_MEMSET_S */ #ifndef HAVE_GETPROGNAME # ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME # define PROGNAME_SIZE 32 static char rep_progname[PROGNAME_SIZE]; # endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ const char *rep_getprogname(void) { #ifdef HAVE_PROGRAM_INVOCATION_SHORT_NAME return program_invocation_short_name; #else /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ FILE *fp = NULL; char cmdline[4096] = {0}; char *p = NULL; pid_t pid; size_t nread; int len; int rc; if (rep_progname[0] != '\0') { return rep_progname; } len = snprintf(rep_progname, sizeof(rep_progname), "%s", ""); if (len <= 0) { return NULL; } pid = getpid(); if (pid <= 1 || pid == (pid_t)-1) { return NULL; } len = snprintf(cmdline, sizeof(cmdline), "/proc/%u/cmdline", (unsigned int)pid); if (len <= 0 || len == sizeof(cmdline)) { return NULL; } fp = fopen(cmdline, "r"); if (fp == NULL) { return NULL; } nread = fread(cmdline, 1, sizeof(cmdline) - 1, fp); rc = fclose(fp); if (rc != 0) { return NULL; } if (nread == 0) { return NULL; } cmdline[nread] = '\0'; p = strrchr(cmdline, '/'); if (p != NULL) { p++; } else { p = cmdline; } len = strlen(p); if (len > PROGNAME_SIZE) { p[PROGNAME_SIZE - 1] = '\0'; } (void)snprintf(rep_progname, sizeof(rep_progname), "%s", p); return rep_progname; #endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ } #endif /* HAVE_GETPROGNAME */ ldb-2.0.8/lib/replace/replace.h0000660000000000000000000005156613573675413016216 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. macros to go along with the lib/replace/ portability layer code Copyright (C) Andrew Tridgell 2005 Copyright (C) Jelmer Vernooij 2006-2008 Copyright (C) Jeremy Allison 2007. ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifndef _LIBREPLACE_REPLACE_H #define _LIBREPLACE_REPLACE_H #ifndef NO_CONFIG_H #include "config.h" #endif #ifdef HAVE_STANDARDS_H #include #endif /* * Needs to be defined before std*.h and string*.h are included * As it's also needed when Python.h is the first header we * require a global -D__STDC_WANT_LIB_EXT1__=1 */ #ifndef __STDC_WANT_LIB_EXT1__ #error -D__STDC_WANT_LIB_EXT1__=1 required #endif #include #include #include #include #ifndef HAVE_DECL_EWOULDBLOCK #define EWOULDBLOCK EAGAIN #endif #if defined(_MSC_VER) || defined(__MINGW32__) #include "win32_replace.h" #endif #ifdef HAVE_INTTYPES_H #define __STDC_FORMAT_MACROS #include #elif defined(HAVE_STDINT_H) #include /* force off HAVE_INTTYPES_H so that roken doesn't try to include both, which causes a warning storm on irix */ #undef HAVE_INTTYPES_H #endif #ifdef HAVE_MALLOC_H #include #endif #ifndef __PRI64_PREFIX # if __WORDSIZE == 64 && ! defined __APPLE__ # define __PRI64_PREFIX "l" # else # define __PRI64_PREFIX "ll" # endif #endif /* Decimal notation. */ #ifndef PRId8 # define PRId8 "d" #endif #ifndef PRId16 # define PRId16 "d" #endif #ifndef PRId32 # define PRId32 "d" #endif #ifndef PRId64 # define PRId64 __PRI64_PREFIX "d" #endif #ifndef PRIi8 # define PRIi8 "i" #endif #ifndef PRIi16 # define PRIi16 "i" #endif #ifndef PRIi32 # define PRIi32 "i" #endif #ifndef PRIi64 # define PRIi64 __PRI64_PREFIX "i" #endif #ifndef PRIu8 # define PRIu8 "u" #endif #ifndef PRIu16 # define PRIu16 "u" #endif #ifndef PRIu32 # define PRIu32 "u" #endif #ifndef PRIu64 # define PRIu64 __PRI64_PREFIX "u" #endif #ifndef SCNd8 # define SCNd8 "hhd" #endif #ifndef SCNd16 # define SCNd16 "hd" #endif #ifndef SCNd32 # define SCNd32 "d" #endif #ifndef SCNd64 # define SCNd64 __PRI64_PREFIX "d" #endif #ifndef SCNi8 # define SCNi8 "hhi" #endif #ifndef SCNi16 # define SCNi16 "hi" #endif #ifndef SCNi32 # define SCNi32 "i" #endif #ifndef SCNi64 # define SCNi64 __PRI64_PREFIX "i" #endif #ifndef SCNu8 # define SCNu8 "hhu" #endif #ifndef SCNu16 # define SCNu16 "hu" #endif #ifndef SCNu32 # define SCNu32 "u" #endif #ifndef SCNu64 # define SCNu64 __PRI64_PREFIX "u" #endif #ifdef HAVE_BSD_STRING_H #include #endif #ifdef HAVE_BSD_UNISTD_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_SYSMACROS_H #include #endif #ifdef HAVE_SETPROCTITLE_H #include #endif #if STDC_HEADERS #include #include #endif #ifdef HAVE_LINUX_TYPES_H /* * This is needed as some broken header files require this to be included early */ #include #endif #ifndef HAVE_STRERROR extern char *sys_errlist[]; #define strerror(i) sys_errlist[i] #endif #ifndef HAVE_ERRNO_DECL extern int errno; #endif #ifndef HAVE_STRDUP #define strdup rep_strdup char *rep_strdup(const char *s); #endif #ifndef HAVE_MEMMOVE #define memmove rep_memmove void *rep_memmove(void *dest,const void *src,int size); #endif #ifndef HAVE_MEMMEM #define memmem rep_memmem void *rep_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); #endif #ifndef HAVE_MEMALIGN #define memalign rep_memalign void *rep_memalign(size_t boundary, size_t size); #endif #ifndef HAVE_MKTIME #define mktime rep_mktime /* prototype is in "system/time.h" */ #endif #ifndef HAVE_TIMEGM #define timegm rep_timegm /* prototype is in "system/time.h" */ #endif #ifndef HAVE_UTIME #define utime rep_utime /* prototype is in "system/time.h" */ #endif #ifndef HAVE_UTIMES #define utimes rep_utimes /* prototype is in "system/time.h" */ #endif #ifndef HAVE_STRLCPY #define strlcpy rep_strlcpy size_t rep_strlcpy(char *d, const char *s, size_t bufsize); #endif #ifndef HAVE_STRLCAT #define strlcat rep_strlcat size_t rep_strlcat(char *d, const char *s, size_t bufsize); #endif #ifndef HAVE_CLOSEFROM #define closefrom rep_closefrom int rep_closefrom(int lower); #endif #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP)) #undef HAVE_STRNDUP #define strndup rep_strndup char *rep_strndup(const char *s, size_t n); #endif #if (defined(BROKEN_STRNLEN) || !defined(HAVE_STRNLEN)) #undef HAVE_STRNLEN #define strnlen rep_strnlen size_t rep_strnlen(const char *s, size_t n); #endif #if !defined(HAVE_DECL_ENVIRON) # ifdef __APPLE__ # include # define environ (*_NSGetEnviron()) # else /* __APPLE__ */ extern char **environ; # endif /* __APPLE */ #endif /* !defined(HAVE_DECL_ENVIRON) */ #ifndef HAVE_SETENV #define setenv rep_setenv int rep_setenv(const char *name, const char *value, int overwrite); #else #ifndef HAVE_SETENV_DECL int setenv(const char *name, const char *value, int overwrite); #endif #endif #ifndef HAVE_UNSETENV #define unsetenv rep_unsetenv int rep_unsetenv(const char *name); #endif #ifndef HAVE_SETEUID #define seteuid rep_seteuid int rep_seteuid(uid_t); #endif #ifndef HAVE_SETEGID #define setegid rep_setegid int rep_setegid(gid_t); #endif #if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL)) /* stupid glibc */ int setresuid(uid_t ruid, uid_t euid, uid_t suid); #endif #if (defined(USE_SETRESUID) && !defined(HAVE_SETRESGID_DECL)) int setresgid(gid_t rgid, gid_t egid, gid_t sgid); #endif #ifndef HAVE_CHOWN #define chown rep_chown int rep_chown(const char *path, uid_t uid, gid_t gid); #endif #ifndef HAVE_CHROOT #define chroot rep_chroot int rep_chroot(const char *dirname); #endif #ifndef HAVE_LINK #define link rep_link int rep_link(const char *oldpath, const char *newpath); #endif #ifndef HAVE_READLINK #define readlink rep_readlink ssize_t rep_readlink(const char *path, char *buf, size_t bufsize); #endif #ifndef HAVE_SYMLINK #define symlink rep_symlink int rep_symlink(const char *oldpath, const char *newpath); #endif #ifndef HAVE_REALPATH #define realpath rep_realpath char *rep_realpath(const char *path, char *resolved_path); #endif #ifndef HAVE_LCHOWN #define lchown rep_lchown int rep_lchown(const char *fname,uid_t uid,gid_t gid); #endif #ifdef HAVE_UNIX_H #include #endif #ifndef HAVE_SETLINEBUF #define setlinebuf rep_setlinebuf void rep_setlinebuf(FILE *); #endif #ifndef HAVE_STRCASESTR #define strcasestr rep_strcasestr char *rep_strcasestr(const char *haystack, const char *needle); #endif #ifndef HAVE_STRSEP #define strsep rep_strsep char *rep_strsep(char **pps, const char *delim); #endif #ifndef HAVE_STRTOK_R #define strtok_r rep_strtok_r char *rep_strtok_r(char *s, const char *delim, char **save_ptr); #endif #ifndef HAVE_STRTOLL #define strtoll rep_strtoll long long int rep_strtoll(const char *str, char **endptr, int base); #else #ifdef HAVE_BSD_STRTOLL #define strtoll rep_strtoll long long int rep_strtoll(const char *str, char **endptr, int base); #endif #endif #ifndef HAVE_STRTOULL #define strtoull rep_strtoull unsigned long long int rep_strtoull(const char *str, char **endptr, int base); #else #ifdef HAVE_BSD_STRTOLL /* yes, it's not HAVE_BSD_STRTOULL */ #define strtoull rep_strtoull unsigned long long int rep_strtoull(const char *str, char **endptr, int base); #endif #endif #ifndef HAVE_FTRUNCATE #define ftruncate rep_ftruncate int rep_ftruncate(int,off_t); #endif #ifndef HAVE_INITGROUPS #define initgroups rep_initgroups int rep_initgroups(char *name, gid_t id); #endif #if !defined(HAVE_BZERO) && defined(HAVE_MEMSET) #define bzero(a,b) memset((a),'\0',(b)) #endif #ifndef HAVE_DLERROR #define dlerror rep_dlerror char *rep_dlerror(void); #endif #ifndef HAVE_DLOPEN #define dlopen rep_dlopen #ifdef DLOPEN_TAKES_UNSIGNED_FLAGS void *rep_dlopen(const char *name, unsigned int flags); #else void *rep_dlopen(const char *name, int flags); #endif #endif #ifndef HAVE_DLSYM #define dlsym rep_dlsym void *rep_dlsym(void *handle, const char *symbol); #endif #ifndef HAVE_DLCLOSE #define dlclose rep_dlclose int rep_dlclose(void *handle); #endif #ifndef HAVE_SOCKETPAIR #define socketpair rep_socketpair /* prototype is in system/network.h */ #endif #ifndef PRINTF_ATTRIBUTE #ifdef HAVE___ATTRIBUTE__ /** Use gcc attribute to check printf fns. a1 is the 1-based index of * the parameter containing the format, and a2 the index of the first * argument. Note that some gcc 2.x versions don't handle this * properly **/ #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) #else #define PRINTF_ATTRIBUTE(a1, a2) #endif #endif #ifndef _DEPRECATED_ #ifdef HAVE___ATTRIBUTE__ #define _DEPRECATED_ __attribute__ ((deprecated)) #else #define _DEPRECATED_ #endif #endif #if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define vdprintf rep_vdprintf int rep_vdprintf(int fd, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); #endif #if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define dprintf rep_dprintf int rep_dprintf(int fd, const char *format, ...) PRINTF_ATTRIBUTE(2,3); #endif #if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define vasprintf rep_vasprintf int rep_vasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); #endif #if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define snprintf rep_snprintf int rep_snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4); #endif #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define vsnprintf rep_vsnprintf int rep_vsnprintf(char *,size_t ,const char *, va_list ap) PRINTF_ATTRIBUTE(3,0); #endif #if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define asprintf rep_asprintf int rep_asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); #endif #if !defined(HAVE_C99_VSNPRINTF) #ifdef REPLACE_BROKEN_PRINTF /* * We do not redefine printf by default * as it breaks the build if system headers * use __attribute__((format(printf, 3, 0))) * instead of __attribute__((format(__printf__, 3, 0))) */ #define printf rep_printf #endif int rep_printf(const char *, ...) PRINTF_ATTRIBUTE(1,2); #endif #if !defined(HAVE_C99_VSNPRINTF) #define fprintf rep_fprintf int rep_fprintf(FILE *stream, const char *, ...) PRINTF_ATTRIBUTE(2,3); #endif #ifndef HAVE_VSYSLOG #ifdef HAVE_SYSLOG #define vsyslog rep_vsyslog void rep_vsyslog (int facility_priority, const char *format, va_list arglist) PRINTF_ATTRIBUTE(2,0); #endif #endif /* we used to use these fns, but now we have good replacements for snprintf and vsnprintf */ #define slprintf snprintf #ifndef HAVE_VA_COPY #undef va_copy #ifdef HAVE___VA_COPY #define va_copy(dest, src) __va_copy(dest, src) #else #define va_copy(dest, src) (dest) = (src) #endif #endif #ifndef HAVE_VOLATILE #define volatile #endif #ifndef HAVE_COMPARISON_FN_T typedef int (*comparison_fn_t)(const void *, const void *); #endif #ifndef HAVE_WORKING_STRPTIME #define strptime rep_strptime struct tm; char *rep_strptime(const char *buf, const char *format, struct tm *tm); #endif #ifndef HAVE_DUP2 #define dup2 rep_dup2 int rep_dup2(int oldfd, int newfd); #endif /* Load header file for dynamic linking stuff */ #ifdef HAVE_DLFCN_H #include #endif #ifndef RTLD_LAZY #define RTLD_LAZY 0 #endif #ifndef RTLD_NOW #define RTLD_NOW 0 #endif #ifndef RTLD_GLOBAL #define RTLD_GLOBAL 0 #endif #ifndef HAVE_SECURE_MKSTEMP #define mkstemp(path) rep_mkstemp(path) int rep_mkstemp(char *temp); #endif #ifndef HAVE_MKDTEMP #define mkdtemp rep_mkdtemp char *rep_mkdtemp(char *template); #endif #ifndef HAVE_PREAD #define pread rep_pread ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); #define LIBREPLACE_PREAD_REPLACED 1 #else #define LIBREPLACE_PREAD_NOT_REPLACED 1 #endif #ifndef HAVE_PWRITE #define pwrite rep_pwrite ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); #define LIBREPLACE_PWRITE_REPLACED 1 #else #define LIBREPLACE_PWRITE_NOT_REPLACED 1 #endif #if !defined(HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) #define inet_ntoa rep_inet_ntoa /* prototype is in "system/network.h" */ #endif #ifndef HAVE_INET_PTON #define inet_pton rep_inet_pton /* prototype is in "system/network.h" */ #endif #ifndef HAVE_INET_NTOP #define inet_ntop rep_inet_ntop /* prototype is in "system/network.h" */ #endif #ifndef HAVE_INET_ATON #define inet_aton rep_inet_aton /* prototype is in "system/network.h" */ #endif #ifndef HAVE_CONNECT #define connect rep_connect /* prototype is in "system/network.h" */ #endif #ifndef HAVE_GETHOSTBYNAME #define gethostbyname rep_gethostbyname /* prototype is in "system/network.h" */ #endif #ifndef HAVE_GETIFADDRS #define getifaddrs rep_getifaddrs /* prototype is in "system/network.h" */ #endif #ifndef HAVE_FREEIFADDRS #define freeifaddrs rep_freeifaddrs /* prototype is in "system/network.h" */ #endif #ifndef HAVE_GET_CURRENT_DIR_NAME #define get_current_dir_name rep_get_current_dir_name char *rep_get_current_dir_name(void); #endif #if (!defined(HAVE_STRERROR_R) || !defined(STRERROR_R_XSI_NOT_GNU)) #define strerror_r rep_strerror_r int rep_strerror_r(int errnum, char *buf, size_t buflen); #endif #if !defined(HAVE_CLOCK_GETTIME) #define clock_gettime rep_clock_gettime #endif #ifdef HAVE_LIMITS_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif /* The extra casts work around common compiler bugs. */ #define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) /* The outer cast is needed to work around a bug in Cray C 5.0.3.0. It is necessary at least when t == time_t. */ #define _TYPE_MINIMUM(t) ((t) (_TYPE_SIGNED (t) \ ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) #define _TYPE_MAXIMUM(t) ((t) (~ (t) 0 - _TYPE_MINIMUM (t))) #ifndef UINT16_MAX #define UINT16_MAX 65535 #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef UINT64_MAX #define UINT64_MAX ((uint64_t)-1) #endif #ifndef INT64_MAX #define INT64_MAX 9223372036854775807LL #endif #ifndef CHAR_BIT #define CHAR_BIT 8 #endif #ifndef INT32_MAX #define INT32_MAX _TYPE_MAXIMUM(int32_t) #endif #ifdef HAVE_STDBOOL_H #include #endif #if !defined(HAVE_BOOL) #ifdef HAVE__Bool #define bool _Bool #else typedef int bool; #endif #endif #if !defined(HAVE_INTPTR_T) typedef long long intptr_t ; #define __intptr_t_defined #endif #if !defined(HAVE_UINTPTR_T) typedef unsigned long long uintptr_t ; #define __uintptr_t_defined #endif #if !defined(HAVE_PTRDIFF_T) typedef unsigned long long ptrdiff_t ; #endif /* * to prevent from doing a redefine of 'bool' * * IRIX, HPUX, MacOS 10 and Solaris need BOOL_DEFINED * Tru64 needs _BOOL_EXISTS * AIX needs _BOOL,_TRUE,_FALSE */ #ifndef BOOL_DEFINED #define BOOL_DEFINED #endif #ifndef _BOOL_EXISTS #define _BOOL_EXISTS #endif #ifndef _BOOL #define _BOOL #endif #ifndef __bool_true_false_are_defined #define __bool_true_false_are_defined #endif #ifndef true #define true (1) #endif #ifndef false #define false (0) #endif #ifndef _TRUE #define _TRUE true #endif #ifndef _FALSE #define _FALSE false #endif #ifndef HAVE_FUNCTION_MACRO #ifdef HAVE_func_MACRO #define __FUNCTION__ __func__ #else #define __FUNCTION__ ("") #endif #endif #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif #if !defined(HAVE_VOLATILE) #define volatile #endif /** this is a warning hack. The idea is to use this everywhere that we get the "discarding const" warning from gcc. That doesn't actually fix the problem of course, but it means that when we do get to cleaning them up we can do it by searching the code for discard_const. It also means that other error types aren't as swamped by the noise of hundreds of const warnings, so we are more likely to notice when we get new errors. Please only add more uses of this macro when you find it _really_ hard to fix const warnings. Our aim is to eventually use this function in only a very few places. Also, please call this via the discard_const_p() macro interface, as that makes the return type safe. */ #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) /** Type-safe version of discard_const */ #define discard_const_p(type, ptr) ((type *)discard_const(ptr)) #ifndef __STRING #define __STRING(x) #x #endif #ifndef __STRINGSTRING #define __STRINGSTRING(x) __STRING(x) #endif #ifndef __LINESTR__ #define __LINESTR__ __STRINGSTRING(__LINE__) #endif #ifndef __location__ #define __location__ __FILE__ ":" __LINESTR__ #endif /** * Zero a structure. */ #define ZERO_STRUCT(x) memset_s((char *)&(x), sizeof(x), 0, sizeof(x)) /** * Zero a structure given a pointer to the structure. */ #define ZERO_STRUCTP(x) do { \ if ((x) != NULL) { \ memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))); \ } \ } while(0) /** * Zero a structure given a pointer to the structure - no zero check */ #define ZERO_STRUCTPN(x) memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))) /** * Zero an array - note that sizeof(array) must work - ie. it must not be a * pointer */ #define ZERO_ARRAY(x) memset_s((char *)(x), sizeof(x), 0, sizeof(x)) /** * Zero a given len of an array */ #define ZERO_ARRAY_LEN(x, l) memset_s((char *)(x), (l), 0, (l)) /** * Work out how many elements there are in a static array. */ #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) /** * Pointer difference macro */ #define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) #ifdef __COMPAR_FN_T #define QSORT_CAST (__compar_fn_t) #endif #ifndef QSORT_CAST #define QSORT_CAST (int (*)(const void *, const void *)) #endif #ifndef PATH_MAX #define PATH_MAX 1024 #endif #ifndef MAX_DNS_NAME_LENGTH #define MAX_DNS_NAME_LENGTH 256 /* Actually 255 but +1 for terminating null. */ #endif #ifndef HAVE_CRYPT char *ufc_crypt(const char *key, const char *salt); #define crypt ufc_crypt #else #ifdef HAVE_CRYPT_H #include #endif #endif /* these macros gain us a few percent of speed on gcc */ #if (__GNUC__ >= 3) /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 as its first argument */ #ifndef likely #define likely(x) __builtin_expect(!!(x), 1) #endif #ifndef unlikely #define unlikely(x) __builtin_expect(!!(x), 0) #endif #else #ifndef likely #define likely(x) (x) #endif #ifndef unlikely #define unlikely(x) (x) #endif #endif #ifndef HAVE_FDATASYNC #define fdatasync(fd) fsync(fd) #elif !defined(HAVE_DECL_FDATASYNC) int fdatasync(int ); #endif /* these are used to mark symbols as local to a shared lib, or * publicly available via the shared lib API */ #ifndef _PUBLIC_ #ifdef HAVE_VISIBILITY_ATTR #define _PUBLIC_ __attribute__((visibility("default"))) #else #define _PUBLIC_ #endif #endif #ifndef _PRIVATE_ #ifdef HAVE_VISIBILITY_ATTR # define _PRIVATE_ __attribute__((visibility("hidden"))) #else # define _PRIVATE_ #endif #endif #ifndef HAVE_POLL #define poll rep_poll /* prototype is in "system/network.h" */ #endif #ifndef HAVE_GETPEEREID #define getpeereid rep_getpeereid int rep_getpeereid(int s, uid_t *uid, gid_t *gid); #endif #ifndef HAVE_USLEEP #define usleep rep_usleep typedef long useconds_t; int usleep(useconds_t); #endif #ifndef HAVE_SETPROCTITLE #define setproctitle rep_setproctitle void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); #endif #ifndef HAVE_SETPROCTITLE_INIT #define setproctitle_init rep_setproctitle_init void rep_setproctitle_init(int argc, char *argv[], char *envp[]); #endif #ifndef HAVE_MEMSET_S #define memset_s rep_memset_s int rep_memset_s(void *dest, size_t destsz, int ch, size_t count); #endif #ifndef HAVE_GETPROGNAME #define getprogname rep_getprogname const char *rep_getprogname(void); #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); bool uid_wrapper_enabled(void); /* Needed for Solaris atomic_add_XX functions. */ #if defined(HAVE_SYS_ATOMIC_H) #include #endif #endif /* _LIBREPLACE_REPLACE_H */ ldb-2.0.8/lib/replace/snprintf.c0000660000000000000000000010674613573675413016442 0ustar rootroot00000000000000/* * NOTE: If you change this file, please merge it into rsync, samba, etc. */ /* * Copyright Patrick Powell 1995 * This code is based on code written by Patrick Powell (papowell@astart.com) * It may be used for any purpose as long as this notice remains intact * on all source code distributions */ /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 * A bombproof version of doprnt (dopr) included. * Sigh. This sort of thing is always nasty do deal with. Note that * the version here does not include floating point... * * snprintf() is used instead of sprintf() as it does limit checks * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from * causing nast effects. * * More Recently: * Brandon Long 9/15/96 for mutt 0.43 * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything * from the normal C string format, at least as far as I can tell from * the Solaris 2.5 printf(3S) man page. * * Brandon Long 10/22/97 for mutt 0.87.1 * Ok, added some minimal floating point support, which means this * probably requires libm on most operating systems. Don't yet * support the exponent (e,E) and sigfig (g,G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways * which showed it, so that's been fixed. Also, formatted the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. * * Thomas Roessler 01/27/98 for mutt 0.89i * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 * The original code assumed that both snprintf() and vsnprintf() were * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * Andrew Tridgell (tridge@samba.org) Oct 1998 * fixed handling of %.0f * added test for HAVE_LONG_DOUBLE * * tridge@samba.org, idra@samba.org, April 2001 * got rid of fcvt code (twas buggy and made testing harder) * added C99 semantics * * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 * actually print args for %g and %e * * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 * Since includes.h isn't included here, VA_COPY has to be defined here. I don't * see any include file that is guaranteed to be here, so I'm defining it * locally. Fixes AIX and Solaris builds. * * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 * put the ifdef for HAVE_VA_COPY in one place rather than in lots of * functions * * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 * Fix usage of va_list passed as an arg. Use __va_copy before using it * when it exists. * * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 * Fix incorrect zpadlen handling in fmtfp. * Thanks to Ollie Oldham for spotting it. * few mods to make it easier to compile the tests. * addedd the "Ollie" test to the floating point ones. * * Martin Pool (mbp@samba.org) April 2003 * Remove NO_CONFIG_H so that the test case can be built within a source * tree with less trouble. * Remove unnecessary SAFE_FREE() definition. * * Martin Pool (mbp@samba.org) May 2003 * Put in a prototype for dummy_snprintf() to quiet compiler warnings. * * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even * if the C library has some snprintf functions already. * * Darren Tucker (dtucker@zip.com.au) 2005 * Fix bug allowing read overruns of the source string with "%.*s" * Usually harmless unless the read runs outside the process' allocation * (eg if your malloc does guard pages) in which case it will segfault. * From OpenSSH. Also added test for same. * * Simo Sorce (idra@samba.org) Jan 2006 * * Add support for position independent parameters * fix fmtstr now it conforms to sprintf wrt min.max * **************************************************************/ #include "replace.h" #include "system/locale.h" #ifdef TEST_SNPRINTF /* need math library headers for testing */ /* In test mode, we pretend that this system doesn't have any snprintf * functions, regardless of what config.h says. */ # undef HAVE_SNPRINTF # undef HAVE_VSNPRINTF # undef HAVE_C99_VSNPRINTF # undef HAVE_ASPRINTF # undef HAVE_VASPRINTF # include #endif /* TEST_SNPRINTF */ #if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) /* only include stdio.h if we are not re-defining snprintf or vsnprintf */ #include /* make the compiler happy with an empty file */ void dummy_snprintf(void); void dummy_snprintf(void) {} #endif /* HAVE_SNPRINTF, etc */ /* yes this really must be a ||. Don't muck with this (tridge) */ #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) #ifdef HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif #ifdef HAVE_LONG_LONG #define LLONG long long #else #define LLONG long #endif #ifndef VA_COPY #ifdef HAVE_VA_COPY #define VA_COPY(dest, src) va_copy(dest, src) #else #ifdef HAVE___VA_COPY #define VA_COPY(dest, src) __va_copy(dest, src) #else #define VA_COPY(dest, src) (dest) = (src) #endif #endif /* * dopr(): poor man's version of doprintf */ /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 #define DP_S_MIN 2 #define DP_S_DOT 3 #define DP_S_MAX 4 #define DP_S_MOD 5 #define DP_S_CONV 6 #define DP_S_DONE 7 /* format flags - Bits */ #define DP_F_MINUS (1 << 0) #define DP_F_PLUS (1 << 1) #define DP_F_SPACE (1 << 2) #define DP_F_NUM (1 << 3) #define DP_F_ZERO (1 << 4) #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ #define DP_C_CHAR 1 #define DP_C_SHORT 2 #define DP_C_LONG 3 #define DP_C_LDOUBLE 4 #define DP_C_LLONG 5 #define DP_C_SIZET 6 /* Chunk types */ #define CNK_FMT_STR 0 #define CNK_INT 1 #define CNK_OCTAL 2 #define CNK_UINT 3 #define CNK_HEX 4 #define CNK_FLOAT 5 #define CNK_CHAR 6 #define CNK_STRING 7 #define CNK_PTR 8 #define CNK_NUM 9 #define CNK_PRCNT 10 #define char_to_int(p) ((p)- '0') #ifndef MAX #define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif struct pr_chunk { int type; /* chunk type */ int num; /* parameter number */ int min; int max; int flags; int cflags; int start; int len; LLONG value; LDOUBLE fvalue; char *strvalue; void *pnum; struct pr_chunk *min_star; struct pr_chunk *max_star; struct pr_chunk *next; }; struct pr_chunk_x { struct pr_chunk **chunks; int num; }; static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in); static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static void fmtint(char *buffer, size_t *currlen, size_t maxlen, LLONG value, int base, int min, int max, int flags); static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); static struct pr_chunk *new_chunk(void); static int add_cnk_list_entry(struct pr_chunk_x **list, int max_num, struct pr_chunk *chunk); static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { char ch; int state; int pflag; int pnum; int pfirst; size_t currlen; va_list args; const char *base; struct pr_chunk *chunks = NULL; struct pr_chunk *cnk = NULL; struct pr_chunk_x *clist = NULL; int max_pos; int ret = -1; VA_COPY(args, args_in); state = DP_S_DEFAULT; pfirst = 1; pflag = 0; pnum = 0; max_pos = 0; base = format; ch = *format++; /* retrieve the string structure as chunks */ while (state != DP_S_DONE) { if (ch == '\0') state = DP_S_DONE; switch(state) { case DP_S_DEFAULT: if (cnk) { cnk->next = new_chunk(); cnk = cnk->next; } else { cnk = new_chunk(); } if (!cnk) goto done; if (!chunks) chunks = cnk; if (ch == '%') { state = DP_S_FLAGS; ch = *format++; } else { cnk->type = CNK_FMT_STR; cnk->start = format - base -1; while ((ch != '\0') && (ch != '%')) ch = *format++; cnk->len = format - base - cnk->start -1; } break; case DP_S_FLAGS: switch (ch) { case '-': cnk->flags |= DP_F_MINUS; ch = *format++; break; case '+': cnk->flags |= DP_F_PLUS; ch = *format++; break; case ' ': cnk->flags |= DP_F_SPACE; ch = *format++; break; case '#': cnk->flags |= DP_F_NUM; ch = *format++; break; case '0': cnk->flags |= DP_F_ZERO; ch = *format++; break; case 'I': /* internationalization not supported yet */ ch = *format++; break; default: state = DP_S_MIN; break; } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { cnk->min = 10 * cnk->min + char_to_int (ch); ch = *format++; } else if (ch == '$') { if (!pfirst && !pflag) { /* parameters must be all positioned or none */ goto done; } if (pfirst) { pfirst = 0; pflag = 1; } if (cnk->min == 0) /* what ?? */ goto done; cnk->num = cnk->min; cnk->min = 0; ch = *format++; } else if (ch == '*') { if (pfirst) pfirst = 0; cnk->min_star = new_chunk(); if (!cnk->min_star) /* out of memory :-( */ goto done; cnk->min_star->type = CNK_INT; if (pflag) { int num; ch = *format++; if (!isdigit((unsigned char)ch)) { /* parameters must be all positioned or none */ goto done; } for (num = 0; isdigit((unsigned char)ch); ch = *format++) { num = 10 * num + char_to_int(ch); } cnk->min_star->num = num; if (ch != '$') /* what ?? */ goto done; } else { cnk->min_star->num = ++pnum; } max_pos = add_cnk_list_entry(&clist, max_pos, cnk->min_star); if (max_pos == 0) /* out of memory :-( */ goto done; ch = *format++; state = DP_S_DOT; } else { if (pfirst) pfirst = 0; state = DP_S_DOT; } break; case DP_S_DOT: if (ch == '.') { state = DP_S_MAX; ch = *format++; } else { state = DP_S_MOD; } break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (cnk->max < 0) cnk->max = 0; cnk->max = 10 * cnk->max + char_to_int (ch); ch = *format++; } else if (ch == '$') { if (!pfirst && !pflag) { /* parameters must be all positioned or none */ goto done; } if (cnk->max <= 0) /* what ?? */ goto done; cnk->num = cnk->max; cnk->max = -1; ch = *format++; } else if (ch == '*') { cnk->max_star = new_chunk(); if (!cnk->max_star) /* out of memory :-( */ goto done; cnk->max_star->type = CNK_INT; if (pflag) { int num; ch = *format++; if (!isdigit((unsigned char)ch)) { /* parameters must be all positioned or none */ goto done; } for (num = 0; isdigit((unsigned char)ch); ch = *format++) { num = 10 * num + char_to_int(ch); } cnk->max_star->num = num; if (ch != '$') /* what ?? */ goto done; } else { cnk->max_star->num = ++pnum; } max_pos = add_cnk_list_entry(&clist, max_pos, cnk->max_star); if (max_pos == 0) /* out of memory :-( */ goto done; ch = *format++; state = DP_S_MOD; } else { state = DP_S_MOD; } break; case DP_S_MOD: switch (ch) { case 'h': cnk->cflags = DP_C_SHORT; ch = *format++; if (ch == 'h') { cnk->cflags = DP_C_CHAR; ch = *format++; } break; case 'l': cnk->cflags = DP_C_LONG; ch = *format++; if (ch == 'l') { /* It's a long long */ cnk->cflags = DP_C_LLONG; ch = *format++; } break; case 'j': cnk->cflags = DP_C_LLONG; ch = *format++; break; case 'L': cnk->cflags = DP_C_LDOUBLE; ch = *format++; break; case 'z': cnk->cflags = DP_C_SIZET; ch = *format++; break; default: break; } state = DP_S_CONV; break; case DP_S_CONV: if (cnk->num == 0) cnk->num = ++pnum; max_pos = add_cnk_list_entry(&clist, max_pos, cnk); if (max_pos == 0) /* out of memory :-( */ goto done; switch (ch) { case 'd': case 'i': cnk->type = CNK_INT; break; case 'o': cnk->type = CNK_OCTAL; cnk->flags |= DP_F_UNSIGNED; break; case 'u': cnk->type = CNK_UINT; cnk->flags |= DP_F_UNSIGNED; break; case 'X': cnk->flags |= DP_F_UP; case 'x': cnk->type = CNK_HEX; cnk->flags |= DP_F_UNSIGNED; break; case 'A': /* hex float not supported yet */ case 'E': case 'G': case 'F': cnk->flags |= DP_F_UP; case 'a': /* hex float not supported yet */ case 'e': case 'f': case 'g': cnk->type = CNK_FLOAT; break; case 'c': cnk->type = CNK_CHAR; break; case 's': cnk->type = CNK_STRING; break; case 'p': cnk->type = CNK_PTR; cnk->flags |= DP_F_UNSIGNED; break; case 'n': cnk->type = CNK_NUM; break; case '%': cnk->type = CNK_PRCNT; break; default: /* Unknown, bail out*/ goto done; } ch = *format++; state = DP_S_DEFAULT; break; case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ } } /* retrieve the format arguments */ for (pnum = 0; pnum < max_pos; pnum++) { int i; if (clist[pnum].num == 0) { /* ignoring a parameter should not be permitted * all parameters must be matched at least once * BUT seem some system ignore this rule ... * at least my glibc based system does --SSS */ #ifdef DEBUG_SNPRINTF printf("parameter at position %d not used\n", pnum+1); #endif /* eat the parameter */ va_arg (args, int); continue; } for (i = 1; i < clist[pnum].num; i++) { if (clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) { /* nooo noo no! * all the references to a parameter * must be of the same type */ goto done; } } cnk = clist[pnum].chunks[0]; switch (cnk->type) { case CNK_INT: if (cnk->cflags == DP_C_SHORT) cnk->value = va_arg (args, int); else if (cnk->cflags == DP_C_LONG) cnk->value = va_arg (args, long int); else if (cnk->cflags == DP_C_LLONG) cnk->value = va_arg (args, LLONG); else if (cnk->cflags == DP_C_SIZET) cnk->value = va_arg (args, ssize_t); else cnk->value = va_arg (args, int); for (i = 1; i < clist[pnum].num; i++) { clist[pnum].chunks[i]->value = cnk->value; } break; case CNK_OCTAL: case CNK_UINT: case CNK_HEX: if (cnk->cflags == DP_C_SHORT) cnk->value = va_arg (args, unsigned int); else if (cnk->cflags == DP_C_LONG) cnk->value = (unsigned long int)va_arg (args, unsigned long int); else if (cnk->cflags == DP_C_LLONG) cnk->value = (LLONG)va_arg (args, unsigned LLONG); else if (cnk->cflags == DP_C_SIZET) cnk->value = (size_t)va_arg (args, size_t); else cnk->value = (unsigned int)va_arg (args, unsigned int); for (i = 1; i < clist[pnum].num; i++) { clist[pnum].chunks[i]->value = cnk->value; } break; case CNK_FLOAT: if (cnk->cflags == DP_C_LDOUBLE) cnk->fvalue = va_arg (args, LDOUBLE); else cnk->fvalue = va_arg (args, double); for (i = 1; i < clist[pnum].num; i++) { clist[pnum].chunks[i]->fvalue = cnk->fvalue; } break; case CNK_CHAR: cnk->value = va_arg (args, int); for (i = 1; i < clist[pnum].num; i++) { clist[pnum].chunks[i]->value = cnk->value; } break; case CNK_STRING: cnk->strvalue = va_arg (args, char *); if (!cnk->strvalue) cnk->strvalue = "(NULL)"; for (i = 1; i < clist[pnum].num; i++) { clist[pnum].chunks[i]->strvalue = cnk->strvalue; } break; case CNK_PTR: cnk->strvalue = va_arg (args, void *); for (i = 1; i < clist[pnum].num; i++) { clist[pnum].chunks[i]->strvalue = cnk->strvalue; } break; case CNK_NUM: if (cnk->cflags == DP_C_CHAR) cnk->pnum = va_arg (args, char *); else if (cnk->cflags == DP_C_SHORT) cnk->pnum = va_arg (args, short int *); else if (cnk->cflags == DP_C_LONG) cnk->pnum = va_arg (args, long int *); else if (cnk->cflags == DP_C_LLONG) cnk->pnum = va_arg (args, LLONG *); else if (cnk->cflags == DP_C_SIZET) cnk->pnum = va_arg (args, ssize_t *); else cnk->pnum = va_arg (args, int *); for (i = 1; i < clist[pnum].num; i++) { clist[pnum].chunks[i]->pnum = cnk->pnum; } break; case CNK_PRCNT: break; default: /* what ?? */ goto done; } } /* print out the actual string from chunks */ currlen = 0; cnk = chunks; while (cnk) { int len, min, max; if (cnk->min_star) min = cnk->min_star->value; else min = cnk->min; if (cnk->max_star) max = cnk->max_star->value; else max = cnk->max; switch (cnk->type) { case CNK_FMT_STR: if (maxlen != 0 && maxlen > currlen) { if (maxlen > (currlen + cnk->len)) len = cnk->len; else len = maxlen - currlen; memcpy(&(buffer[currlen]), &(base[cnk->start]), len); } currlen += cnk->len; break; case CNK_INT: case CNK_UINT: fmtint (buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags); break; case CNK_OCTAL: fmtint (buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags); break; case CNK_HEX: fmtint (buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags); break; case CNK_FLOAT: fmtfp (buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags); break; case CNK_CHAR: dopr_outch (buffer, &currlen, maxlen, cnk->value); break; case CNK_STRING: if (max == -1) { max = strlen(cnk->strvalue); } fmtstr (buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max); break; case CNK_PTR: fmtint (buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags); break; case CNK_NUM: if (cnk->cflags == DP_C_CHAR) *((char *)(cnk->pnum)) = (char)currlen; else if (cnk->cflags == DP_C_SHORT) *((short int *)(cnk->pnum)) = (short int)currlen; else if (cnk->cflags == DP_C_LONG) *((long int *)(cnk->pnum)) = (long int)currlen; else if (cnk->cflags == DP_C_LLONG) *((LLONG *)(cnk->pnum)) = (LLONG)currlen; else if (cnk->cflags == DP_C_SIZET) *((ssize_t *)(cnk->pnum)) = (ssize_t)currlen; else *((int *)(cnk->pnum)) = (int)currlen; break; case CNK_PRCNT: dopr_outch (buffer, &currlen, maxlen, '%'); break; default: /* what ?? */ goto done; } cnk = cnk->next; } if (maxlen != 0) { if (currlen < maxlen - 1) buffer[currlen] = '\0'; else if (maxlen > 0) buffer[maxlen - 1] = '\0'; } ret = currlen; done: va_end(args); while (chunks) { cnk = chunks->next; free(chunks); chunks = cnk; } if (clist) { for (pnum = 0; pnum < max_pos; pnum++) { if (clist[pnum].chunks) free(clist[pnum].chunks); } free(clist); } return ret; } static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; #ifdef DEBUG_SNPRINTF printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); #endif if (value == 0) { value = ""; } for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } while (*value && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, *value++); ++cnt; } while (padlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, LLONG value, int base, int min, int max, int flags) { int signvalue = 0; unsigned LLONG uvalue; char convert[22+1]; /* 64-bit value in octal: 22 digits + \0 */ int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if(!(flags & DP_F_UNSIGNED)) { if( value < 0 ) { signvalue = '-'; uvalue = -value; } else { if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); } while(uvalue && (place < sizeof(convert))); if (place == sizeof(convert)) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place); #endif /* Spaces */ while (spadlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) dopr_outch (buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++spadlen; } } static LDOUBLE abs_val(LDOUBLE value) { LDOUBLE result = value; if (value < 0) result = -value; return result; } static LDOUBLE POW10(int exp) { LDOUBLE result = 1; while (exp) { result *= 10; exp--; } return result; } static LLONG ROUND(LDOUBLE value) { LLONG intpart; intpart = (LLONG)value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } /* a replacement for modf that doesn't need the math library. Should be portable, but slow */ static double my_modf(double x0, double *iptr) { int i; LLONG l=0; double x = x0; double f = 1.0; for (i=0;i<100;i++) { l = (long)x; if (l <= (x+1) && l >= (x-1)) break; x *= 0.1; f *= 10.0; } if (i == 100) { /* yikes! the number is beyond what we can handle. What do we do? */ (*iptr) = 0; return 0; } if (i != 0) { double i2; double ret; ret = my_modf(x0-l*f, &i2); (*iptr) = l*f + i2; return ret; } (*iptr) = l; return x - (*iptr); } static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; double ufvalue; char iconvert[311]; char fconvert[311]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; int caps = 0; int idx; double intpart; double fracpart; double temp; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val (fvalue); if (fvalue < 0) { signvalue = '-'; } else { if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ signvalue = '+'; } else { if (flags & DP_F_SPACE) signvalue = ' '; } } #if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif #if 0 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ #endif /* * Sorry, we only support 9 digits past the decimal because of our * conversion method */ if (max > 9) max = 9; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ temp = ufvalue; my_modf(temp, &intpart); fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); if (fracpart >= POW10(max)) { intpart++; fracpart -= POW10(max); } /* Convert integer part */ do { temp = intpart*0.1; my_modf(temp, &intpart); idx = (int) ((temp -intpart +0.05)* 10.0); /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; } while (intpart && (iplace < 311)); if (iplace == 311) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ if (fracpart) { do { temp = fracpart*0.1; my_modf(temp, &fracpart); idx = (int) ((temp -fracpart +0.05)* 10.0); /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; } while(fracpart && (fplace < 311)); if (fplace == 311) fplace--; } fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { dopr_outch (buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); while (iplace > 0) dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); #endif /* * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { dopr_outch (buffer, currlen, maxlen, '.'); while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } while (fplace > 0) dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); } while (padlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; } } static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) { if (*currlen < maxlen) { buffer[(*currlen)] = c; } (*currlen)++; } static struct pr_chunk *new_chunk(void) { struct pr_chunk *new_c = (struct pr_chunk *)malloc(sizeof(struct pr_chunk)); if (!new_c) return NULL; new_c->type = 0; new_c->num = 0; new_c->min = 0; new_c->min_star = NULL; new_c->max = -1; new_c->max_star = NULL; new_c->flags = 0; new_c->cflags = 0; new_c->start = 0; new_c->len = 0; new_c->value = 0; new_c->fvalue = 0; new_c->strvalue = NULL; new_c->pnum = NULL; new_c->next = NULL; return new_c; } static int add_cnk_list_entry(struct pr_chunk_x **list, int max_num, struct pr_chunk *chunk) { struct pr_chunk_x *l; struct pr_chunk **c; int max; int cnum; int i, pos; if (chunk->num > max_num) { max = chunk->num; if (*list == NULL) { l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max); pos = 0; } else { l = (struct pr_chunk_x *)realloc(*list, sizeof(struct pr_chunk_x) * max); pos = max_num; } if (l == NULL) { for (i = 0; i < max; i++) { if ((*list)[i].chunks) free((*list)[i].chunks); } return 0; } for (i = pos; i < max; i++) { l[i].chunks = NULL; l[i].num = 0; } } else { l = *list; max = max_num; } i = chunk->num - 1; cnum = l[i].num + 1; if (l[i].chunks == NULL) { c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum); } else { c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum); } if (c == NULL) { for (i = 0; i < max; i++) { if (l[i].chunks) free(l[i].chunks); } return 0; } c[l[i].num] = chunk; l[i].chunks = c; l[i].num = cnum; *list = l; return max; } int rep_vsnprintf (char *str, size_t count, const char *fmt, va_list args) { return dopr(str, count, fmt, args); } #endif /* yes this really must be a ||. Don't muck with this (tridge) * * The logic for these two is that we need our own definition if the * OS *either* has no definition of *sprintf, or if it does have one * that doesn't work properly according to the autoconf test. */ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_snprintf(char *str,size_t count,const char *fmt,...) { size_t ret; va_list ap; va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); return ret; } #endif #ifndef HAVE_C99_VSNPRINTF int rep_printf(const char *fmt, ...) { va_list ap; int ret; char *s; s = NULL; va_start(ap, fmt); ret = vasprintf(&s, fmt, ap); va_end(ap); if (s) { fwrite(s, 1, strlen(s), stdout); } free(s); return ret; } #endif #ifndef HAVE_C99_VSNPRINTF int rep_fprintf(FILE *stream, const char *fmt, ...) { va_list ap; int ret; char *s; s = NULL; va_start(ap, fmt); ret = vasprintf(&s, fmt, ap); va_end(ap); if (s) { fwrite(s, 1, strlen(s), stream); } free(s); return ret; } #endif #endif #if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_vasprintf(char **ptr, const char *format, va_list ap) { int ret; va_list ap2; VA_COPY(ap2, ap); ret = vsnprintf(NULL, 0, format, ap2); va_end(ap2); if (ret < 0) return ret; (*ptr) = (char *)malloc(ret+1); if (!*ptr) return -1; VA_COPY(ap2, ap); ret = vsnprintf(*ptr, ret+1, format, ap2); va_end(ap2); return ret; } #endif #if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_asprintf(char **ptr, const char *format, ...) { va_list ap; int ret; *ptr = NULL; va_start(ap, format); ret = vasprintf(ptr, format, ap); va_end(ap); return ret; } #endif #ifdef TEST_SNPRINTF int sprintf(char *str,const char *fmt,...); int printf(const char *fmt,...); int main (void) { char buf1[1024]; char buf2[1024]; char *buf3; char *fp_fmt[] = { "%1.1f", "%-1.5f", "%1.5f", "%123.9f", "%10.5f", "% 10.5f", "%+22.9f", "%+4.9f", "%01.3f", "%4f", "%3.1f", "%3.2f", "%.0f", "%f", "%-8.8f", "%-9.9f", NULL }; double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996, 0.9996, 1.996, 4.136, 5.030201, 0.00205, /* END LIST */ 0}; char *int_fmt[] = { "%-1.5d", "%1.5d", "%123.9d", "%5.5d", "%10.5d", "% 10.5d", "%+22.33d", "%01.3d", "%4d", "%d", NULL }; long int_nums[] = { -1, 134, 91340, 341, 0203, 1234567890, 0}; char *str_fmt[] = { "%10.5s", "%-10.5s", "%5.10s", "%-5.10s", "%10.1s", "%0.10s", "%10.0s", "%1.10s", "%s", "%.1s", "%.10s", "%10s", NULL }; char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; #ifdef HAVE_LONG_LONG char *ll_fmt[] = { "%llu", NULL }; LLONG ll_nums[] = { 134, 91340, 341, 0203, 1234567890, 128006186140000000LL, 0}; #endif int x, y; int fail = 0; int num = 0; int l1, l2; char *ss_fmt[] = { "%zd", "%zu", NULL }; size_t ss_nums[] = {134, 91340, 123456789, 0203, 1234567890, 0}; printf ("Testing snprintf format codes against system sprintf...\n"); for (x = 0; fp_fmt[x] ; x++) { for (y = 0; fp_nums[y] != 0 ; y++) { buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); l2 = sprintf (buf2, fp_fmt[x], fp_nums[y]); buf1[1023] = buf2[1023] = '\0'; if (strcmp (buf1, buf2) || (l1 != l2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", fp_fmt[x], l1, buf1, l2, buf2); fail++; } num++; } } for (x = 0; int_fmt[x] ; x++) { for (y = 0; int_nums[y] != 0 ; y++) { buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); l2 = sprintf (buf2, int_fmt[x], int_nums[y]); buf1[1023] = buf2[1023] = '\0'; if (strcmp (buf1, buf2) || (l1 != l2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", int_fmt[x], l1, buf1, l2, buf2); fail++; } num++; } } for (x = 0; str_fmt[x] ; x++) { for (y = 0; str_vals[y] != 0 ; y++) { buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); l2 = sprintf (buf2, str_fmt[x], str_vals[y]); buf1[1023] = buf2[1023] = '\0'; if (strcmp (buf1, buf2) || (l1 != l2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", str_fmt[x], l1, buf1, l2, buf2); fail++; } num++; } } #ifdef HAVE_LONG_LONG for (x = 0; ll_fmt[x] ; x++) { for (y = 0; ll_nums[y] != 0 ; y++) { buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), ll_fmt[x], ll_nums[y]); l2 = sprintf (buf2, ll_fmt[x], ll_nums[y]); buf1[1023] = buf2[1023] = '\0'; if (strcmp (buf1, buf2) || (l1 != l2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", ll_fmt[x], l1, buf1, l2, buf2); fail++; } num++; } } #endif #define BUFSZ 2048 buf1[0] = buf2[0] = '\0'; if ((buf3 = malloc(BUFSZ)) == NULL) { fail++; } else { num++; memset(buf3, 'a', BUFSZ); snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3); buf1[1023] = '\0'; if (strcmp(buf1, "a") != 0) { printf("length limit buf1 '%s' expected 'a'\n", buf1); fail++; } } buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); l2 = sprintf(buf2, "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); buf1[1023] = buf2[1023] = '\0'; if (strcmp(buf1, buf2) || (l1 != l2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); fail++; } buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); l2 = sprintf(buf2, "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); buf1[1023] = buf2[1023] = '\0'; if (strcmp(buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); fail++; } for (x = 0; ss_fmt[x] ; x++) { for (y = 0; ss_nums[y] != 0 ; y++) { buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), ss_fmt[x], ss_nums[y]); l2 = sprintf (buf2, ss_fmt[x], ss_nums[y]); buf1[1023] = buf2[1023] = '\0'; if (strcmp (buf1, buf2) || (l1 != l2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", ss_fmt[x], l1, buf1, l2, buf2); fail++; } num++; } } #if 0 buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), "%lld", (LLONG)1234567890); l2 = sprintf(buf2, "%lld", (LLONG)1234567890); buf1[1023] = buf2[1023] = '\0'; if (strcmp(buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", "%lld", l1, buf1, l2, buf2); fail++; } buf1[0] = buf2[0] = '\0'; l1 = snprintf(buf1, sizeof(buf1), "%Lf", (LDOUBLE)890.1234567890123); l2 = sprintf(buf2, "%Lf", (LDOUBLE)890.1234567890123); buf1[1023] = buf2[1023] = '\0'; if (strcmp(buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", "%Lf", l1, buf1, l2, buf2); fail++; } #endif printf ("%d tests failed out of %d.\n", fail, num); printf("seeing how many digits we support\n"); { double v0 = 0.12345678901234567890123456789012345678901; for (x=0; x<100; x++) { double p = pow(10, x); double r = v0*p; snprintf(buf1, sizeof(buf1), "%1.1f", r); sprintf(buf2, "%1.1f", r); if (strcmp(buf1, buf2)) { printf("we seem to support %d digits\n", x-1); break; } } } return 0; } #endif /* TEST_SNPRINTF */ ldb-2.0.8/lib/replace/socket.c0000660000000000000000000000230712406075657016051 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * * Dummy replacements for socket functions. * * Copyright (C) Michael Adam 2008 * * ** NOTE! The following LGPL license applies to the replace * ** 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 * Library 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 . */ #include "replace.h" #include "system/network.h" int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) { errno = ENOSYS; return -1; } struct hostent *rep_gethostbyname(const char *name) { errno = ENOSYS; return NULL; } ldb-2.0.8/lib/replace/socketpair.c0000660000000000000000000000250112406075657016721 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * replacement routines for broken systems * Copyright (C) Jelmer Vernooij 2006 * Copyright (C) Michael Adam 2008 * * ** NOTE! The following LGPL license applies to the replace * ** 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 . */ #include "replace.h" #include "system/network.h" int rep_socketpair(int d, int type, int protocol, int sv[2]) { if (d != AF_UNIX) { errno = EAFNOSUPPORT; return -1; } if (protocol != 0) { errno = EPROTONOSUPPORT; return -1; } if (type != SOCK_STREAM) { errno = EOPNOTSUPP; return -1; } return pipe(sv); } ldb-2.0.8/lib/replace/strptime.c0000660000000000000000000005674113444661620016435 0ustar rootroot00000000000000/* Convert a string representation of time to a time value. Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. The GNU C 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. The GNU C 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 Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If not, see . */ /* XXX This version of the implementation is not really complete. Some of the fields cannot add information alone. But if seeing some of them in the same format (such as year, week and weekday) this is enough information for determining the date. */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #ifndef __P # if defined (__GNUC__) || (defined (__STDC__) && __STDC__) # define __P(args) args # else # define __P(args) () # endif /* GCC. */ #endif /* Not __P. */ #if ! HAVE_LOCALTIME_R && ! defined localtime_r # ifdef _LIBC # define localtime_r __localtime_r # else /* Approximate localtime_r as best we can in its absence. */ # define localtime_r my_localtime_r static struct tm *localtime_r __P ((const time_t *, struct tm *)); static struct tm * localtime_r (t, tp) const time_t *t; struct tm *tp; { struct tm *l = localtime (t); if (! l) return 0; *tp = *l; return tp; } # endif /* ! _LIBC */ #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ #define match_char(ch1, ch2) if (ch1 != ch2) return NULL #if defined __GNUC__ && __GNUC__ >= 2 # define match_string(cs1, s2) \ ({ size_t len = strlen (cs1); \ int result = strncasecmp ((cs1), (s2), len) == 0; \ if (result) (s2) += len; \ result; }) #else /* Oh come on. Get a reasonable compiler. */ # define match_string(cs1, s2) \ (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) #endif /* We intentionally do not use isdigit() for testing because this will lead to problems with the wide character version. */ #define get_number(from, to, n) \ do { \ int __n = n; \ val = 0; \ while (*rp == ' ') \ ++rp; \ if (*rp < '0' || *rp > '9') \ return NULL; \ do { \ val *= 10; \ val += *rp++ - '0'; \ } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ if (val < from || val > to) \ return NULL; \ } while (0) #ifdef _NL_CURRENT # define get_alt_number(from, to, n) \ ({ \ __label__ do_normal; \ if (*decided != raw) \ { \ const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ int __n = n; \ int any = 0; \ while (*rp == ' ') \ ++rp; \ val = 0; \ do { \ val *= 10; \ while (*alts != '\0') \ { \ size_t len = strlen (alts); \ if (strncasecmp (alts, rp, len) == 0) \ break; \ alts += len + 1; \ ++val; \ } \ if (*alts == '\0') \ { \ if (*decided == not && ! any) \ goto do_normal; \ /* If we haven't read anything it's an error. */ \ if (! any) \ return NULL; \ /* Correct the premature multiplication. */ \ val /= 10; \ break; \ } \ else \ *decided = loc; \ } while (--__n > 0 && val * 10 <= to); \ if (val < from || val > to) \ return NULL; \ } \ else \ { \ do_normal: \ get_number (from, to, n); \ } \ 0; \ }) #else # define get_alt_number(from, to, n) \ /* We don't have the alternate representation. */ \ get_number(from, to, n) #endif #define recursive(new_fmt) \ (*(new_fmt) != '\0' \ && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) #ifdef _LIBC /* This is defined in locale/C-time.c in the GNU libc. */ extern const struct locale_data _nl_C_LC_TIME; extern const unsigned short int __mon_yday[2][13]; # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) # define ab_weekday_name \ (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) # define HERE_T_FMT_AMPM \ (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) #else static char const weekday_name[][10] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static char const ab_weekday_name[][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static char const month_name[][10] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static char const ab_month_name[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" # define HERE_D_FMT "%m/%d/%y" # define HERE_AM_STR "AM" # define HERE_PM_STR "PM" # define HERE_T_FMT_AMPM "%I:%M:%S %p" # define HERE_T_FMT "%H:%M:%S" static const unsigned short int __mon_yday[2][13] = { /* Normal years. */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, /* Leap years. */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; #endif /* Status of lookup: do we use the locale data or the raw data? */ enum locale_status { not, loc, raw }; #ifndef __isleap /* Nonzero if YEAR is a leap year (every 4 years, except every 100th isn't, and every 400th is). */ # define __isleap(year) \ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) #endif /* Compute the day of the week. */ static void day_of_the_week (struct tm *tm) { /* We know that January 1st 1970 was a Thursday (= 4). Compute the the difference between this data in the one on TM and so determine the weekday. */ int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); int wday = (-473 + (365 * (tm->tm_year - 70)) + (corr_year / 4) - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) + (((corr_year / 4) / 25) / 4) + __mon_yday[0][tm->tm_mon] + tm->tm_mday - 1); tm->tm_wday = ((wday % 7) + 7) % 7; } /* Compute the day of the year. */ static void day_of_the_year (struct tm *tm) { tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] + (tm->tm_mday - 1)); } static char * #ifdef _LIBC internal_function #endif strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, enum locale_status *decided, int era_cnt)); static char * #ifdef _LIBC internal_function #endif strptime_internal (rp, fmt, tm, decided, era_cnt) const char *rp; const char *fmt; struct tm *tm; enum locale_status *decided; int era_cnt; { int cnt; size_t val; int have_I, is_pm; int century, want_century; int want_era; int have_wday, want_xday; int have_yday; int have_mon, have_mday; #ifdef _NL_CURRENT const char *rp_backup; size_t num_eras; struct era_entry *era; era = NULL; #endif have_I = is_pm = 0; century = -1; want_century = 0; want_era = 0; have_wday = want_xday = have_yday = have_mon = have_mday = 0; while (*fmt != '\0') { /* A white space in the format string matches 0 more or white space in the input string. */ if (isspace (*fmt)) { while (isspace (*rp)) ++rp; ++fmt; continue; } /* Any character but `%' must be matched by the same character in the iput string. */ if (*fmt != '%') { match_char (*fmt++, *rp++); continue; } ++fmt; #ifndef _NL_CURRENT /* We need this for handling the `E' modifier. */ start_over: #endif #ifdef _NL_CURRENT /* Make back up of current processing pointer. */ rp_backup = rp; #endif switch (*fmt++) { case '%': /* Match the `%' character itself. */ match_char ('%', *rp++); break; case 'a': case 'A': /* Match day of week. */ for (cnt = 0; cnt < 7; ++cnt) { #ifdef _NL_CURRENT if (*decided !=raw) { if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) { if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), weekday_name[cnt])) *decided = loc; break; } if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) { if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), ab_weekday_name[cnt])) *decided = loc; break; } } #endif if (*decided != loc && (match_string (weekday_name[cnt], rp) || match_string (ab_weekday_name[cnt], rp))) { *decided = raw; break; } } if (cnt == 7) /* Does not match a weekday name. */ return NULL; tm->tm_wday = cnt; have_wday = 1; break; case 'b': case 'B': case 'h': /* Match month name. */ for (cnt = 0; cnt < 12; ++cnt) { #ifdef _NL_CURRENT if (*decided !=raw) { if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) { if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), month_name[cnt])) *decided = loc; break; } if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) { if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), ab_month_name[cnt])) *decided = loc; break; } } #endif if (match_string (month_name[cnt], rp) || match_string (ab_month_name[cnt], rp)) { *decided = raw; break; } } if (cnt == 12) /* Does not match a month name. */ return NULL; tm->tm_mon = cnt; want_xday = 1; break; case 'c': /* Match locale's date and time format. */ #ifdef _NL_CURRENT if (*decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) { if (*decided == loc) return NULL; else rp = rp_backup; } else { if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) *decided = loc; want_xday = 1; break; } *decided = raw; } #endif if (!recursive (HERE_D_T_FMT)) return NULL; want_xday = 1; break; case 'C': /* Match century number. */ #ifdef _NL_CURRENT match_century: #endif get_number (0, 99, 2); century = val; want_xday = 1; break; case 'd': case 'e': /* Match day of month. */ get_number (1, 31, 2); tm->tm_mday = val; have_mday = 1; want_xday = 1; break; case 'F': if (!recursive ("%Y-%m-%d")) return NULL; want_xday = 1; break; case 'x': #ifdef _NL_CURRENT if (*decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) { if (*decided == loc) return NULL; else rp = rp_backup; } else { if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) *decided = loc; want_xday = 1; break; } *decided = raw; } #endif FALL_THROUGH; case 'D': /* Match standard day format. */ if (!recursive (HERE_D_FMT)) return NULL; want_xday = 1; break; case 'k': case 'H': /* Match hour in 24-hour clock. */ get_number (0, 23, 2); tm->tm_hour = val; have_I = 0; break; case 'I': /* Match hour in 12-hour clock. */ get_number (1, 12, 2); tm->tm_hour = val % 12; have_I = 1; break; case 'j': /* Match day number of year. */ get_number (1, 366, 3); tm->tm_yday = val - 1; have_yday = 1; break; case 'm': /* Match number of month. */ get_number (1, 12, 2); tm->tm_mon = val - 1; have_mon = 1; want_xday = 1; break; case 'M': /* Match minute. */ get_number (0, 59, 2); tm->tm_min = val; break; case 'n': case 't': /* Match any white space. */ while (isspace (*rp)) ++rp; break; case 'p': /* Match locale's equivalent of AM/PM. */ #ifdef _NL_CURRENT if (*decided != raw) { if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) { if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) *decided = loc; break; } if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) { if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) *decided = loc; is_pm = 1; break; } *decided = raw; } #endif if (!match_string (HERE_AM_STR, rp)) { if (match_string (HERE_PM_STR, rp)) { is_pm = 1; } else { return NULL; } } break; case 'r': #ifdef _NL_CURRENT if (*decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) { if (*decided == loc) return NULL; else rp = rp_backup; } else { if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), HERE_T_FMT_AMPM)) *decided = loc; break; } *decided = raw; } #endif if (!recursive (HERE_T_FMT_AMPM)) return NULL; break; case 'R': if (!recursive ("%H:%M")) return NULL; break; case 's': { /* The number of seconds may be very high so we cannot use the `get_number' macro. Instead read the number character for character and construct the result while doing this. */ time_t secs = 0; if (*rp < '0' || *rp > '9') /* We need at least one digit. */ return NULL; do { secs *= 10; secs += *rp++ - '0'; } while (*rp >= '0' && *rp <= '9'); if (localtime_r (&secs, tm) == NULL) /* Error in function. */ return NULL; } break; case 'S': get_number (0, 61, 2); tm->tm_sec = val; break; case 'X': #ifdef _NL_CURRENT if (*decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) { if (*decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) *decided = loc; break; } *decided = raw; } #endif FALL_THROUGH; case 'T': if (!recursive (HERE_T_FMT)) return NULL; break; case 'u': get_number (1, 7, 1); tm->tm_wday = val % 7; have_wday = 1; break; case 'g': get_number (0, 99, 2); /* XXX This cannot determine any field in TM. */ break; case 'G': if (*rp < '0' || *rp > '9') return NULL; /* XXX Ignore the number since we would need some more information to compute a real date. */ do ++rp; while (*rp >= '0' && *rp <= '9'); break; case 'U': case 'V': case 'W': get_number (0, 53, 2); /* XXX This cannot determine any field in TM without some information. */ break; case 'w': /* Match number of weekday. */ get_number (0, 6, 1); tm->tm_wday = val; have_wday = 1; break; case 'y': #ifdef _NL_CURRENT match_year_in_century: #endif /* Match year within century. */ get_number (0, 99, 2); /* The "Year 2000: The Millennium Rollover" paper suggests that values in the range 69-99 refer to the twentieth century. */ tm->tm_year = val >= 69 ? val : val + 100; /* Indicate that we want to use the century, if specified. */ want_century = 1; want_xday = 1; break; case 'Y': /* Match year including century number. */ get_number (0, 9999, 4); tm->tm_year = val - 1900; want_century = 0; want_xday = 1; break; case 'Z': /* XXX How to handle this? */ break; case 'E': #ifdef _NL_CURRENT switch (*fmt++) { case 'c': /* Match locale's alternate date and time format. */ if (*decided != raw) { const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); if (*fmt == '\0') fmt = _NL_CURRENT (LC_TIME, D_T_FMT); if (!recursive (fmt)) { if (*decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (fmt, HERE_D_T_FMT)) *decided = loc; want_xday = 1; break; } *decided = raw; } /* The C locale has no era information, so use the normal representation. */ if (!recursive (HERE_D_T_FMT)) return NULL; want_xday = 1; break; case 'C': if (*decided != raw) { if (era_cnt >= 0) { era = _nl_select_era_entry (era_cnt); if (match_string (era->era_name, rp)) { *decided = loc; break; } else return NULL; } else { num_eras = _NL_CURRENT_WORD (LC_TIME, _NL_TIME_ERA_NUM_ENTRIES); for (era_cnt = 0; era_cnt < (int) num_eras; ++era_cnt, rp = rp_backup) { era = _nl_select_era_entry (era_cnt); if (match_string (era->era_name, rp)) { *decided = loc; break; } } if (era_cnt == (int) num_eras) { era_cnt = -1; if (*decided == loc) return NULL; } else break; } *decided = raw; } /* The C locale has no era information, so use the normal representation. */ goto match_century; case 'y': if (*decided == raw) goto match_year_in_century; get_number(0, 9999, 4); tm->tm_year = val; want_era = 1; want_xday = 1; break; case 'Y': if (*decided != raw) { num_eras = _NL_CURRENT_WORD (LC_TIME, _NL_TIME_ERA_NUM_ENTRIES); for (era_cnt = 0; era_cnt < (int) num_eras; ++era_cnt, rp = rp_backup) { era = _nl_select_era_entry (era_cnt); if (recursive (era->era_format)) break; } if (era_cnt == (int) num_eras) { era_cnt = -1; if (*decided == loc) return NULL; else rp = rp_backup; } else { *decided = loc; era_cnt = -1; break; } *decided = raw; } get_number (0, 9999, 4); tm->tm_year = val - 1900; want_century = 0; want_xday = 1; break; case 'x': if (*decided != raw) { const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); if (*fmt == '\0') fmt = _NL_CURRENT (LC_TIME, D_FMT); if (!recursive (fmt)) { if (*decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (fmt, HERE_D_FMT)) *decided = loc; break; } *decided = raw; } if (!recursive (HERE_D_FMT)) return NULL; break; case 'X': if (*decided != raw) { const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); if (*fmt == '\0') fmt = _NL_CURRENT (LC_TIME, T_FMT); if (!recursive (fmt)) { if (*decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (fmt, HERE_T_FMT)) *decided = loc; break; } *decided = raw; } if (!recursive (HERE_T_FMT)) return NULL; break; default: return NULL; } break; #else /* We have no information about the era format. Just use the normal format. */ if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' && *fmt != 'x' && *fmt != 'X') /* This is an illegal format. */ return NULL; goto start_over; #endif case 'O': switch (*fmt++) { case 'd': case 'e': /* Match day of month using alternate numeric symbols. */ get_alt_number (1, 31, 2); tm->tm_mday = val; have_mday = 1; want_xday = 1; break; case 'H': /* Match hour in 24-hour clock using alternate numeric symbols. */ get_alt_number (0, 23, 2); tm->tm_hour = val; have_I = 0; break; case 'I': /* Match hour in 12-hour clock using alternate numeric symbols. */ get_alt_number (1, 12, 2); tm->tm_hour = val - 1; have_I = 1; break; case 'm': /* Match month using alternate numeric symbols. */ get_alt_number (1, 12, 2); tm->tm_mon = val - 1; have_mon = 1; want_xday = 1; break; case 'M': /* Match minutes using alternate numeric symbols. */ get_alt_number (0, 59, 2); tm->tm_min = val; break; case 'S': /* Match seconds using alternate numeric symbols. */ get_alt_number (0, 61, 2); tm->tm_sec = val; break; case 'U': case 'V': case 'W': get_alt_number (0, 53, 2); /* XXX This cannot determine any field in TM without further information. */ break; case 'w': /* Match number of weekday using alternate numeric symbols. */ get_alt_number (0, 6, 1); tm->tm_wday = val; have_wday = 1; break; case 'y': /* Match year within century using alternate numeric symbols. */ get_alt_number (0, 99, 2); tm->tm_year = val >= 69 ? val : val + 100; want_xday = 1; break; default: return NULL; } break; default: return NULL; } } if (have_I && is_pm) tm->tm_hour += 12; if (century != -1) { if (want_century) tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; else /* Only the century, but not the year. Strange, but so be it. */ tm->tm_year = (century - 19) * 100; } #ifdef _NL_CURRENT if (era_cnt != -1) { era = _nl_select_era_entry(era_cnt); if (want_era) tm->tm_year = (era->start_date[0] + ((tm->tm_year - era->offset) * era->absolute_direction)); else /* Era start year assumed. */ tm->tm_year = era->start_date[0]; } else #endif if (want_era) return NULL; if (want_xday && !have_wday) { if ( !(have_mon && have_mday) && have_yday) { /* We don't have tm_mon and/or tm_mday, compute them. */ int t_mon = 0; while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) t_mon++; if (!have_mon) tm->tm_mon = t_mon - 1; if (!have_mday) tm->tm_mday = (tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); } day_of_the_week (tm); } if (want_xday && !have_yday) day_of_the_year (tm); return discard_const_p(char, rp); } char *rep_strptime(const char *buf, const char *format, struct tm *tm) { enum locale_status decided; #ifdef _NL_CURRENT decided = not; #else decided = raw; #endif return strptime_internal (buf, format, tm, &decided, -1); } ldb-2.0.8/lib/replace/system/README0000660000000000000000000000036212406075657016620 0ustar rootroot00000000000000This directory contains wrappers around logical groups of system include files. The idea is to avoid #ifdef blocks in the main code, and instead put all the necessary conditional includes in subsystem specific header files in this directory. ldb-2.0.8/lib/replace/system/aio.h0000660000000000000000000000201412406075657016655 0ustar rootroot00000000000000#ifndef _system_aio_h #define _system_aio_h /* Unix SMB/CIFS implementation. AIO system include wrappers Copyright (C) Andrew Tridgell 2006 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_LIBAIO_H #include #endif #endif ldb-2.0.8/lib/replace/system/capability.h0000660000000000000000000000322613573675413020236 0ustar rootroot00000000000000#ifndef _system_capability_h #define _system_capability_h /* Unix SMB/CIFS implementation. capability system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_SYS_CAPABILITY_H #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) #define _I386_STATFS_H #define _PPC_STATFS_H #define BROKEN_REDHAT_7_STATFS_WORKAROUND #endif #if defined(BROKEN_RHEL5_SYS_CAP_HEADER) && !defined(_LINUX_TYPES_H) #define BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND #endif #ifdef HAVE_POSIX_CAPABILITIES #include #endif #ifdef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND #undef _LINUX_TYPES_H #undef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND #endif #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND #undef _PPC_STATFS_H #undef _I386_STATFS_H #undef BROKEN_REDHAT_7_STATFS_WORKAROUND #endif #endif #endif ldb-2.0.8/lib/replace/system/dir.h0000660000000000000000000000352513573675413016675 0ustar rootroot00000000000000#ifndef _system_dir_h #define _system_dir_h /* Unix SMB/CIFS implementation. directory system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif #ifndef HAVE_MKDIR_MODE #define mkdir(dir, mode) mkdir(dir) #endif #ifdef HAVE_LIBGEN_H # include #endif /* Test whether a file name is the "." or ".." directory entries. * These really should be inline functions. */ #ifndef ISDOT #define ISDOT(path) ( \ *((const char *)(path)) == '.' && \ *(((const char *)(path)) + 1) == '\0' \ ) #endif #ifndef ISDOTDOT #define ISDOTDOT(path) ( \ *((const char *)(path)) == '.' && \ *(((const char *)(path)) + 1) == '.' && \ *(((const char *)(path)) + 2) == '\0' \ ) #endif #endif ldb-2.0.8/lib/replace/system/filesys.h0000660000000000000000000001360313573675413017573 0ustar rootroot00000000000000#ifndef _system_filesys_h #define _system_filesys_h /* Unix SMB/CIFS implementation. filesystem system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_UNISTD_H #include #endif #include #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_MNTENT_H #include #endif #ifdef HAVE_SYS_VFS_H #include #endif #ifdef HAVE_SYS_ACL_H #include #endif #ifdef HAVE_ACL_LIBACL_H #include #endif #ifdef HAVE_SYS_FS_S5PARAM_H #include #endif #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) #include #endif #ifdef HAVE_SYS_STATFS_H # include #endif #ifdef HAVE_DUSTAT_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif #ifdef HAVE_SYS_FILIO_H #include #endif #ifdef HAVE_SYS_FILE_H #include #endif #ifdef HAVE_FCNTL_H #include #else #ifdef HAVE_SYS_FCNTL_H #include #endif #endif #ifdef HAVE_SYS_MODE_H /* apparently AIX needs this for S_ISLNK */ #ifndef S_ISLNK #include #endif #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_SYS_UIO_H #include #endif #if defined(HAVE_SYS_ATTRIBUTES_H) #include #elif defined(HAVE_ATTR_ATTRIBUTES_H) #include #endif /* mutually exclusive (SuSE 8.2) */ #if defined(HAVE_ATTR_XATTR_H) #include #elif defined(HAVE_SYS_XATTR_H) #include #endif #ifdef HAVE_SYS_EA_H #include #endif #ifdef HAVE_SYS_EXTATTR_H #include #endif #ifdef HAVE_SYS_RESOURCE_H #include #endif #ifndef XATTR_CREATE #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ #endif #ifndef XATTR_REPLACE #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ #endif /* Some POSIX definitions for those without */ #ifndef S_IFDIR #define S_IFDIR 0x4000 #endif #ifndef S_ISDIR #define S_ISDIR(mode) ((mode & 0xF000) == S_IFDIR) #endif #ifndef S_IRWXU #define S_IRWXU 00700 /* read, write, execute: owner */ #endif #ifndef S_IRUSR #define S_IRUSR 00400 /* read permission: owner */ #endif #ifndef S_IWUSR #define S_IWUSR 00200 /* write permission: owner */ #endif #ifndef S_IXUSR #define S_IXUSR 00100 /* execute permission: owner */ #endif #ifndef S_IRWXG #define S_IRWXG 00070 /* read, write, execute: group */ #endif #ifndef S_IRGRP #define S_IRGRP 00040 /* read permission: group */ #endif #ifndef S_IWGRP #define S_IWGRP 00020 /* write permission: group */ #endif #ifndef S_IXGRP #define S_IXGRP 00010 /* execute permission: group */ #endif #ifndef S_IRWXO #define S_IRWXO 00007 /* read, write, execute: other */ #endif #ifndef S_IROTH #define S_IROTH 00004 /* read permission: other */ #endif #ifndef S_IWOTH #define S_IWOTH 00002 /* write permission: other */ #endif #ifndef S_IXOTH #define S_IXOTH 00001 /* execute permission: other */ #endif #ifndef O_ACCMODE #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) #endif #ifndef MAXPATHLEN #define MAXPATHLEN 256 #endif #ifndef SEEK_SET #define SEEK_SET 0 #endif #ifdef _WIN32 #define mkdir(d,m) _mkdir(d) #endif /* this allows us to use a uniform error handling for our xattr wrappers */ #ifndef ENOATTR #define ENOATTR ENODATA #endif #if !defined(HAVE_XATTR_XATTR) || defined(XATTR_ADDITIONAL_OPTIONS) ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size); #define getxattr(path, name, value, size) rep_getxattr(path, name, value, size) /* define is in "replace.h" */ ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size); #define fgetxattr(filedes, name, value, size) rep_fgetxattr(filedes, name, value, size) /* define is in "replace.h" */ ssize_t rep_listxattr (const char *path, char *list, size_t size); #define listxattr(path, list, size) rep_listxattr(path, list, size) /* define is in "replace.h" */ ssize_t rep_flistxattr (int filedes, char *list, size_t size); #define flistxattr(filedes, value, size) rep_flistxattr(filedes, value, size) /* define is in "replace.h" */ int rep_removexattr (const char *path, const char *name); #define removexattr(path, name) rep_removexattr(path, name) /* define is in "replace.h" */ int rep_fremovexattr (int filedes, const char *name); #define fremovexattr(filedes, name) rep_fremovexattr(filedes, name) /* define is in "replace.h" */ int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags); #define setxattr(path, name, value, size, flags) rep_setxattr(path, name, value, size, flags) /* define is in "replace.h" */ int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags); #define fsetxattr(filedes, name, value, size, flags) rep_fsetxattr(filedes, name, value, size, flags) /* define is in "replace.h" */ #endif /* !defined(HAVE_XATTR_XATTR) || defined(XATTR_ADDITIONAL_OPTIONS) */ #endif ldb-2.0.8/lib/replace/system/glob.h0000660000000000000000000000207712406075657017041 0ustar rootroot00000000000000#ifndef _system_glob_h #define _system_glob_h /* Unix SMB/CIFS implementation. glob system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_GLOB_H #include #endif #ifdef HAVE_FNMATCH_H #include #endif #endif ldb-2.0.8/lib/replace/system/gssapi.h0000660000000000000000000000272513573675413017406 0ustar rootroot00000000000000#ifndef _system_gssapi_h #define _system_gssapi_h /* Unix SMB/CIFS implementation. GSSAPI system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_GSSAPI #ifdef HAVE_GSSAPI_GSSAPI_EXT_H #include #elif defined(HAVE_GSSAPI_GSSAPI_H) #include #elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) #include #elif defined(HAVE_GSSAPI_H) #include #endif #ifdef HAVE_GSSAPI_GSSAPI_KRB5_H #include #endif #ifdef HAVE_GSSAPI_GSSAPI_SPNEGO_H #include #elif defined(HAVE_GSSAPI_SPNEGO_H) #include #endif #endif #endif ldb-2.0.8/lib/replace/system/iconv.h0000660000000000000000000000304612406075657017231 0ustar rootroot00000000000000#ifndef _system_iconv_h #define _system_iconv_h /* Unix SMB/CIFS implementation. iconv memory system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #if !defined(HAVE_ICONV) && defined(HAVE_ICONV_H) #define HAVE_ICONV #endif #if !defined(HAVE_GICONV) && defined(HAVE_GICONV_H) #define HAVE_GICONV #endif #if !defined(HAVE_BICONV) && defined(HAVE_BICONV_H) #define HAVE_BICONV #endif #ifdef HAVE_NATIVE_ICONV #if defined(HAVE_ICONV) #include #elif defined(HAVE_GICONV) #include #elif defined(HAVE_BICONV) #include #endif #endif /* HAVE_NATIVE_ICONV */ /* needed for some systems without iconv. Doesn't really matter what error code we use */ #ifndef EILSEQ #define EILSEQ EIO #endif #endif ldb-2.0.8/lib/replace/system/kerberos.h0000660000000000000000000000213713573675413017731 0ustar rootroot00000000000000#ifndef _system_kerberos_h #define _system_kerberos_h /* Unix SMB/CIFS implementation. kerberos system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_KRB5 #ifdef HAVE_KRB5_H #include #endif #ifdef HAVE_COM_ERR_H #include #endif #endif #endif ldb-2.0.8/lib/replace/system/locale.h0000660000000000000000000000216412406075657017352 0ustar rootroot00000000000000#ifndef _system_locale_h #define _system_locale_h /* Unix SMB/CIFS implementation. locale include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_CTYPE_H #include #endif #ifdef HAVE_LOCALE_H #include #endif #ifdef HAVE_LANGINFO_H #include #endif #endif ldb-2.0.8/lib/replace/system/network.h0000660000000000000000000001722113055076237017600 0ustar rootroot00000000000000#ifndef _system_network_h #define _system_network_h /* Unix SMB/CIFS implementation. networking system include wrappers Copyright (C) Andrew Tridgell 2004 Copyright (C) Jelmer Vernooij 2007 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifndef LIBREPLACE_NETWORK_CHECKS #error "AC_LIBREPLACE_NETWORK_CHECKS missing in configure" #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_UNIXSOCKET #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_NETINET_TCP_H #include #endif /* * The next three defines are needed to access the IPTOS_* options * on some systems. */ #ifdef HAVE_NETINET_IN_SYSTM_H #include #endif #ifdef HAVE_NETINET_IN_IP_H #include #endif #ifdef HAVE_NETINET_IP_H #include #endif #ifdef HAVE_NET_IF_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_SYS_UIO_H #include #endif #ifdef HAVE_STROPTS_H #include #endif #ifndef HAVE_SOCKLEN_T #define HAVE_SOCKLEN_T typedef int socklen_t; #endif #if !defined (HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) /* define is in "replace.h" */ char *rep_inet_ntoa(struct in_addr ip); #endif #ifndef HAVE_INET_PTON /* define is in "replace.h" */ int rep_inet_pton(int af, const char *src, void *dst); #endif #ifndef HAVE_INET_NTOP /* define is in "replace.h" */ const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif #ifndef HAVE_INET_ATON /* define is in "replace.h" */ int rep_inet_aton(const char *src, struct in_addr *dst); #endif #ifndef HAVE_CONNECT /* define is in "replace.h" */ int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); #endif #ifndef HAVE_GETHOSTBYNAME /* define is in "replace.h" */ struct hostent *rep_gethostbyname(const char *name); #endif #ifdef HAVE_IFADDRS_H #include #endif #ifndef HAVE_STRUCT_IFADDRS struct ifaddrs { struct ifaddrs *ifa_next; /* Pointer to next struct */ char *ifa_name; /* Interface name */ unsigned int ifa_flags; /* Interface flags */ struct sockaddr *ifa_addr; /* Interface address */ struct sockaddr *ifa_netmask; /* Interface netmask */ #undef ifa_dstaddr struct sockaddr *ifa_dstaddr; /* P2P interface destination */ void *ifa_data; /* Address specific data */ }; #endif #ifndef HAVE_GETIFADDRS int rep_getifaddrs(struct ifaddrs **); #endif #ifndef HAVE_FREEIFADDRS void rep_freeifaddrs(struct ifaddrs *); #endif #ifndef HAVE_SOCKETPAIR /* define is in "replace.h" */ int rep_socketpair(int d, int type, int protocol, int sv[2]); #endif /* * Some systems have getaddrinfo but not the * defines needed to use it. */ /* Various macros that ought to be in , but might not be */ #ifndef EAI_FAIL #define EAI_BADFLAGS (-1) #define EAI_NONAME (-2) #define EAI_AGAIN (-3) #define EAI_FAIL (-4) #define EAI_FAMILY (-6) #define EAI_SOCKTYPE (-7) #define EAI_SERVICE (-8) #define EAI_MEMORY (-10) #define EAI_SYSTEM (-11) #endif /* !EAI_FAIL */ #ifndef AI_PASSIVE #define AI_PASSIVE 0x0001 #endif #ifndef AI_CANONNAME #define AI_CANONNAME 0x0002 #endif #ifndef AI_NUMERICHOST /* * some platforms don't support AI_NUMERICHOST; define as zero if using * the system version of getaddrinfo... */ #if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) #define AI_NUMERICHOST 0 #else #define AI_NUMERICHOST 0x0004 #endif #endif /* * Some of the functions in source3/lib/util_sock.c use AI_ADDRCONFIG. On QNX * 6.3.0, this macro is defined but, if it's used, getaddrinfo will fail. This * prevents smbd from opening any sockets. * * If I undefine AI_ADDRCONFIG on such systems and define it to be 0, * this works around the issue. */ #ifdef __QNX__ #include #if _NTO_VERSION == 630 #undef AI_ADDRCONFIG #endif #endif #ifndef AI_ADDRCONFIG /* * logic copied from AI_NUMERICHOST */ #if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) #define AI_ADDRCONFIG 0 #else #define AI_ADDRCONFIG 0x0020 #endif #endif #ifndef AI_NUMERICSERV /* * logic copied from AI_NUMERICHOST */ #if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) #define AI_NUMERICSERV 0 #else #define AI_NUMERICSERV 0x0400 #endif #endif #ifndef NI_NUMERICHOST #define NI_NUMERICHOST 1 #endif #ifndef NI_NUMERICSERV #define NI_NUMERICSERV 2 #endif #ifndef NI_NOFQDN #define NI_NOFQDN 4 #endif #ifndef NI_NAMEREQD #define NI_NAMEREQD 8 #endif #ifndef NI_DGRAM #define NI_DGRAM 16 #endif #ifndef NI_MAXHOST #define NI_MAXHOST 1025 #endif #ifndef NI_MAXSERV #define NI_MAXSERV 32 #endif /* * glibc on linux doesn't seem to have MSG_WAITALL * defined. I think the kernel has it though.. */ #ifndef MSG_WAITALL #define MSG_WAITALL 0 #endif #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif #ifndef EAFNOSUPPORT #define EAFNOSUPPORT EINVAL #endif #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 #endif #ifndef INET6_ADDRSTRLEN #define INET6_ADDRSTRLEN 46 #endif #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 255 #endif #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN HOST_NAME_MAX #endif #ifndef HAVE_SA_FAMILY_T #define HAVE_SA_FAMILY_T typedef unsigned short int sa_family_t; #endif #ifndef HAVE_STRUCT_SOCKADDR_STORAGE #define HAVE_STRUCT_SOCKADDR_STORAGE #ifdef HAVE_STRUCT_SOCKADDR_IN6 #define sockaddr_storage sockaddr_in6 #define ss_family sin6_family #define HAVE_SS_FAMILY 1 #else /*HAVE_STRUCT_SOCKADDR_IN6*/ #define sockaddr_storage sockaddr_in #define ss_family sin_family #define HAVE_SS_FAMILY 1 #endif /*HAVE_STRUCT_SOCKADDR_IN6*/ #endif /*HAVE_STRUCT_SOCKADDR_STORAGE*/ #ifndef HAVE_SS_FAMILY #ifdef HAVE___SS_FAMILY #define ss_family __ss_family #define HAVE_SS_FAMILY 1 #endif #endif #ifndef IOV_MAX # ifdef UIO_MAXIOV # define IOV_MAX UIO_MAXIOV # else # ifdef __sgi /* * IRIX 6.5 has sysconf(_SC_IOV_MAX) * which might return 512 or bigger */ # define IOV_MAX 512 # endif # endif #endif #ifndef HAVE_STRUCT_ADDRINFO #define HAVE_STRUCT_ADDRINFO struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }; #endif /* HAVE_STRUCT_ADDRINFO */ #if !defined(HAVE_GETADDRINFO) #include "getaddrinfo.h" #endif /* Needed for some systems that don't define it (Solaris). */ #ifndef ifr_netmask #define ifr_netmask ifr_addr #endif /* Some old Linux systems have broken header files */ #ifdef HAVE_IPV6 #ifdef HAVE_LINUX_IPV6_V6ONLY_26 #define IPV6_V6ONLY 26 #endif /* HAVE_LINUX_IPV6_V6ONLY_26 */ #endif /* HAVE_IPV6 */ #ifndef SCOPE_DELIMITER #define SCOPE_DELIMITER '%' #endif #endif ldb-2.0.8/lib/replace/system/nis.h0000660000000000000000000000303513573675413016704 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. nis system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifndef _nis_passwd_h #define _nis_passwd_h #if defined(HAVE_RPC_RPC_H) /* * Check for AUTH_ERROR define conflict with rpc/rpc.h in prot.h. */ #if defined(HAVE_SYS_SECURITY_H) && defined(HAVE_RPC_AUTH_ERROR_CONFLICT) #undef AUTH_ERROR #endif /* HAVE_SYS_SECURITY_H && HAVE_RPC_AUTH_ERROR_CONFLICT */ #include #endif /* HAVE_RPC_RPC_H */ #if defined (HAVE_NETGROUP) #if defined(HAVE_RPCSVC_YP_PROT_H) #include #endif /* HAVE_RPCSVC_YP_PROT_H */ #if defined(HAVE_RPCSVC_YPCLNT_H) #include #endif /* HAVE_RPCSVC_YPCLNT_H */ #endif /* HAVE_NETGROUP */ #endif /* _nis_passwd_h */ ldb-2.0.8/lib/replace/system/passwd.h0000660000000000000000000000404212412743715017403 0ustar rootroot00000000000000#ifndef _system_passwd_h #define _system_passwd_h /* Unix SMB/CIFS implementation. passwd system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_PWD_H #include #endif #ifdef HAVE_GRP_H #include #endif #ifdef HAVE_SYS_PRIV_H #include #endif #ifdef HAVE_SYS_ID_H #include #endif #ifdef HAVE_CRYPT_H #include #endif #ifdef HAVE_SHADOW_H #include #endif #ifdef HAVE_SYS_SECURITY_H #include #include #define PASSWORD_LENGTH 16 #endif /* HAVE_SYS_SECURITY_H */ #ifdef HAVE_GETPWANAM #include #include #include #endif #ifdef HAVE_COMPAT_H #include #endif #ifndef NGROUPS_MAX #define NGROUPS_MAX 32 /* Guess... */ #endif /* what is the longest significant password available on your system? Knowing this speeds up password searches a lot */ #ifndef PASSWORD_LENGTH #define PASSWORD_LENGTH 8 #endif #ifndef ALLOW_CHANGE_PASSWORD #if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID)) #define ALLOW_CHANGE_PASSWORD 1 #endif #endif #if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID) #define ULTRIX_AUTH 1 #endif #endif ldb-2.0.8/lib/replace/system/readline.h0000660000000000000000000000335013573675413017676 0ustar rootroot00000000000000#ifndef _system_readline_h #define _system_readline_h /* Unix SMB/CIFS implementation. Readline wrappers ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_LIBREADLINE # ifdef HAVE_READLINE_READLINE_H # ifdef HAVE_READLINE_READLINE_WORKAROUND # define _FUNCTION_DEF # endif # include # ifdef HAVE_READLINE_HISTORY_H # include # endif # else # ifdef HAVE_READLINE_H # include # ifdef HAVE_HISTORY_H # include # endif # else # undef HAVE_LIBREADLINE # endif # endif #endif #ifdef HAVE_NEW_LIBREADLINE #ifdef HAVE_CPPFUNCTION # define RL_COMPLETION_CAST (CPPFunction *) #elif defined(HAVE_RL_COMPLETION_T) # define RL_COMPLETION_CAST (rl_completion_t *) #else # define RL_COMPLETION_CAST #endif #else /* This type is missing from libreadline<4.0 (approximately) */ # define RL_COMPLETION_CAST #endif /* HAVE_NEW_LIBREADLINE */ #endif ldb-2.0.8/lib/replace/system/select.h0000660000000000000000000000462212474026560017365 0ustar rootroot00000000000000#ifndef _system_select_h #define _system_select_h /* Unix SMB/CIFS implementation. select system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_EPOLL_H #include #endif #ifdef HAVE_SOLARIS_PORTS #include #endif #ifndef SELECT_CAST #define SELECT_CAST #endif #ifdef HAVE_POLL #include #else /* Type used for the number of file descriptors. */ typedef unsigned long int nfds_t; /* Data structure describing a polling request. */ struct pollfd { int fd; /* File descriptor to poll. */ short int events; /* Types of events poller cares about. */ short int revents; /* Types of events that actually occurred. */ }; /* Event types that can be polled for. These bits may be set in `events' to indicate the interesting event types; they will appear in `revents' to indicate the status of the file descriptor. */ #define POLLIN 0x001 /* There is data to read. */ #define POLLPRI 0x002 /* There is urgent data to read. */ #define POLLOUT 0x004 /* Writing now will not block. */ #define POLLRDNORM 0x040 /* Normal data may be read. */ #define POLLRDBAND 0x080 /* Priority data may be read. */ #define POLLWRNORM 0x100 /* Writing now will not block. */ #define POLLWRBAND 0x200 /* Priority data may be written. */ #define POLLERR 0x008 /* Error condition. */ #define POLLHUP 0x010 /* Hung up. */ #define POLLNVAL 0x020 /* Invalid polling request. */ /* define is in "replace.h" */ int rep_poll(struct pollfd *fds, nfds_t nfds, int timeout); #endif #endif ldb-2.0.8/lib/replace/system/shmem.h0000660000000000000000000000262512406075657017226 0ustar rootroot00000000000000#ifndef _system_shmem_h #define _system_shmem_h /* Unix SMB/CIFS implementation. shared memory system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #if defined(HAVE_SYS_IPC_H) #include #endif /* HAVE_SYS_IPC_H */ #if defined(HAVE_SYS_SHM_H) #include #endif /* HAVE_SYS_SHM_H */ #ifdef HAVE_SYS_MMAN_H #include #endif /* NetBSD doesn't have these */ #ifndef SHM_R #define SHM_R 0400 #endif #ifndef SHM_W #define SHM_W 0200 #endif #ifndef MAP_FILE #define MAP_FILE 0 #endif #ifndef MAP_FAILED #define MAP_FAILED ((void *)-1) #endif #endif ldb-2.0.8/lib/replace/system/syslog.h0000660000000000000000000000343512406075657017435 0ustar rootroot00000000000000#ifndef _system_syslog_h #define _system_syslog_h /* Unix SMB/CIFS implementation. syslog system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_SYSLOG_H #include #else #ifdef HAVE_SYS_SYSLOG_H #include #endif #endif /* For sys_adminlog(). */ #ifndef LOG_EMERG #define LOG_EMERG 0 /* system is unusable */ #endif #ifndef LOG_ALERT #define LOG_ALERT 1 /* action must be taken immediately */ #endif #ifndef LOG_CRIT #define LOG_CRIT 2 /* critical conditions */ #endif #ifndef LOG_ERR #define LOG_ERR 3 /* error conditions */ #endif #ifndef LOG_WARNING #define LOG_WARNING 4 /* warning conditions */ #endif #ifndef LOG_NOTICE #define LOG_NOTICE 5 /* normal but significant condition */ #endif #ifndef LOG_INFO #define LOG_INFO 6 /* informational */ #endif #ifndef LOG_DEBUG #define LOG_DEBUG 7 /* debug-level messages */ #endif #endif ldb-2.0.8/lib/replace/system/terminal.h0000660000000000000000000000262512406075657017730 0ustar rootroot00000000000000#ifndef _system_terminal_h #define _system_terminal_h /* Unix SMB/CIFS implementation. terminal system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef SUNOS4 /* on SUNOS4 termios.h conflicts with sys/ioctl.h */ #undef HAVE_TERMIOS_H #endif #if defined(HAVE_TERMIOS_H) /* POSIX terminal handling. */ #include #elif defined(HAVE_TERMIO_H) /* Older SYSV terminal handling - don't use if we can avoid it. */ #include #elif defined(HAVE_SYS_TERMIO_H) /* Older SYSV terminal handling - don't use if we can avoid it. */ #include #endif #endif ldb-2.0.8/lib/replace/system/threads.h0000660000000000000000000000465313573675413017554 0ustar rootroot00000000000000#ifndef _system_threads_h #define _system_threads_h /* Unix SMB/CIFS implementation. macros to go along with the lib/replace/ portability layer code Copyright (C) Volker Lendecke 2012 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #include #if defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP) && \ !defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST) #define pthread_mutexattr_setrobust pthread_mutexattr_setrobust_np #endif #if defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP) && \ !defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST) #define PTHREAD_MUTEX_ROBUST PTHREAD_MUTEX_ROBUST_NP #endif #if defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP) && \ !defined(HAVE_PTHREAD_MUTEX_CONSISTENT) #define pthread_mutex_consistent pthread_mutex_consistent_np #endif #ifdef HAVE_STDATOMIC_H #include #endif #ifndef HAVE_ATOMIC_THREAD_FENCE #ifdef HAVE___ATOMIC_THREAD_FENCE #define atomic_thread_fence(__ignore_order) __atomic_thread_fence(__ATOMIC_SEQ_CST) #define HAVE_ATOMIC_THREAD_FENCE 1 #endif /* HAVE___ATOMIC_THREAD_FENCE */ #endif /* not HAVE_ATOMIC_THREAD_FENCE */ #ifndef HAVE_ATOMIC_THREAD_FENCE #ifdef HAVE___SYNC_SYNCHRONIZE #define atomic_thread_fence(__ignore_order) __sync_synchronize() #define HAVE_ATOMIC_THREAD_FENCE 1 #endif /* HAVE___SYNC_SYNCHRONIZE */ #endif /* not HAVE_ATOMIC_THREAD_FENCE */ #ifndef HAVE_ATOMIC_THREAD_FENCE #ifdef HAVE_ATOMIC_THREAD_FENCE_SUPPORT #error mismatch_error_between_configure_test_and_header #endif /* make sure the build fails if someone uses it without checking the define */ #define atomic_thread_fence(__order) \ __function__atomic_thread_fence_not_available_on_this_platform__() #endif /* not HAVE_ATOMIC_THREAD_FENCE */ #endif ldb-2.0.8/lib/replace/system/time.h0000660000000000000000000000523713120574744017050 0ustar rootroot00000000000000#ifndef _system_time_h #define _system_time_h /* Unix SMB/CIFS implementation. time system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef TIME_WITH_SYS_TIME #include #include #else #ifdef HAVE_SYS_TIME_H #include #else #include #endif #endif #ifdef HAVE_UTIME_H #include #else struct utimbuf { time_t actime; /* access time */ time_t modtime; /* modification time */ }; #endif #ifndef HAVE_STRUCT_TIMESPEC struct timespec { time_t tv_sec; /* Seconds. */ long tv_nsec; /* Nanoseconds. */ }; #endif #ifndef HAVE_MKTIME /* define is in "replace.h" */ time_t rep_mktime(struct tm *t); #endif #ifndef HAVE_TIMEGM /* define is in "replace.h" */ time_t rep_timegm(struct tm *tm); #endif #ifndef HAVE_UTIME /* define is in "replace.h" */ int rep_utime(const char *filename, const struct utimbuf *buf); #endif #ifndef HAVE_UTIMES /* define is in "replace.h" */ int rep_utimes(const char *filename, const struct timeval tv[2]); #endif #ifndef HAVE_CLOCK_GETTIME /* CLOCK_REALTIME is required by POSIX */ #define CLOCK_REALTIME 0 typedef int clockid_t; int rep_clock_gettime(clockid_t clk_id, struct timespec *tp); #endif /* make sure we have a best effort CUSTOM_CLOCK_MONOTONIC we can rely on. * * on AIX the values of CLOCK_* are cast expressions, not integer constants, * this prevents them from being compared against in a preprocessor directive. * The following ...IS_* macros can be used to check which clock is in use. */ #if defined(CLOCK_MONOTONIC) #define CUSTOM_CLOCK_MONOTONIC CLOCK_MONOTONIC #define CUSTOM_CLOCK_MONOTONIC_IS_MONOTONIC #elif defined(CLOCK_HIGHRES) #define CUSTOM_CLOCK_MONOTONIC CLOCK_HIGHRES #define CUSTOM_CLOCK_MONOTONIC_IS_HIGHRES #else #define CUSTOM_CLOCK_MONOTONIC CLOCK_REALTIME #define CUSTOM_CLOCK_MONOTONIC_IS_REALTIME #endif #endif ldb-2.0.8/lib/replace/system/wait.h0000660000000000000000000000257212702766507017062 0ustar rootroot00000000000000#ifndef _system_wait_h #define _system_wait_h /* Unix SMB/CIFS implementation. waitpid system include wrappers Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #ifdef HAVE_SYS_WAIT_H #include #endif #include #ifndef SIGCLD #define SIGCLD SIGCHLD #endif #ifdef HAVE_SETJMP_H #include #endif #ifdef HAVE_SYS_UCONTEXT_H #include #endif #if !defined(HAVE_SIG_ATOMIC_T_TYPE) typedef int sig_atomic_t; #endif #if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4) int rep_waitpid(pid_t pid,int *status,int options); #endif #endif ldb-2.0.8/lib/replace/system/wscript_configure0000660000000000000000000000156413444661620021416 0ustar rootroot00000000000000#!/usr/bin/env python # solaris varients of getXXent_r conf.CHECK_C_PROTOTYPE('getpwent_r', 'struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)', define='SOLARIS_GETPWENT_R', headers='pwd.h') conf.CHECK_C_PROTOTYPE('getgrent_r', 'struct group *getgrent_r(struct group *src, char *buf, int buflen)', define='SOLARIS_GETGRENT_R', headers='grp.h') # the irix varients conf.CHECK_C_PROTOTYPE('getpwent_r', 'struct passwd *getpwent_r(struct passwd *src, char *buf, size_t buflen)', define='SOLARIS_GETPWENT_R', headers='pwd.h') 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') ldb-2.0.8/lib/replace/tests/getifaddrs.c0000660000000000000000000000504513573675413020043 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * * libreplace getifaddrs test * * Copyright (C) Michael Adam 2008 * * ** NOTE! The following LGPL license applies to the replace * ** 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 * Library 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 . */ #ifndef AUTOCONF_TEST #include "replace.h" #include "system/network.h" #include "replace-test.h" #endif #ifdef HAVE_INET_NTOP #define rep_inet_ntop inet_ntop #endif static const char *format_sockaddr(struct sockaddr *addr, char *addrstring, socklen_t addrlen) { const char *result = NULL; if (addr->sa_family == AF_INET) { result = rep_inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, addrstring, addrlen); #ifdef HAVE_STRUCT_SOCKADDR_IN6 } else if (addr->sa_family == AF_INET6) { result = rep_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)addr)->sin6_addr, addrstring, addrlen); #endif } return result; } int getifaddrs_test(void) { struct ifaddrs *ifs = NULL; struct ifaddrs *ifs_head = NULL; int ret; ret = getifaddrs(&ifs); ifs_head = ifs; if (ret != 0) { fprintf(stderr, "getifaddrs() failed: %s\n", strerror(errno)); return 1; } while (ifs) { printf("%-10s ", ifs->ifa_name); if (ifs->ifa_addr != NULL) { char addrstring[INET6_ADDRSTRLEN]; const char *result; result = format_sockaddr(ifs->ifa_addr, addrstring, sizeof(addrstring)); if (result != NULL) { printf("IP=%s ", addrstring); } if (ifs->ifa_netmask != NULL) { result = format_sockaddr(ifs->ifa_netmask, addrstring, sizeof(addrstring)); if (result != NULL) { printf("NETMASK=%s", addrstring); } } else { printf("AF=%d ", ifs->ifa_addr->sa_family); } } else { printf(""); } printf("\n"); ifs = ifs->ifa_next; } freeifaddrs(ifs_head); return 0; } ldb-2.0.8/lib/replace/tests/incoherent_mmap.c0000660000000000000000000000345613573675413021103 0ustar rootroot00000000000000/* In OpenBSD, if you write to a file, another process doesn't see it * in its mmap. Returns with exit status 0 if that is the case, 1 if * it's coherent, and other if there's a problem. */ #include #include #include #include #include #include #include #include #include #define DATA "coherent.mmap" int main(int argc, char *argv[]) { int tochild[2], toparent[2]; int fd; volatile unsigned char *map; unsigned char *page; const char *fname = argv[1]; char c = 0; if (pipe(tochild) != 0 || pipe(toparent) != 0) err(2, "Creating pipe"); if (!fname) fname = DATA; fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0600); if (fd < 0) err(2, "opening %s", fname); unlink(fname); switch (fork()) { case -1: err(2, "Fork"); case 0: close(tochild[1]); close(toparent[0]); /* Wait for parent to create file. */ if (read(tochild[0], &c, 1) != 1) err(2, "reading from parent"); /* Alter first byte. */ pwrite(fd, &c, 1, 0); if (write(toparent[1], &c, 1) != 1) err(2, "writing to parent"); exit(0); default: close(tochild[0]); close(toparent[1]); /* Create a file and mmap it. */ page = malloc(getpagesize()); memset(page, 0x42, getpagesize()); if (write(fd, page, getpagesize()) != getpagesize()) err(2, "writing first page"); map = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (map == MAP_FAILED) err(2, "mapping file"); if (*map != 0x42) errx(2, "first byte isn't 0x42!"); /* Tell child to alter file. */ if (write(tochild[1], &c, 1) != 1) err(2, "writing to child"); if (read(toparent[0], &c, 1) != 1) err(2, "reading from child"); if (*map) errx(0, "mmap incoherent: first byte isn't 0."); exit(1); } } ldb-2.0.8/lib/replace/tests/main.c0000660000000000000000000000205013573675413016644 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. libreplace tests Copyright (C) Jelmer Vernooij 2006 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include "replace.h" #include "replace-testsuite.h" int main(void) { bool ret = torture_local_replace(NULL); if (ret) return 0; return -1; } ldb-2.0.8/lib/replace/tests/os2_delete.c0000660000000000000000000000514213573675413017752 0ustar rootroot00000000000000/* test readdir/unlink pattern that OS/2 uses tridge@samba.org July 2005 */ #include #include #include #include #include #include #include #include #include #include "replace-test.h" #define NUM_FILES 700 #define READDIR_SIZE 100 #define DELETE_SIZE 4 #define TESTDIR "test.dir" static int test_readdir_os2_delete_ret; #define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1) #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif #ifdef _WIN32 #define mkdir(d,m) _mkdir(d) #endif static void cleanup(void) { /* I'm a lazy bastard */ if (system("rm -rf " TESTDIR)) { FAILED("system"); } mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); } static void create_files(void) { int i; for (i=0;id_name); } if (i == 0) { return 0; } /* delete the first few */ for (j=0; jd_name, ".") == 0 || FAILED("match ."); de = readdir(d); strcmp(de->d_name, "..") == 0 || FAILED("match .."); while (1) { int n = os2_delete(d); if (n == 0) break; total_deleted += n; } closedir(d); fprintf(stderr, "Deleted %d files of %d\n", total_deleted, NUM_FILES); rmdir(TESTDIR) == 0 || FAILED("rmdir"); if (system("rm -rf " TESTDIR) == -1) { FAILED("system"); } return test_readdir_os2_delete_ret; } ldb-2.0.8/lib/replace/tests/shared_mmap.c0000660000000000000000000000231513573675413020204 0ustar rootroot00000000000000/* this tests whether we can use a shared writeable mmap on a file - as needed for the mmap variant of FAST_SHARE_MODES */ #if defined(HAVE_UNISTD_H) #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include #include #define DATA "conftest.mmap" #ifndef MAP_FILE #define MAP_FILE 0 #endif int main(void) { int *buf; int i; int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); int count=7; if (fd == -1) exit(1); for (i=0;i<10000;i++) { write(fd,&i,sizeof(i)); } close(fd); if (fork() == 0) { fd = open(DATA,O_RDWR); if (fd == -1) exit(1); buf = (int *)mmap(NULL, 10000*sizeof(int), (PROT_READ | PROT_WRITE), MAP_FILE | MAP_SHARED, fd, 0); while (count-- && buf[9124] != 55732) sleep(1); if (count <= 0) exit(1); buf[1763] = 7268; exit(0); } fd = open(DATA,O_RDWR); if (fd == -1) exit(1); buf = (int *)mmap(NULL, 10000*sizeof(int), (PROT_READ | PROT_WRITE), MAP_FILE | MAP_SHARED, fd, 0); if (buf == (int *)-1) exit(1); buf[9124] = 55732; while (count-- && buf[1763] != 7268) sleep(1); unlink(DATA); if (count > 0) exit(0); exit(1); } ldb-2.0.8/lib/replace/tests/shared_mremap.c0000660000000000000000000000141713573675413020535 0ustar rootroot00000000000000/* this tests whether we can use mremap */ #if defined(HAVE_UNISTD_H) #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include #include #define DATA "conftest.mmap" #ifndef MAP_FILE #define MAP_FILE 0 #endif #ifndef MAP_FAILED #define MAP_FAILED (int *)-1 #endif int main(void) { int *buf; int fd; int err = 1; fd = open(DATA, O_RDWR|O_CREAT|O_TRUNC, 0666); if (fd == -1) { exit(1); } buf = (int *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); if (buf == MAP_FAILED) { goto done; } buf = mremap(buf, 0x1000, 0x2000, MREMAP_MAYMOVE); if (buf == MAP_FAILED) { goto done; } err = 0; done: close(fd); unlink(DATA); exit(err); } ldb-2.0.8/lib/replace/tests/snprintf.c0000660000000000000000000000135513573675413017572 0ustar rootroot00000000000000void foo(const char *format, ...) { va_list ap; int len; char buf[20]; long long l = 1234567890; l *= 100; va_start(ap, format); len = vsnprintf(buf, 0, format, ap); va_end(ap); if (len != 5) exit(1); va_start(ap, format); len = vsnprintf(0, 0, format, ap); va_end(ap); if (len != 5) exit(2); if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(3); if (snprintf(buf, 20, "%lld", l) != 12 || strcmp(buf, "123456789000") != 0) exit(4); if (snprintf(buf, 20, "%zu", 123456789) != 9 || strcmp(buf, "123456789") != 0) exit(5); if (snprintf(buf, 20, "%2\$d %1\$d", 3, 4) != 3 || strcmp(buf, "4 3") != 0) exit(6); if (snprintf(buf, 20, "%s", 0) < 3) exit(7); printf("1"); exit(0); } int main(void) { foo("hello"); } ldb-2.0.8/lib/replace/tests/strptime.c0000660000000000000000000000660613573675413017602 0ustar rootroot00000000000000 #ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME #include #include #include #define true 1 #define false 0 #ifndef __STRING #define __STRING(x) #x #endif /* make printf a no-op */ #define printf if(0) printf #else /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ #include "replace.h" #include "system/time.h" #include "replace-test.h" #endif /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ int libreplace_test_strptime(void) { const char *s = "20070414101546Z"; char *ret; struct tm t, t2; memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2)); printf("test: strptime\n"); ret = strptime(s, "%Y%m%d%H%M%S", &t); if ( ret == NULL ) { printf("failure: strptime [\n" "returned NULL\n" "]\n"); return false; } if ( *ret != 'Z' ) { printf("failure: strptime [\n" "ret doesn't point to 'Z'\n" "]\n"); return false; } ret = strptime(s, "%Y%m%d%H%M%SZ", &t2); if ( ret == NULL ) { printf("failure: strptime [\n" "returned NULL with Z\n" "]\n"); return false; } if ( *ret != '\0' ) { printf("failure: strptime [\n" "ret doesn't point to '\\0'\n" "]\n"); return false; } #define CMP_TM_ELEMENT(t1,t2,elem) \ if (t1.elem != t2.elem) { \ printf("failure: strptime [\n" \ "result differs if the format string has a 'Z' at the end\n" \ "element: %s %d != %d\n" \ "]\n", \ __STRING(elen), t1.elem, t2.elem); \ return false; \ } CMP_TM_ELEMENT(t,t2,tm_sec); CMP_TM_ELEMENT(t,t2,tm_min); CMP_TM_ELEMENT(t,t2,tm_hour); CMP_TM_ELEMENT(t,t2,tm_mday); CMP_TM_ELEMENT(t,t2,tm_mon); CMP_TM_ELEMENT(t,t2,tm_year); CMP_TM_ELEMENT(t,t2,tm_wday); CMP_TM_ELEMENT(t,t2,tm_yday); CMP_TM_ELEMENT(t,t2,tm_isdst); if (t.tm_sec != 46) { printf("failure: strptime [\n" "tm_sec: expected: 46, got: %d\n" "]\n", t.tm_sec); return false; } if (t.tm_min != 15) { printf("failure: strptime [\n" "tm_min: expected: 15, got: %d\n" "]\n", t.tm_min); return false; } if (t.tm_hour != 10) { printf("failure: strptime [\n" "tm_hour: expected: 10, got: %d\n" "]\n", t.tm_hour); return false; } if (t.tm_mday != 14) { printf("failure: strptime [\n" "tm_mday: expected: 14, got: %d\n" "]\n", t.tm_mday); return false; } if (t.tm_mon != 3) { printf("failure: strptime [\n" "tm_mon: expected: 3, got: %d\n" "]\n", t.tm_mon); return false; } if (t.tm_year != 107) { printf("failure: strptime [\n" "tm_year: expected: 107, got: %d\n" "]\n", t.tm_year); return false; } if (t.tm_wday != 6) { /* saturday */ printf("failure: strptime [\n" "tm_wday: expected: 6, got: %d\n" "]\n", t.tm_wday); return false; } if (t.tm_yday != 103) { printf("failure: strptime [\n" "tm_yday: expected: 103, got: %d\n" "]\n", t.tm_yday); return false; } /* we don't test this as it depends on the host configuration if (t.tm_isdst != 0) { printf("failure: strptime [\n" "tm_isdst: expected: 0, got: %d\n" "]\n", t.tm_isdst); return false; }*/ printf("success: strptime\n"); return true; } #ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME int main (void) { int ret; ret = libreplace_test_strptime(); if (ret == false) return 1; return 0; } #endif ldb-2.0.8/lib/replace/tests/testsuite.c0000660000000000000000000007213513573675413017764 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. libreplace tests Copyright (C) Jelmer Vernooij 2006 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include "replace.h" #include "replace-test.h" #include "replace-testsuite.h" /* we include all the system/ include files here so that libreplace tests them in the build farm */ #include "system/capability.h" #include "system/dir.h" #include "system/filesys.h" #include "system/glob.h" #include "system/iconv.h" #include "system/locale.h" #include "system/network.h" #include "system/passwd.h" #include "system/readline.h" #include "system/select.h" #include "system/shmem.h" #include "system/syslog.h" #include "system/terminal.h" #include "system/time.h" #include "system/wait.h" #include "system/aio.h" #define TESTFILE "testfile.dat" /* test ftruncate() function */ static int test_ftruncate(void) { struct stat st; int fd; const int size = 1234; printf("test: ftruncate\n"); unlink(TESTFILE); fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); if (fd == -1) { printf("failure: ftruncate [\n" "creating '%s' failed - %s\n]\n", TESTFILE, strerror(errno)); return false; } if (ftruncate(fd, size) != 0) { printf("failure: ftruncate [\n%s\n]\n", strerror(errno)); close(fd); return false; } if (fstat(fd, &st) != 0) { printf("failure: ftruncate [\nfstat failed - %s\n]\n", strerror(errno)); close(fd); return false; } if (st.st_size != size) { printf("failure: ftruncate [\ngave wrong size %d - expected %d\n]\n", (int)st.st_size, size); close(fd); return false; } unlink(TESTFILE); printf("success: ftruncate\n"); close(fd); return true; } /* test strlcpy() function. see http://www.gratisoft.us/todd/papers/strlcpy.html */ static int test_strlcpy(void) { char buf[4]; const struct { const char *src; size_t result; } tests[] = { { "abc", 3 }, { "abcdef", 6 }, { "abcd", 4 }, { "", 0 }, { NULL, 0 } }; int i; printf("test: strlcpy\n"); for (i=0;tests[i].src;i++) { if (strlcpy(buf, tests[i].src, sizeof(buf)) != tests[i].result) { printf("failure: strlcpy [\ntest %d failed\n]\n", i); return false; } } printf("success: strlcpy\n"); return true; } static int test_strlcat(void) { char tmp[10]; printf("test: strlcat\n"); strlcpy(tmp, "", sizeof(tmp)); if (strlcat(tmp, "bla", 3) != 3) { printf("failure: strlcat [\ninvalid return code\n]\n"); return false; } if (strcmp(tmp, "bl") != 0) { printf("failure: strlcat [\nexpected \"bl\", got \"%s\"\n]\n", tmp); return false; } strlcpy(tmp, "da", sizeof(tmp)); if (strlcat(tmp, "me", 4) != 4) { printf("failure: strlcat [\nexpected \"dam\", got \"%s\"\n]\n", tmp); return false; } printf("success: strlcat\n"); return true; } static int test_mktime(void) { /* FIXME */ return true; } static int test_initgroups(void) { /* FIXME */ return true; } static int test_memmove(void) { /* FIXME */ return true; } static int test_strdup(void) { char *x; printf("test: strdup\n"); x = strdup("bla"); if (strcmp("bla", x) != 0) { printf("failure: strdup [\nfailed: expected \"bla\", got \"%s\"\n]\n", x); return false; } free(x); printf("success: strdup\n"); return true; } static int test_setlinebuf(void) { printf("test: setlinebuf\n"); setlinebuf(stdout); printf("success: setlinebuf\n"); return true; } static int test_vsyslog(void) { /* FIXME */ return true; } static int test_timegm(void) { /* FIXME */ return true; } static int test_setenv(void) { #define TEST_SETENV(key, value, overwrite, result) do { \ int _ret; \ char *_v; \ _ret = setenv(key, value, overwrite); \ if (_ret != 0) { \ printf("failure: setenv [\n" \ "setenv(%s, %s, %d) failed\n" \ "]\n", \ key, value, overwrite); \ return false; \ } \ _v=getenv(key); \ if (!_v) { \ printf("failure: setenv [\n" \ "getenv(%s) returned NULL\n" \ "]\n", \ key); \ return false; \ } \ if (strcmp(result, _v) != 0) { \ printf("failure: setenv [\n" \ "getenv(%s): '%s' != '%s'\n" \ "]\n", \ key, result, _v); \ return false; \ } \ } while(0) #define TEST_UNSETENV(key) do { \ char *_v; \ unsetenv(key); \ _v=getenv(key); \ if (_v) { \ printf("failure: setenv [\n" \ "getenv(%s): NULL != '%s'\n" \ "]\n", \ SETENVTEST_KEY, _v); \ return false; \ } \ } while (0) #define SETENVTEST_KEY "SETENVTESTKEY" #define SETENVTEST_VAL "SETENVTESTVAL" printf("test: setenv\n"); TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"1", 0, SETENVTEST_VAL"1"); TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"2", 0, SETENVTEST_VAL"1"); TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"3", 1, SETENVTEST_VAL"3"); TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"4", 1, SETENVTEST_VAL"4"); TEST_UNSETENV(SETENVTEST_KEY); TEST_UNSETENV(SETENVTEST_KEY); TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"5", 0, SETENVTEST_VAL"5"); TEST_UNSETENV(SETENVTEST_KEY); TEST_UNSETENV(SETENVTEST_KEY); printf("success: setenv\n"); return true; } static int test_strndup(void) { char *x; printf("test: strndup\n"); x = strndup("bla", 0); if (strcmp(x, "") != 0) { printf("failure: strndup [\ninvalid\n]\n"); return false; } free(x); x = strndup("bla", 2); if (strcmp(x, "bl") != 0) { printf("failure: strndup [\ninvalid\n]\n"); return false; } free(x); x = strndup("bla", 10); if (strcmp(x, "bla") != 0) { printf("failure: strndup [\ninvalid\n]\n"); free(x); return false; } free(x); printf("success: strndup\n"); return true; } static int test_strnlen(void) { printf("test: strnlen\n"); if (strnlen("bla", 2) != 2) { printf("failure: strnlen [\nunexpected length\n]\n"); return false; } if (strnlen("some text\n", 0) != 0) { printf("failure: strnlen [\nunexpected length\n]\n"); return false; } if (strnlen("some text", 20) != 9) { printf("failure: strnlen [\nunexpected length\n]\n"); return false; } printf("success: strnlen\n"); return true; } static int test_waitpid(void) { /* FIXME */ return true; } static int test_seteuid(void) { /* FIXME */ return true; } static int test_setegid(void) { /* FIXME */ return true; } static int test_asprintf(void) { char *x; printf("test: asprintf\n"); if (asprintf(&x, "%d", 9) != 1) { printf("failure: asprintf [\ngenerate asprintf\n]\n"); return false; } if (strcmp(x, "9") != 0) { printf("failure: asprintf [\ngenerate asprintf\n]\n"); return false; } if (asprintf(&x, "dat%s", "a") != 4) { printf("failure: asprintf [\ngenerate asprintf\n]\n"); return false; } if (strcmp(x, "data") != 0) { printf("failure: asprintf [\ngenerate asprintf\n]\n"); return false; } printf("success: asprintf\n"); return true; } static int test_snprintf(void) { char tmp[10]; printf("test: snprintf\n"); if (snprintf(tmp, 3, "foo%d", 9) != 4) { printf("failure: snprintf [\nsnprintf return code failed\n]\n"); return false; } if (strcmp(tmp, "fo") != 0) { printf("failure: snprintf [\nsnprintf failed\n]\n"); return false; } printf("success: snprintf\n"); return true; } static int test_vasprintf(void) { /* FIXME */ return true; } static int test_vsnprintf(void) { /* FIXME */ return true; } static int test_opendir(void) { /* FIXME */ return true; } static int test_readdir(void) { printf("test: readdir\n"); if (test_readdir_os2_delete() != 0) { return false; } printf("success: readdir\n"); return true; } static int test_telldir(void) { /* FIXME */ return true; } static int test_seekdir(void) { /* FIXME */ return true; } static int test_dlopen(void) { /* FIXME: test dlopen, dlsym, dlclose, dlerror */ return true; } static int test_chroot(void) { /* FIXME: chroot() */ return true; } static int test_bzero(void) { /* FIXME: bzero */ return true; } static int test_strerror(void) { /* FIXME */ return true; } static int test_errno(void) { printf("test: errno\n"); errno = 3; if (errno != 3) { printf("failure: errno [\nerrno failed\n]\n"); return false; } printf("success: errno\n"); return true; } static int test_mkdtemp(void) { /* FIXME */ return true; } static int test_mkstemp(void) { /* FIXME */ return true; } static int test_pread(void) { /* FIXME */ return true; } static int test_pwrite(void) { /* FIXME */ return true; } static int test_inet_ntoa(void) { /* FIXME */ return true; } #define TEST_STRTO_X(type,fmt,func,str,base,res,diff,rrnoo) do {\ type _v; \ char _s[64]; \ char *_p = NULL;\ char *_ep = NULL; \ strlcpy(_s, str, sizeof(_s));\ if (diff >= 0) { \ _ep = &_s[diff]; \ } \ errno = 0; \ _v = func(_s, &_p, base); \ if (errno != rrnoo) { \ printf("failure: %s [\n" \ "\t%s\n" \ "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ "\terrno: %d != %d\n" \ "]\n", \ __STRING(func), __location__, __STRING(func), \ str, diff, base, res, _v, rrnoo, errno); \ return false; \ } else if (_v != res) { \ printf("failure: %s [\n" \ "\t%s\n" \ "\t%s(\"%s\",%d,%d): " fmt " != " fmt "\n" \ "]\n", \ __STRING(func), __location__, __STRING(func), \ str, diff, base, res, _v); \ return false; \ } else if (_p != _ep) { \ printf("failure: %s [\n" \ "\t%s\n" \ "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ "\tptr: %p - %p = %d != %d\n" \ "]\n", \ __STRING(func), __location__, __STRING(func), \ str, diff, base, res, _v, _ep, _p, (int)(diff - (_ep - _p)), diff); \ return false; \ } \ } while (0) static int test_strtoll(void) { printf("test: strtoll\n"); #define TEST_STRTOLL(str,base,res,diff,errnoo) TEST_STRTO_X(long long int, "%lld", strtoll,str,base,res,diff,errnoo) TEST_STRTOLL("15", 10, 15LL, 2, 0); TEST_STRTOLL(" 15", 10, 15LL, 4, 0); TEST_STRTOLL("15", 0, 15LL, 2, 0); TEST_STRTOLL(" 15 ", 0, 15LL, 3, 0); TEST_STRTOLL("+15", 10, 15LL, 3, 0); TEST_STRTOLL(" +15", 10, 15LL, 5, 0); TEST_STRTOLL("+15", 0, 15LL, 3, 0); TEST_STRTOLL(" +15 ", 0, 15LL, 4, 0); TEST_STRTOLL("-15", 10, -15LL, 3, 0); TEST_STRTOLL(" -15", 10, -15LL, 5, 0); TEST_STRTOLL("-15", 0, -15LL, 3, 0); TEST_STRTOLL(" -15 ", 0, -15LL, 4, 0); TEST_STRTOLL("015", 10, 15LL, 3, 0); TEST_STRTOLL(" 015", 10, 15LL, 5, 0); TEST_STRTOLL("015", 0, 13LL, 3, 0); TEST_STRTOLL(" 015", 0, 13LL, 5, 0); TEST_STRTOLL("0x15", 10, 0LL, 1, 0); TEST_STRTOLL(" 0x15", 10, 0LL, 3, 0); TEST_STRTOLL("0x15", 0, 21LL, 4, 0); TEST_STRTOLL(" 0x15", 0, 21LL, 6, 0); TEST_STRTOLL("10", 16, 16LL, 2, 0); TEST_STRTOLL(" 10 ", 16, 16LL, 4, 0); TEST_STRTOLL("0x10", 16, 16LL, 4, 0); TEST_STRTOLL("0x10", 0, 16LL, 4, 0); TEST_STRTOLL(" 0x10 ", 0, 16LL, 5, 0); TEST_STRTOLL("+10", 16, 16LL, 3, 0); TEST_STRTOLL(" +10 ", 16, 16LL, 5, 0); TEST_STRTOLL("+0x10", 16, 16LL, 5, 0); TEST_STRTOLL("+0x10", 0, 16LL, 5, 0); TEST_STRTOLL(" +0x10 ", 0, 16LL, 6, 0); TEST_STRTOLL("-10", 16, -16LL, 3, 0); TEST_STRTOLL(" -10 ", 16, -16LL, 5, 0); TEST_STRTOLL("-0x10", 16, -16LL, 5, 0); TEST_STRTOLL("-0x10", 0, -16LL, 5, 0); TEST_STRTOLL(" -0x10 ", 0, -16LL, 6, 0); TEST_STRTOLL("010", 16, 16LL, 3, 0); TEST_STRTOLL(" 010 ", 16, 16LL, 5, 0); TEST_STRTOLL("-010", 16, -16LL, 4, 0); TEST_STRTOLL("11", 8, 9LL, 2, 0); TEST_STRTOLL("011", 8, 9LL, 3, 0); TEST_STRTOLL("011", 0, 9LL, 3, 0); TEST_STRTOLL("-11", 8, -9LL, 3, 0); TEST_STRTOLL("-011", 8, -9LL, 4, 0); TEST_STRTOLL("-011", 0, -9LL, 4, 0); TEST_STRTOLL("011", 8, 9LL, 3, 0); TEST_STRTOLL("011", 0, 9LL, 3, 0); TEST_STRTOLL("-11", 8, -9LL, 3, 0); TEST_STRTOLL("-011", 8, -9LL, 4, 0); TEST_STRTOLL("-011", 0, -9LL, 4, 0); TEST_STRTOLL("Text", 0, 0LL, 0, 0); TEST_STRTOLL("9223372036854775807", 10, 9223372036854775807LL, 19, 0); TEST_STRTOLL("9223372036854775807", 0, 9223372036854775807LL, 19, 0); TEST_STRTOLL("9223372036854775808", 0, 9223372036854775807LL, 19, ERANGE); TEST_STRTOLL("9223372036854775808", 10, 9223372036854775807LL, 19, ERANGE); TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LL, 18, 0); TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 18, 0); TEST_STRTOLL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 16, 0); TEST_STRTOLL("0x8000000000000000", 0, 9223372036854775807LL, 18, ERANGE); TEST_STRTOLL("0x8000000000000000", 16, 9223372036854775807LL, 18, ERANGE); TEST_STRTOLL("80000000000000000", 16, 9223372036854775807LL, 17, ERANGE); TEST_STRTOLL("0777777777777777777777", 0, 9223372036854775807LL, 22, 0); TEST_STRTOLL("0777777777777777777777", 8, 9223372036854775807LL, 22, 0); TEST_STRTOLL("777777777777777777777", 8, 9223372036854775807LL, 21, 0); TEST_STRTOLL("01000000000000000000000", 0, 9223372036854775807LL, 23, ERANGE); TEST_STRTOLL("01000000000000000000000", 8, 9223372036854775807LL, 23, ERANGE); TEST_STRTOLL("1000000000000000000000", 8, 9223372036854775807LL, 22, ERANGE); TEST_STRTOLL("-9223372036854775808", 10, -9223372036854775807LL -1, 20, 0); TEST_STRTOLL("-9223372036854775808", 0, -9223372036854775807LL -1, 20, 0); TEST_STRTOLL("-9223372036854775809", 0, -9223372036854775807LL -1, 20, ERANGE); TEST_STRTOLL("-9223372036854775809", 10, -9223372036854775807LL -1, 20, ERANGE); TEST_STRTOLL("-0x8000000000000000", 0, -9223372036854775807LL -1, 19, 0); TEST_STRTOLL("-0x8000000000000000", 16, -9223372036854775807LL -1, 19, 0); TEST_STRTOLL("-8000000000000000", 16, -9223372036854775807LL -1, 17, 0); TEST_STRTOLL("-0x8000000000000001", 0, -9223372036854775807LL -1, 19, ERANGE); TEST_STRTOLL("-0x8000000000000001", 16, -9223372036854775807LL -1, 19, ERANGE); TEST_STRTOLL("-80000000000000001", 16, -9223372036854775807LL -1, 18, ERANGE); TEST_STRTOLL("-01000000000000000000000",0, -9223372036854775807LL -1, 24, 0); TEST_STRTOLL("-01000000000000000000000",8, -9223372036854775807LL -1, 24, 0); TEST_STRTOLL("-1000000000000000000000", 8, -9223372036854775807LL -1, 23, 0); TEST_STRTOLL("-01000000000000000000001",0, -9223372036854775807LL -1, 24, ERANGE); TEST_STRTOLL("-01000000000000000000001",8, -9223372036854775807LL -1, 24, ERANGE); TEST_STRTOLL("-1000000000000000000001", 8, -9223372036854775807LL -1, 23, ERANGE); printf("success: strtoll\n"); return true; } static int test_strtoull(void) { printf("test: strtoull\n"); #define TEST_STRTOULL(str,base,res,diff,errnoo) TEST_STRTO_X(long long unsigned int,"%llu",strtoull,str,base,res,diff,errnoo) TEST_STRTOULL("15", 10, 15LLU, 2, 0); TEST_STRTOULL(" 15", 10, 15LLU, 4, 0); TEST_STRTOULL("15", 0, 15LLU, 2, 0); TEST_STRTOULL(" 15 ", 0, 15LLU, 3, 0); TEST_STRTOULL("+15", 10, 15LLU, 3, 0); TEST_STRTOULL(" +15", 10, 15LLU, 5, 0); TEST_STRTOULL("+15", 0, 15LLU, 3, 0); TEST_STRTOULL(" +15 ", 0, 15LLU, 4, 0); TEST_STRTOULL("-15", 10, 18446744073709551601LLU, 3, 0); TEST_STRTOULL(" -15", 10, 18446744073709551601LLU, 5, 0); TEST_STRTOULL("-15", 0, 18446744073709551601LLU, 3, 0); TEST_STRTOULL(" -15 ", 0, 18446744073709551601LLU, 4, 0); TEST_STRTOULL("015", 10, 15LLU, 3, 0); TEST_STRTOULL(" 015", 10, 15LLU, 5, 0); TEST_STRTOULL("015", 0, 13LLU, 3, 0); TEST_STRTOULL(" 015", 0, 13LLU, 5, 0); TEST_STRTOULL("0x15", 10, 0LLU, 1, 0); TEST_STRTOULL(" 0x15", 10, 0LLU, 3, 0); TEST_STRTOULL("0x15", 0, 21LLU, 4, 0); TEST_STRTOULL(" 0x15", 0, 21LLU, 6, 0); TEST_STRTOULL("10", 16, 16LLU, 2, 0); TEST_STRTOULL(" 10 ", 16, 16LLU, 4, 0); TEST_STRTOULL("0x10", 16, 16LLU, 4, 0); TEST_STRTOULL("0x10", 0, 16LLU, 4, 0); TEST_STRTOULL(" 0x10 ", 0, 16LLU, 5, 0); TEST_STRTOULL("+10", 16, 16LLU, 3, 0); TEST_STRTOULL(" +10 ", 16, 16LLU, 5, 0); TEST_STRTOULL("+0x10", 16, 16LLU, 5, 0); TEST_STRTOULL("+0x10", 0, 16LLU, 5, 0); TEST_STRTOULL(" +0x10 ", 0, 16LLU, 6, 0); TEST_STRTOULL("-10", 16, -16LLU, 3, 0); TEST_STRTOULL(" -10 ", 16, -16LLU, 5, 0); TEST_STRTOULL("-0x10", 16, -16LLU, 5, 0); TEST_STRTOULL("-0x10", 0, -16LLU, 5, 0); TEST_STRTOULL(" -0x10 ", 0, -16LLU, 6, 0); TEST_STRTOULL("010", 16, 16LLU, 3, 0); TEST_STRTOULL(" 010 ", 16, 16LLU, 5, 0); TEST_STRTOULL("-010", 16, -16LLU, 4, 0); TEST_STRTOULL("11", 8, 9LLU, 2, 0); TEST_STRTOULL("011", 8, 9LLU, 3, 0); TEST_STRTOULL("011", 0, 9LLU, 3, 0); TEST_STRTOULL("-11", 8, -9LLU, 3, 0); TEST_STRTOULL("-011", 8, -9LLU, 4, 0); TEST_STRTOULL("-011", 0, -9LLU, 4, 0); TEST_STRTOULL("011", 8, 9LLU, 3, 0); TEST_STRTOULL("011", 0, 9LLU, 3, 0); TEST_STRTOULL("-11", 8, -9LLU, 3, 0); TEST_STRTOULL("-011", 8, -9LLU, 4, 0); TEST_STRTOULL("-011", 0, -9LLU, 4, 0); TEST_STRTOULL("Text", 0, 0LLU, 0, 0); TEST_STRTOULL("9223372036854775807", 10, 9223372036854775807LLU, 19, 0); TEST_STRTOULL("9223372036854775807", 0, 9223372036854775807LLU, 19, 0); TEST_STRTOULL("9223372036854775808", 0, 9223372036854775808LLU, 19, 0); TEST_STRTOULL("9223372036854775808", 10, 9223372036854775808LLU, 19, 0); TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LLU, 18, 0); TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 18, 0); TEST_STRTOULL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 16, 0); TEST_STRTOULL("0x8000000000000000", 0, 9223372036854775808LLU, 18, 0); TEST_STRTOULL("0x8000000000000000", 16, 9223372036854775808LLU, 18, 0); TEST_STRTOULL("8000000000000000", 16, 9223372036854775808LLU, 16, 0); TEST_STRTOULL("0777777777777777777777", 0, 9223372036854775807LLU, 22, 0); TEST_STRTOULL("0777777777777777777777", 8, 9223372036854775807LLU, 22, 0); TEST_STRTOULL("777777777777777777777", 8, 9223372036854775807LLU, 21, 0); TEST_STRTOULL("01000000000000000000000",0, 9223372036854775808LLU, 23, 0); TEST_STRTOULL("01000000000000000000000",8, 9223372036854775808LLU, 23, 0); TEST_STRTOULL("1000000000000000000000", 8, 9223372036854775808LLU, 22, 0); TEST_STRTOULL("-9223372036854775808", 10, 9223372036854775808LLU, 20, 0); TEST_STRTOULL("-9223372036854775808", 0, 9223372036854775808LLU, 20, 0); TEST_STRTOULL("-9223372036854775809", 0, 9223372036854775807LLU, 20, 0); TEST_STRTOULL("-9223372036854775809", 10, 9223372036854775807LLU, 20, 0); TEST_STRTOULL("-0x8000000000000000", 0, 9223372036854775808LLU, 19, 0); TEST_STRTOULL("-0x8000000000000000", 16, 9223372036854775808LLU, 19, 0); TEST_STRTOULL("-8000000000000000", 16, 9223372036854775808LLU, 17, 0); TEST_STRTOULL("-0x8000000000000001", 0, 9223372036854775807LLU, 19, 0); TEST_STRTOULL("-0x8000000000000001", 16, 9223372036854775807LLU, 19, 0); TEST_STRTOULL("-8000000000000001", 16, 9223372036854775807LLU, 17, 0); TEST_STRTOULL("-01000000000000000000000",0, 9223372036854775808LLU, 24, 0); TEST_STRTOULL("-01000000000000000000000",8, 9223372036854775808LLU, 24, 0); TEST_STRTOULL("-1000000000000000000000",8, 9223372036854775808LLU, 23, 0); TEST_STRTOULL("-01000000000000000000001",0, 9223372036854775807LLU, 24, 0); TEST_STRTOULL("-01000000000000000000001",8, 9223372036854775807LLU, 24, 0); TEST_STRTOULL("-1000000000000000000001",8, 9223372036854775807LLU, 23, 0); TEST_STRTOULL("18446744073709551615", 0, 18446744073709551615LLU, 20, 0); TEST_STRTOULL("18446744073709551615", 10, 18446744073709551615LLU, 20, 0); TEST_STRTOULL("18446744073709551616", 0, 18446744073709551615LLU, 20, ERANGE); TEST_STRTOULL("18446744073709551616", 10, 18446744073709551615LLU, 20, ERANGE); TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 0, 18446744073709551615LLU, 18, 0); TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 18, 0); TEST_STRTOULL("FFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 16, 0); TEST_STRTOULL("0x10000000000000000", 0, 18446744073709551615LLU, 19, ERANGE); TEST_STRTOULL("0x10000000000000000", 16, 18446744073709551615LLU, 19, ERANGE); TEST_STRTOULL("10000000000000000", 16, 18446744073709551615LLU, 17, ERANGE); TEST_STRTOULL("01777777777777777777777",0, 18446744073709551615LLU, 23, 0); TEST_STRTOULL("01777777777777777777777",8, 18446744073709551615LLU, 23, 0); TEST_STRTOULL("1777777777777777777777", 8, 18446744073709551615LLU, 22, 0); TEST_STRTOULL("02000000000000000000000",0, 18446744073709551615LLU, 23, ERANGE); TEST_STRTOULL("02000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); TEST_STRTOULL("2000000000000000000000", 8, 18446744073709551615LLU, 22, ERANGE); TEST_STRTOULL("-18446744073709551615", 0, 1LLU, 21, 0); TEST_STRTOULL("-18446744073709551615", 10, 1LLU, 21, 0); TEST_STRTOULL("-18446744073709551616", 0, 18446744073709551615LLU, 21, ERANGE); TEST_STRTOULL("-18446744073709551616", 10, 18446744073709551615LLU, 21, ERANGE); TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 0, 1LLU, 19, 0); TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 16, 1LLU, 19, 0); TEST_STRTOULL("-FFFFFFFFFFFFFFFF", 16, 1LLU, 17, 0); TEST_STRTOULL("-0x10000000000000000", 0, 18446744073709551615LLU, 20, ERANGE); TEST_STRTOULL("-0x10000000000000000", 16, 18446744073709551615LLU, 20, ERANGE); TEST_STRTOULL("-10000000000000000", 16, 18446744073709551615LLU, 18, ERANGE); TEST_STRTOULL("-01777777777777777777777",0, 1LLU, 24, 0); TEST_STRTOULL("-01777777777777777777777",8, 1LLU, 24, 0); TEST_STRTOULL("-1777777777777777777777",8, 1LLU, 23, 0); TEST_STRTOULL("-02000000000000000000000",0, 18446744073709551615LLU, 24, ERANGE); TEST_STRTOULL("-02000000000000000000000",8, 18446744073709551615LLU, 24, ERANGE); TEST_STRTOULL("-2000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); printf("success: strtoull\n"); return true; } /* FIXME: Types: bool socklen_t uint{8,16,32,64}_t int{8,16,32,64}_t intptr_t Constants: PATH_NAME_MAX UINT{16,32,64}_MAX INT32_MAX */ static int test_va_copy(void) { /* FIXME */ return true; } static int test_FUNCTION(void) { printf("test: FUNCTION\n"); if (strcmp(__FUNCTION__, "test_FUNCTION") != 0) { printf("failure: FUNCTION [\nFUNCTION invalid\n]\n"); return false; } printf("success: FUNCTION\n"); return true; } static int test_MIN(void) { printf("test: MIN\n"); if (MIN(20, 1) != 1) { printf("failure: MIN [\nMIN invalid\n]\n"); return false; } if (MIN(1, 20) != 1) { printf("failure: MIN [\nMIN invalid\n]\n"); return false; } printf("success: MIN\n"); return true; } static int test_MAX(void) { printf("test: MAX\n"); if (MAX(20, 1) != 20) { printf("failure: MAX [\nMAX invalid\n]\n"); return false; } if (MAX(1, 20) != 20) { printf("failure: MAX [\nMAX invalid\n]\n"); return false; } printf("success: MAX\n"); return true; } static int test_socketpair(void) { int sock[2]; char buf[20]; printf("test: socketpair\n"); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock) == -1) { printf("failure: socketpair [\n" "socketpair() failed\n" "]\n"); return false; } if (write(sock[1], "automatisch", 12) == -1) { printf("failure: socketpair [\n" "write() failed: %s\n" "]\n", strerror(errno)); return false; } if (read(sock[0], buf, 12) == -1) { printf("failure: socketpair [\n" "read() failed: %s\n" "]\n", strerror(errno)); return false; } if (strcmp(buf, "automatisch") != 0) { printf("failure: socketpair [\n" "expected: automatisch, got: %s\n" "]\n", buf); return false; } printf("success: socketpair\n"); return true; } extern int libreplace_test_strptime(void); static int test_strptime(void) { return libreplace_test_strptime(); } extern int getifaddrs_test(void); static int test_getifaddrs(void) { printf("test: getifaddrs\n"); if (getifaddrs_test() != 0) { printf("failure: getifaddrs\n"); return false; } printf("success: getifaddrs\n"); return true; } static int test_utime(void) { struct utimbuf u; struct stat st1, st2, st3; int fd; printf("test: utime\n"); unlink(TESTFILE); fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); if (fd == -1) { printf("failure: utime [\n" "creating '%s' failed - %s\n]\n", TESTFILE, strerror(errno)); return false; } if (fstat(fd, &st1) != 0) { printf("failure: utime [\n" "fstat (1) failed - %s\n]\n", strerror(errno)); close(fd); return false; } u.actime = st1.st_atime + 300; u.modtime = st1.st_mtime - 300; if (utime(TESTFILE, &u) != 0) { printf("failure: utime [\n" "utime(&u) failed - %s\n]\n", strerror(errno)); close(fd); return false; } if (fstat(fd, &st2) != 0) { printf("failure: utime [\n" "fstat (2) failed - %s\n]\n", strerror(errno)); close(fd); return false; } if (utime(TESTFILE, NULL) != 0) { printf("failure: utime [\n" "utime(NULL) failed - %s\n]\n", strerror(errno)); close(fd); return false; } if (fstat(fd, &st3) != 0) { printf("failure: utime [\n" "fstat (3) failed - %s\n]\n", strerror(errno)); close(fd); return false; } #define CMP_VAL(a,c,b) do { \ if (a c b) { \ printf("failure: utime [\n" \ "%s: %s(%d) %s %s(%d)\n]\n", \ __location__, \ #a, (int)a, #c, #b, (int)b); \ close(fd); \ return false; \ } \ } while(0) #define EQUAL_VAL(a,b) CMP_VAL(a,!=,b) #define GREATER_VAL(a,b) CMP_VAL(a,<=,b) #define LESSER_VAL(a,b) CMP_VAL(a,>=,b) EQUAL_VAL(st2.st_atime, st1.st_atime + 300); EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); LESSER_VAL(st3.st_atime, st2.st_atime); GREATER_VAL(st3.st_mtime, st2.st_mtime); #undef CMP_VAL #undef EQUAL_VAL #undef GREATER_VAL #undef LESSER_VAL unlink(TESTFILE); printf("success: utime\n"); close(fd); return true; } static int test_utimes(void) { struct timeval tv[2]; struct stat st1, st2; int fd; printf("test: utimes\n"); unlink(TESTFILE); fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); if (fd == -1) { printf("failure: utimes [\n" "creating '%s' failed - %s\n]\n", TESTFILE, strerror(errno)); return false; } if (fstat(fd, &st1) != 0) { printf("failure: utimes [\n" "fstat (1) failed - %s\n]\n", strerror(errno)); close(fd); return false; } ZERO_STRUCT(tv); tv[0].tv_sec = st1.st_atime + 300; tv[1].tv_sec = st1.st_mtime - 300; if (utimes(TESTFILE, tv) != 0) { printf("failure: utimes [\n" "utimes(tv) failed - %s\n]\n", strerror(errno)); close(fd); return false; } if (fstat(fd, &st2) != 0) { printf("failure: utimes [\n" "fstat (2) failed - %s\n]\n", strerror(errno)); close(fd); return false; } #define EQUAL_VAL(a,b) do { \ if (a != b) { \ printf("failure: utimes [\n" \ "%s: %s(%d) != %s(%d)\n]\n", \ __location__, \ #a, (int)a, #b, (int)b); \ close(fd); \ return false; \ } \ } while(0) EQUAL_VAL(st2.st_atime, st1.st_atime + 300); EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); #undef EQUAL_VAL unlink(TESTFILE); printf("success: utimes\n"); close(fd); return true; } static int test_memmem(void) { char *s; printf("test: memmem\n"); s = (char *)memmem("foo", 3, "fo", 2); if (strcmp(s, "foo") != 0) { printf(__location__ ": Failed memmem\n"); return false; } s = (char *)memmem("foo", 3, "", 0); /* it is allowable for this to return NULL (as happens on FreeBSD) */ if (s && strcmp(s, "foo") != 0) { printf(__location__ ": Failed memmem\n"); return false; } s = (char *)memmem("foo", 4, "o", 1); if (strcmp(s, "oo") != 0) { printf(__location__ ": Failed memmem\n"); return false; } s = (char *)memmem("foobarfodx", 11, "fod", 3); if (strcmp(s, "fodx") != 0) { printf(__location__ ": Failed memmem\n"); return false; } printf("success: memmem\n"); return true; } static bool test_closefrom(void) { int i, fd; for (i=0; i<100; i++) { fd = dup(0); if (fd == -1) { perror("dup failed"); return false; } /* 1000 is just an arbitrarily chosen upper bound */ if (fd >= 1000) { printf("fd=%d\n", fd); return false; } } closefrom(3); for (i=3; i<=fd; i++) { off_t off; off = lseek(i, 0, SEEK_CUR); if ((off != (off_t)-1) || (errno != EBADF)) { printf("fd %d not closed\n", i); return false; } } return true; } bool torture_local_replace(struct torture_context *ctx) { bool ret = true; ret &= test_ftruncate(); ret &= test_strlcpy(); ret &= test_strlcat(); ret &= test_mktime(); ret &= test_initgroups(); ret &= test_memmove(); ret &= test_strdup(); ret &= test_setlinebuf(); ret &= test_vsyslog(); ret &= test_timegm(); ret &= test_setenv(); ret &= test_strndup(); ret &= test_strnlen(); ret &= test_waitpid(); ret &= test_seteuid(); ret &= test_setegid(); ret &= test_asprintf(); ret &= test_snprintf(); ret &= test_vasprintf(); ret &= test_vsnprintf(); ret &= test_opendir(); ret &= test_readdir(); ret &= test_telldir(); ret &= test_seekdir(); ret &= test_dlopen(); ret &= test_chroot(); ret &= test_bzero(); ret &= test_strerror(); ret &= test_errno(); ret &= test_mkdtemp(); ret &= test_mkstemp(); ret &= test_pread(); ret &= test_pwrite(); ret &= test_inet_ntoa(); ret &= test_strtoll(); ret &= test_strtoull(); ret &= test_va_copy(); ret &= test_FUNCTION(); ret &= test_MIN(); ret &= test_MAX(); ret &= test_socketpair(); ret &= test_strptime(); ret &= test_getifaddrs(); ret &= test_utime(); ret &= test_utimes(); ret &= test_memmem(); ret &= test_closefrom(); return ret; } ldb-2.0.8/lib/replace/timegm.c0000660000000000000000000000476412406075657016054 0ustar rootroot00000000000000/* * Copyright (c) 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* adapted for Samba4 by Andrew Tridgell */ #include "replace.h" #include "system/time.h" static int is_leap(unsigned y) { y += 1900; return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); } time_t rep_timegm(struct tm *tm) { static const unsigned ndays[2][12] ={ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; time_t res = 0; unsigned i; if (tm->tm_mon > 12 || tm->tm_mon < 0 || tm->tm_mday > 31 || tm->tm_min > 60 || tm->tm_sec > 60 || tm->tm_hour > 24) { /* invalid tm structure */ return 0; } for (i = 70; i < tm->tm_year; ++i) res += is_leap(i) ? 366 : 365; for (i = 0; i < tm->tm_mon; ++i) res += ndays[is_leap(tm->tm_year)][i]; res += tm->tm_mday - 1; res *= 24; res += tm->tm_hour; res *= 60; res += tm->tm_min; res *= 60; res += tm->tm_sec; return res; } ldb-2.0.8/lib/replace/win32_replace.h0000660000000000000000000001046412406075657017226 0ustar rootroot00000000000000#ifndef _WIN32_REPLACE_H #define _WIN32_REPLACE_H #ifdef HAVE_WINSOCK2_H #include #endif #ifdef HAVE_WS2TCPIP_H #include #endif #ifdef HAVE_WINDOWS_H #include #endif /* Map BSD Socket errorcodes to the WSA errorcodes (if possible) */ #define EAFNOSUPPORT WSAEAFNOSUPPORT #define ECONNREFUSED WSAECONNREFUSED #define EINPROGRESS WSAEINPROGRESS #define EMSGSIZE WSAEMSGSIZE #define ENOBUFS WSAENOBUFS #define ENOTSOCK WSAENOTSOCK #define ENETUNREACH WSAENETUNREACH #define ENOPROTOOPT WSAENOPROTOOPT #define ENOTCONN WSAENOTCONN #define ENOTSUP 134 /* We undefine the following constants due to conflicts with the w32api headers * and the Windows Platform SDK/DDK. */ #undef interface #undef ERROR_INVALID_PARAMETER #undef ERROR_INSUFFICIENT_BUFFER #undef ERROR_INVALID_DATATYPE #undef FILE_GENERIC_READ #undef FILE_GENERIC_WRITE #undef FILE_GENERIC_EXECUTE #undef FILE_ATTRIBUTE_READONLY #undef FILE_ATTRIBUTE_HIDDEN #undef FILE_ATTRIBUTE_SYSTEM #undef FILE_ATTRIBUTE_DIRECTORY #undef FILE_ATTRIBUTE_ARCHIVE #undef FILE_ATTRIBUTE_DEVICE #undef FILE_ATTRIBUTE_NORMAL #undef FILE_ATTRIBUTE_TEMPORARY #undef FILE_ATTRIBUTE_REPARSE_POINT #undef FILE_ATTRIBUTE_COMPRESSED #undef FILE_ATTRIBUTE_OFFLINE #undef FILE_ATTRIBUTE_ENCRYPTED #undef FILE_FLAG_WRITE_THROUGH #undef FILE_FLAG_NO_BUFFERING #undef FILE_FLAG_RANDOM_ACCESS #undef FILE_FLAG_SEQUENTIAL_SCAN #undef FILE_FLAG_DELETE_ON_CLOSE #undef FILE_FLAG_BACKUP_SEMANTICS #undef FILE_FLAG_POSIX_SEMANTICS #undef FILE_TYPE_DISK #undef FILE_TYPE_UNKNOWN #undef FILE_CASE_SENSITIVE_SEARCH #undef FILE_CASE_PRESERVED_NAMES #undef FILE_UNICODE_ON_DISK #undef FILE_PERSISTENT_ACLS #undef FILE_FILE_COMPRESSION #undef FILE_VOLUME_QUOTAS #undef FILE_VOLUME_IS_COMPRESSED #undef FILE_NOTIFY_CHANGE_FILE_NAME #undef FILE_NOTIFY_CHANGE_DIR_NAME #undef FILE_NOTIFY_CHANGE_ATTRIBUTES #undef FILE_NOTIFY_CHANGE_SIZE #undef FILE_NOTIFY_CHANGE_LAST_WRITE #undef FILE_NOTIFY_CHANGE_LAST_ACCESS #undef FILE_NOTIFY_CHANGE_CREATION #undef FILE_NOTIFY_CHANGE_EA #undef FILE_NOTIFY_CHANGE_SECURITY #undef FILE_NOTIFY_CHANGE_STREAM_NAME #undef FILE_NOTIFY_CHANGE_STREAM_SIZE #undef FILE_NOTIFY_CHANGE_STREAM_WRITE #undef FILE_NOTIFY_CHANGE_NAME #undef PRINTER_ATTRIBUTE_QUEUED #undef PRINTER_ATTRIBUTE_DIRECT #undef PRINTER_ATTRIBUTE_DEFAULT #undef PRINTER_ATTRIBUTE_SHARED #undef PRINTER_ATTRIBUTE_NETWORK #undef PRINTER_ATTRIBUTE_HIDDEN #undef PRINTER_ATTRIBUTE_LOCAL #undef PRINTER_ATTRIBUTE_ENABLE_DEVQ #undef PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS #undef PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST #undef PRINTER_ATTRIBUTE_WORK_OFFLINE #undef PRINTER_ATTRIBUTE_ENABLE_BIDI #undef PRINTER_ATTRIBUTE_RAW_ONLY #undef PRINTER_ATTRIBUTE_PUBLISHED #undef PRINTER_ENUM_DEFAULT #undef PRINTER_ENUM_LOCAL #undef PRINTER_ENUM_CONNECTIONS #undef PRINTER_ENUM_FAVORITE #undef PRINTER_ENUM_NAME #undef PRINTER_ENUM_REMOTE #undef PRINTER_ENUM_SHARED #undef PRINTER_ENUM_NETWORK #undef PRINTER_ENUM_EXPAND #undef PRINTER_ENUM_CONTAINER #undef PRINTER_ENUM_ICON1 #undef PRINTER_ENUM_ICON2 #undef PRINTER_ENUM_ICON3 #undef PRINTER_ENUM_ICON4 #undef PRINTER_ENUM_ICON5 #undef PRINTER_ENUM_ICON6 #undef PRINTER_ENUM_ICON7 #undef PRINTER_ENUM_ICON8 #undef PRINTER_STATUS_PAUSED #undef PRINTER_STATUS_ERROR #undef PRINTER_STATUS_PENDING_DELETION #undef PRINTER_STATUS_PAPER_JAM #undef PRINTER_STATUS_PAPER_OUT #undef PRINTER_STATUS_MANUAL_FEED #undef PRINTER_STATUS_PAPER_PROBLEM #undef PRINTER_STATUS_OFFLINE #undef PRINTER_STATUS_IO_ACTIVE #undef PRINTER_STATUS_BUSY #undef PRINTER_STATUS_PRINTING #undef PRINTER_STATUS_OUTPUT_BIN_FULL #undef PRINTER_STATUS_NOT_AVAILABLE #undef PRINTER_STATUS_WAITING #undef PRINTER_STATUS_PROCESSING #undef PRINTER_STATUS_INITIALIZING #undef PRINTER_STATUS_WARMING_UP #undef PRINTER_STATUS_TONER_LOW #undef PRINTER_STATUS_NO_TONER #undef PRINTER_STATUS_PAGE_PUNT #undef PRINTER_STATUS_USER_INTERVENTION #undef PRINTER_STATUS_OUT_OF_MEMORY #undef PRINTER_STATUS_DOOR_OPEN #undef PRINTER_STATUS_SERVER_UNKNOWN #undef PRINTER_STATUS_POWER_SAVE #undef DWORD #undef HKEY_CLASSES_ROOT #undef HKEY_CURRENT_USER #undef HKEY_LOCAL_MACHINE #undef HKEY_USERS #undef HKEY_PERFORMANCE_DATA #undef HKEY_CURRENT_CONFIG #undef HKEY_DYN_DATA #undef REG_DWORD #undef REG_QWORD #undef SERVICE_STATE_ALL #undef SE_GROUP_MANDATORY #undef SE_GROUP_ENABLED_BY_DEFAULT #undef SE_GROUP_ENABLED #endif /* _WIN32_REPLACE_H */ ldb-2.0.8/lib/replace/wscript0000660000000000000000000012177413573675413016047 0ustar rootroot00000000000000#!/usr/bin/env python APPNAME = 'libreplace' VERSION = '1.2.1' import sys import os # find the buildtools directory top = '.' while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: top = top + '/..' sys.path.insert(0, top + '/buildtools/wafsamba') out = 'bin' import wafsamba from wafsamba import samba_dist from waflib import Options, Utils, Logs, Context samba_dist.DIST_DIRS('lib/replace buildtools:buildtools third_party/waf:third_party/waf') def options(opt): opt.BUILTIN_DEFAULT('NONE') opt.PRIVATE_EXTENSION_DEFAULT('') opt.RECURSE('buildtools/wafsamba') @Utils.run_once def configure(conf): conf.RECURSE('buildtools/wafsamba') conf.env.standalone_replace = conf.IN_LAUNCH_DIR() conf.DEFINE('HAVE_LIBREPLACE', 1) conf.DEFINE('LIBREPLACE_NETWORK_CHECKS', 1) conf.CHECK_HEADERS('linux/types.h crypt.h locale.h acl/libacl.h compat.h') conf.CHECK_HEADERS('acl/libacl.h attr/xattr.h compat.h ctype.h dustat.h') conf.CHECK_HEADERS('fcntl.h fnmatch.h glob.h history.h krb5.h langinfo.h') conf.CHECK_HEADERS('libaio.h locale.h ndir.h pwd.h') conf.CHECK_HEADERS('shadow.h sys/acl.h') conf.CHECK_HEADERS('sys/attributes.h attr/attributes.h sys/capability.h sys/dir.h sys/epoll.h') conf.CHECK_HEADERS('port.h') conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h') conf.CHECK_HEADERS('sys/id.h sys/ioctl.h sys/ipc.h sys/mman.h sys/mode.h sys/ndir.h sys/priv.h') conf.CHECK_HEADERS('sys/resource.h sys/security.h sys/shm.h sys/statfs.h sys/statvfs.h sys/termio.h') conf.CHECK_HEADERS('sys/vfs.h sys/xattr.h termio.h termios.h sys/file.h') conf.CHECK_HEADERS('sys/ucontext.h sys/wait.h sys/stat.h') if not conf.CHECK_DECLS('malloc', headers='stdlib.h'): conf.CHECK_HEADERS('malloc.h') conf.CHECK_HEADERS('grp.h') conf.CHECK_HEADERS('sys/select.h setjmp.h utime.h sys/syslog.h syslog.h') conf.CHECK_HEADERS('stdarg.h vararg.h sys/mount.h mntent.h') conf.CHECK_HEADERS('stropts.h unix.h string.h strings.h sys/param.h limits.h') conf.CHECK_HEADERS('''sys/socket.h netinet/in.h netdb.h arpa/inet.h netinet/in_systm.h netinet/ip.h netinet/tcp.h netinet/in_ip.h sys/sockio.h sys/un.h''', together=True) conf.CHECK_HEADERS('sys/uio.h ifaddrs.h direct.h dirent.h') conf.CHECK_HEADERS('windows.h winsock2.h ws2tcpip.h') conf.CHECK_HEADERS('errno.h') conf.CHECK_HEADERS('getopt.h iconv.h') conf.CHECK_HEADERS('memory.h nss.h sasl/sasl.h') conf.CHECK_FUNCS_IN('inotify_init', 'inotify', checklibc=True, headers='sys/inotify.h') conf.CHECK_HEADERS('security/pam_appl.h zlib.h asm/unistd.h') conf.CHECK_HEADERS('aio.h sys/unistd.h alloca.h float.h') conf.SET_TARGET_TYPE('tirpc', 'EMPTY') if conf.CHECK_CODE( '\n#ifndef _TIRPC_RPC_H\n#error "no tirpc headers in system path"\n#endif\n', 'HAVE_RPC_RPC_HEADERS', headers=['rpc/rpc.h', 'rpc/nettype.h'], msg='Checking for tirpc rpc headers in default system path'): if conf.CONFIG_SET('HAVE_RPC_RPC_H'): conf.undefine('HAVE_RPC_RPC_H') if not conf.CONFIG_SET('HAVE_RPC_RPC_H'): if conf.CHECK_CFG(package='libtirpc', args='--cflags --libs', msg='Checking for libtirpc headers', uselib_store='TIRPC'): 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'): if conf.CHECK_CFG(package='libntirpc', args='--cflags', msg='Checking for libntirpc headers', uselib_store='TIRPC'): 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?') conf.SET_TARGET_TYPE('nsl', 'EMPTY') conf.CHECK_HEADERS('rpc/rpc.h rpcsvc/yp_prot.h', lib='tirpc') if not conf.CONFIG_SET('HAVE_RPCSVC_YP_PROT_H'): if conf.CHECK_CFG(package='libnsl', args='--cflags --libs', msg='Checking for libnsl', uselib_store='NSL'): conf.SET_TARGET_TYPE('nsl', 'SYSLIB') conf.CHECK_HEADERS('rpc/rpc.h rpcsvc/yp_prot.h', lib='tirpc nsl') else: conf.SET_TARGET_TYPE('nsl', 'SYSLIB') conf.CHECK_HEADERS('rpcsvc/nis.h rpcsvc/ypclnt.h', lib='tirpc nsl') conf.CHECK_HEADERS('sys/sysctl.h') conf.CHECK_HEADERS('sys/fileio.h sys/filesys.h sys/dustat.h sys/sysmacros.h') conf.CHECK_HEADERS('xfs/libxfs.h netgroup.h') conf.CHECK_HEADERS('valgrind.h valgrind/valgrind.h') conf.CHECK_HEADERS('valgrind/memcheck.h valgrind/helgrind.h') conf.CHECK_HEADERS('nss_common.h nsswitch.h ns_api.h') conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h') conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h') conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h') conf.CHECK_HEADERS('sys/atomic.h stdatomic.h') conf.CHECK_HEADERS('libgen.h') if conf.CHECK_CFLAGS('-Wno-format-truncation'): conf.define('HAVE_WNO_FORMAT_TRUNCATION', '1') 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 int main(void) { prctl(0); return 0; } ''', 'HAVE_PRCTL', headers='sys/prctl.h', msg='Checking for prctl syscall') conf.CHECK_CODE(''' #include #ifdef HAVE_FCNTL_H #include #endif int main(void) { int fd = open("/dev/null", O_DIRECT); } ''', define='HAVE_OPEN_O_DIRECT', addmain=False, msg='Checking for O_DIRECT flag to open(2)') conf.CHECK_TYPES('"long long" intptr_t uintptr_t ptrdiff_t comparison_fn_t') conf.CHECK_TYPE('_Bool', define='HAVE__Bool') conf.CHECK_TYPE('bool', define='HAVE_BOOL') conf.CHECK_TYPE('int8_t', 'char') conf.CHECK_TYPE('uint8_t', 'unsigned char') conf.CHECK_TYPE('int16_t', 'short') conf.CHECK_TYPE('uint16_t', 'unsigned short') conf.CHECK_TYPE('int32_t', 'int') conf.CHECK_TYPE('uint32_t', 'unsigned') conf.CHECK_TYPE('int64_t', 'long long') conf.CHECK_TYPE('uint64_t', 'unsigned long long') conf.CHECK_TYPE('size_t', 'unsigned int') conf.CHECK_TYPE('ssize_t', 'int') conf.CHECK_TYPE('ino_t', 'unsigned') conf.CHECK_TYPE('loff_t', 'off_t') conf.CHECK_TYPE('offset_t', 'loff_t') conf.CHECK_TYPE('volatile int', define='HAVE_VOLATILE') conf.CHECK_TYPE('uint_t', 'unsigned int') conf.CHECK_TYPE('blksize_t', 'long', headers='sys/types.h sys/stat.h unistd.h') conf.CHECK_TYPE('blkcnt_t', 'long', headers='sys/types.h sys/stat.h unistd.h') conf.CHECK_SIZEOF('bool char int "long long" long short size_t ssize_t') conf.CHECK_SIZEOF('int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t') conf.CHECK_SIZEOF('void*', define='SIZEOF_VOID_P') conf.CHECK_SIZEOF('off_t dev_t ino_t time_t') conf.CHECK_TYPES('socklen_t', headers='sys/socket.h') conf.CHECK_TYPE_IN('struct ifaddrs', 'ifaddrs.h') conf.CHECK_TYPE_IN('struct addrinfo', 'netdb.h') conf.CHECK_TYPE_IN('struct sockaddr', 'sys/socket.h') conf.CHECK_CODE('struct sockaddr_in6 x', define='HAVE_STRUCT_SOCKADDR_IN6', headers='sys/socket.h netdb.h netinet/in.h') conf.CHECK_TYPE_IN('struct sockaddr_storage', 'sys/socket.h') conf.CHECK_TYPE_IN('sa_family_t', 'sys/socket.h') conf.CHECK_TYPE_IN('sig_atomic_t', 'signal.h', define='HAVE_SIG_ATOMIC_T_TYPE') conf.CHECK_FUNCS('sigsetmask siggetmask sigprocmask sigblock sigaction sigset') # Those functions are normally available in libc if not conf.CHECK_FUNCS(''' inet_ntoa inet_aton inet_ntop inet_pton connect gethostbyname getaddrinfo getnameinfo freeaddrinfo gai_strerror socketpair''', headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h'): conf.CHECK_FUNCS_IN(''' inet_ntoa inet_aton inet_ntop inet_pton connect gethostbyname getaddrinfo getnameinfo freeaddrinfo gai_strerror socketpair''', 'socket nsl', headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h') conf.DEFINE('REPLACE_REQUIRES_LIBSOCKET_LIBNSL', 1) conf.CHECK_FUNCS('memset_s memset_explicit') conf.CHECK_CODE(''' #include int main(void) { char buf[] = "This is some content"; memset(buf, '\0', sizeof(buf)); __asm__ volatile("" : : "g"(&buf) : "memory"); return 0; } ''', define='HAVE_GCC_VOLATILE_MEMORY_PROTECTION', addmain=False, msg='Checking for volatile memory protection', local_include=False) # Some old Linux systems have broken header files and # miss the IPV6_V6ONLY define in netinet/in.h, # but have it in linux/in6.h. # We can't include both files so we just check if the value # if defined and do the replacement in system/network.h if not conf.CHECK_VARIABLE('IPV6_V6ONLY', headers='sys/socket.h netdb.h netinet/in.h'): conf.CHECK_CODE(''' #include #if (IPV6_V6ONLY != 26) #error no IPV6_V6ONLY support on linux #endif int main(void) { return IPV6_V6ONLY; } ''', define='HAVE_LINUX_IPV6_V6ONLY_26', addmain=False, msg='Checking for IPV6_V6ONLY in linux/in6.h', local_include=False) conf.CHECK_CODE(''' struct sockaddr_storage sa_store; struct addrinfo *ai = NULL; struct in6_addr in6addr; int idx = if_nametoindex("iface1"); int s = socket(AF_INET6, SOCK_STREAM, 0); int ret = getaddrinfo(NULL, NULL, NULL, &ai); if (ret != 0) { const char *es = gai_strerror(ret); } freeaddrinfo(ai); { int val = 1; #ifdef HAVE_LINUX_IPV6_V6ONLY_26 #define IPV6_V6ONLY 26 #endif ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&val, sizeof(val)); } ''', define='HAVE_IPV6', lib='nsl socket', headers='sys/socket.h netdb.h netinet/in.h net/if.h') if conf.CONFIG_SET('HAVE_SYS_UCONTEXT_H') and conf.CONFIG_SET('HAVE_SIGNAL_H'): conf.CHECK_CODE(''' ucontext_t uc; sigaddset(&uc.uc_sigmask, SIGUSR1); ''', 'HAVE_UCONTEXT_T', msg="Checking whether we have ucontext_t", headers='signal.h sys/ucontext.h') # Check for atomic builtins. */ conf.CHECK_CODE(''' int i; (void)__sync_fetch_and_add(&i, 1); ''', 'HAVE___SYNC_FETCH_AND_ADD', msg='Checking for __sync_fetch_and_add compiler builtin') conf.CHECK_CODE(''' int32_t i; atomic_add_32(&i, 1); ''', 'HAVE_ATOMIC_ADD_32', headers='stdint.h sys/atomic.h', msg='Checking for atomic_add_32 compiler builtin') # Check for thread fence. */ tf = conf.CHECK_CODE('atomic_thread_fence(memory_order_seq_cst);', 'HAVE_ATOMIC_THREAD_FENCE', headers='stdatomic.h', msg='Checking for atomic_thread_fence(memory_order_seq_cst) in stdatomic.h') if not tf: tf = conf.CHECK_CODE('__atomic_thread_fence(__ATOMIC_SEQ_CST);', 'HAVE___ATOMIC_THREAD_FENCE', msg='Checking for __atomic_thread_fence(__ATOMIC_SEQ_CST)') if not tf: # __sync_synchronize() is available since 2005 in gcc. tf = conf.CHECK_CODE('__sync_synchronize();', 'HAVE___SYNC_SYNCHRONIZE', msg='Checking for __sync_synchronize') if tf: conf.DEFINE('HAVE_ATOMIC_THREAD_FENCE_SUPPORT', 1) 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, strict=True, cflags=['-Werror=missing-declarations'], 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) # See https://bugzilla.samba.org/show_bug.cgi?id=1097 # # Ported in from autoconf where it was added with this commit: # commit 804cfb20a067b4b687089dc72a8271b3abf20f31 # Author: Simo Sorce # Date: Wed Aug 25 14:24:16 2004 +0000 # r2070: Let's try to overload srnlen and strndup for AIX where they are natly broken. host_os = sys.platform if host_os.rfind('aix') > -1: conf.DEFINE('BROKEN_STRNLEN', 1) conf.DEFINE('BROKEN_STRNDUP', 1) conf.CHECK_FUNCS('shl_load shl_unload shl_findsym') conf.CHECK_FUNCS('pipe strftime srandom random srand rand usleep setbuffer') conf.CHECK_FUNCS('lstat getpgrp utime utimes setuid seteuid setreuid setresuid setgid setegid') conf.CHECK_FUNCS('setregid setresgid chroot strerror vsyslog setlinebuf mktime') conf.CHECK_FUNCS('ftruncate chsize rename waitpid wait4') conf.CHECK_FUNCS('initgroups pread pwrite strndup strcasestr strsep') conf.CHECK_FUNCS('strtok_r mkdtemp dup2 dprintf vdprintf isatty chown lchown') conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf') conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull') conf.CHECK_FUNCS('strtouq strtoll __strtoll strtoq memalign posix_memalign') conf.CHECK_FUNCS('fmemopen') if conf.CONFIG_SET('HAVE_MEMALIGN'): conf.CHECK_DECLS('memalign', headers='malloc.h') # glibc up to 2.3.6 had dangerously broken posix_fallocate(). DON'T USE IT. if conf.CHECK_CODE(''' #define _XOPEN_SOURCE 600 #include #if defined(__GLIBC__) && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 4)) #error probably broken posix_fallocate #endif ''', '_POSIX_FALLOCATE_CAPABLE_LIBC', msg='Checking for posix_fallocate-capable libc'): conf.CHECK_FUNCS('posix_fallocate') conf.CHECK_FUNCS('prctl dirname basename') strlcpy_in_bsd = False # libbsd on some platforms provides strlcpy and strlcat if not conf.CHECK_FUNCS('strlcpy strlcat'): if conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h', checklibc=True): strlcpy_in_bsd = True if not conf.CHECK_FUNCS('getpeereid'): conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h') if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'): conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h') if not conf.CHECK_FUNCS('setproctitle_init'): conf.CHECK_FUNCS_IN('setproctitle_init', 'bsd', headers='sys/types.h bsd/unistd.h') if not conf.CHECK_FUNCS('closefrom'): conf.CHECK_FUNCS_IN('closefrom', 'bsd', headers='bsd/unistd.h') conf.CHECK_CODE(''' struct ucred cred; socklen_t cred_len; int ret = getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len);''', 'HAVE_PEERCRED', msg="Checking whether we can use SO_PEERCRED to get socket credentials", headers='sys/types.h sys/socket.h') #Some OS (ie. freebsd) return EINVAL if the convertion could not be done, it's not what we expect #Let's detect those cases if conf.CONFIG_SET('HAVE_STRTOLL'): conf.CHECK_CODE(''' long long nb = strtoll("Text", NULL, 0); if (errno == EINVAL) { return 0; } else { return 1; } ''', msg="Checking correct behavior of strtoll", headers = 'errno.h', execute = True, define = 'HAVE_BSD_STRTOLL', ) conf.CHECK_FUNCS('if_nametoindex strerror_r') conf.CHECK_FUNCS('getdirentries getdents syslog') conf.CHECK_FUNCS('gai_strerror get_current_dir_name') conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap setgroups syscall setsid') conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize') conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create') conf.CHECK_FUNCS('port_create') conf.CHECK_FUNCS('getprogname') conf.SET_TARGET_TYPE('attr', 'EMPTY') xattr_headers='sys/attributes.h attr/xattr.h sys/xattr.h' # default to 1, we set it to 0 if we don't find any EA implementation below: conf.DEFINE('HAVE_XATTR_SUPPORT', 1) if conf.CHECK_FUNCS_IN('getxattr', 'attr', checklibc=True, headers=xattr_headers): conf.DEFINE('HAVE_XATTR_XATTR', 1) # Darwin has extra options to xattr-family functions conf.CHECK_CODE('getxattr(NULL, NULL, NULL, 0, 0, 0)', headers=xattr_headers, local_include=False, define='XATTR_ADDITIONAL_OPTIONS', msg="Checking whether xattr interface takes additional options") elif conf.CHECK_FUNCS_IN('attr_listf', 'attr', checklibc=True, headers=xattr_headers): conf.DEFINE('HAVE_XATTR_ATTR', 1) elif conf.CHECK_FUNCS('extattr_list_fd'): conf.DEFINE('HAVE_XATTR_EXTATTR', 1) elif conf.CHECK_FUNCS('flistea'): conf.DEFINE('HAVE_XATTR_EA', 1) elif not conf.CHECK_FUNCS('attropen'): conf.DEFINE('HAVE_XATTR_SUPPORT', 0) conf.CHECK_FUNCS_IN('dlopen dlsym dlerror dlclose', 'dl', checklibc=True, headers='dlfcn.h dl.h') conf.CHECK_C_PROTOTYPE('dlopen', 'void *dlopen(const char* filename, unsigned int flags)', define='DLOPEN_TAKES_UNSIGNED_FLAGS', headers='dlfcn.h dl.h') # # Check for clock_gettime and fdatasync # # First check libc to avoid linking libreplace against librt. # if conf.CHECK_FUNCS('fdatasync'): # some systems are missing the declaration conf.CHECK_DECLS('fdatasync') else: if conf.CHECK_FUNCS_IN('fdatasync', 'rt'): # some systems are missing the declaration conf.CHECK_DECLS('fdatasync') has_clock_gettime = False if conf.CHECK_FUNCS('clock_gettime'): has_clock_gettime = True if not has_clock_gettime: if conf.CHECK_FUNCS_IN('clock_gettime', 'rt', checklibc=True): has_clock_gettime = True if has_clock_gettime: for c in ['CLOCK_MONOTONIC', 'CLOCK_PROCESS_CPUTIME_ID', 'CLOCK_REALTIME']: conf.CHECK_CODE(''' #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif clockid_t clk = %s''' % c, 'HAVE_%s' % c, msg='Checking whether the clock_gettime clock ID %s is available' % c) conf.CHECK_TYPE('struct timespec', headers='sys/time.h time.h') # these headers need to be tested as a group on freebsd conf.CHECK_HEADERS(headers='sys/socket.h net/if.h', together=True) conf.CHECK_HEADERS(headers='netinet/in.h arpa/nameser.h resolv.h', together=True) conf.CHECK_FUNCS_IN('res_search', 'resolv', checklibc=True, headers='netinet/in.h arpa/nameser.h resolv.h') # try to find libintl (if --without-gettext is not given) conf.env.intl_libs='' if not Options.options.disable_gettext: conf.CHECK_HEADERS('libintl.h') conf.CHECK_LIB('intl') conf.CHECK_DECLS('dgettext gettext bindtextdomain textdomain bind_textdomain_codeset', headers="libintl.h") # *textdomain functions are not strictly necessary conf.CHECK_FUNCS_IN('bindtextdomain textdomain bind_textdomain_codeset', '', checklibc=True, headers='libintl.h') # gettext and dgettext must exist # on some systems (the ones with glibc, those are in libc) if conf.CHECK_FUNCS_IN('dgettext gettext', '', checklibc=True, headers='libintl.h'): # save for dependency definitions conf.env.intl_libs='' # others (e.g. FreeBSD) have separate libintl elif conf.CHECK_FUNCS_IN('dgettext gettext', 'intl', checklibc=False, headers='libintl.h'): # save for dependency definitions conf.env.intl_libs='intl' # recheck with libintl conf.CHECK_FUNCS_IN('bindtextdomain textdomain bind_textdomain_codeset', 'intl', checklibc=False, headers='libintl.h') else: # Some hosts need lib iconv for linking with lib intl # So we try with flags just in case it helps. oldflags = list(conf.env['EXTRA_LDFLAGS']); conf.env['EXTRA_LDFLAGS'].extend(["-liconv"]) conf.CHECK_FUNCS_IN('dgettext gettext bindtextdomain textdomain bind_textdomain_codeset', 'intl', checklibc=False, headers='libintl.h') conf.env['EXTRA_LDFLAGS'] = oldflags if conf.env['HAVE_GETTEXT'] and conf.env['HAVE_DGETTEXT']: # save for dependency definitions conf.env.intl_libs='iconv intl' # did we find both prototypes and a library to link against? # if not, unset the detected values (see Bug #9911) if not (conf.env['HAVE_GETTEXT'] and conf.env['HAVE_DECL_GETTEXT']): conf.undefine('HAVE_GETTEXT') conf.undefine('HAVE_DECL_GETTEXT') if not (conf.env['HAVE_DGETTEXT'] and conf.env['HAVE_DECL_DGETTEXT']): conf.undefine('HAVE_DGETTEXT') conf.undefine('HAVE_DECL_DGETTEXT') conf.CHECK_FUNCS_IN('pthread_create', 'pthread', checklibc=True, headers='pthread.h') PTHREAD_CFLAGS='error' PTHREAD_LDFLAGS='error' if PTHREAD_LDFLAGS == 'error': # Check if pthread_attr_init() is provided by libc first! if conf.CHECK_FUNCS('pthread_attr_init'): PTHREAD_CFLAGS='-D_REENTRANT' PTHREAD_LDFLAGS='' if PTHREAD_LDFLAGS == 'error': if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthread'): PTHREAD_CFLAGS='-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS' PTHREAD_LDFLAGS='-lpthread' if PTHREAD_LDFLAGS == 'error': if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthreads'): PTHREAD_CFLAGS='-D_THREAD_SAFE' PTHREAD_LDFLAGS='-lpthreads' if PTHREAD_LDFLAGS == 'error': if conf.CHECK_FUNCS_IN('pthread_attr_init', 'c_r'): PTHREAD_CFLAGS='-D_THREAD_SAFE -pthread' PTHREAD_LDFLAGS='-pthread' # especially for HP-UX, where the CHECK_FUNC macro fails to test for # pthread_attr_init. On pthread_mutex_lock it works there... if PTHREAD_LDFLAGS == 'error': if conf.CHECK_FUNCS_IN('pthread_mutex_lock', 'pthread'): PTHREAD_CFLAGS='-D_REENTRANT' PTHREAD_LDFLAGS='-lpthread' if PTHREAD_CFLAGS != 'error' and PTHREAD_LDFLAGS != 'error': if conf.CONFIG_SET('replace_add_global_pthread'): conf.ADD_CFLAGS(PTHREAD_CFLAGS) conf.ADD_LDFLAGS(PTHREAD_LDFLAGS) conf.CHECK_HEADERS('pthread.h') conf.DEFINE('HAVE_PTHREAD', '1') if conf.CONFIG_SET('HAVE_PTHREAD'): conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust', 'pthread', checklibc=True, headers='pthread.h') if not conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST'): conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust_np', 'pthread', checklibc=True, headers='pthread.h') conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST', headers='pthread.h') if not conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST'): conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST_NP', headers='pthread.h') conf.CHECK_FUNCS_IN('pthread_mutex_consistent', 'pthread', checklibc=True, headers='pthread.h') if not conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT'): conf.CHECK_FUNCS_IN('pthread_mutex_consistent_np', 'pthread', checklibc=True, headers='pthread.h') if ((conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST') or conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP')) and (conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST') or conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP')) and (conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT') or conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT_NP'))): conf.DEFINE('HAVE_ROBUST_MUTEXES', 1) # __thread is available since 2002 in gcc. conf.CHECK_CODE(''' __thread int tls; int main(void) { return 0; } ''', 'HAVE___THREAD', addmain=False, msg='Checking for __thread local storage') conf.CHECK_FUNCS_IN('crypt', 'crypt', checklibc=True) conf.CHECK_FUNCS_IN('crypt_r', 'crypt', checklibc=True) conf.CHECK_VARIABLE('rl_event_hook', define='HAVE_DECL_RL_EVENT_HOOK', always=True, headers='readline.h readline/readline.h readline/history.h') conf.CHECK_VARIABLE('program_invocation_short_name', headers='errno.h') conf.CHECK_DECLS('snprintf vsnprintf asprintf vasprintf') conf.CHECK_DECLS('errno', headers='errno.h', reverse=True) conf.CHECK_DECLS('EWOULDBLOCK', headers='errno.h') conf.CHECK_DECLS('environ', reverse=True, headers='unistd.h') conf.CHECK_DECLS('getgrent_r getpwent_r', reverse=True, headers='pwd.h grp.h') conf.CHECK_DECLS('pread pwrite setenv setresgid setresuid', reverse=True) if conf.CONFIG_SET('HAVE_EPOLL_CREATE') and conf.CONFIG_SET('HAVE_SYS_EPOLL_H'): conf.DEFINE('HAVE_EPOLL', 1) if conf.CONFIG_SET('HAVE_PORT_CREATE') and conf.CONFIG_SET('HAVE_PORT_H'): conf.DEFINE('HAVE_SOLARIS_PORTS', 1) if conf.CHECK_FUNCS('eventfd', headers='sys/eventfd.h'): conf.DEFINE('HAVE_EVENTFD', 1) conf.CHECK_HEADERS('poll.h') conf.CHECK_FUNCS('poll') conf.CHECK_FUNCS('strptime') conf.CHECK_DECLS('strptime', headers='time.h') conf.CHECK_CODE('''#define LIBREPLACE_CONFIGURE_TEST_STRPTIME #include "tests/strptime.c"''', define='HAVE_WORKING_STRPTIME', execute=True, addmain=False, msg='Checking for working strptime') conf.CHECK_C_PROTOTYPE('gettimeofday', 'int gettimeofday(struct timeval *tv, struct timezone *tz)', define='HAVE_GETTIMEOFDAY_TZ', headers='sys/time.h') conf.CHECK_C_PROTOTYPE('gettimeofday', 'int gettimeofday(struct timeval *tv, void *tz)', define='HAVE_GETTIMEOFDAY_TZ_VOID', headers='sys/time.h') conf.CHECK_CODE('#include "tests/snprintf.c"', define="HAVE_C99_VSNPRINTF", execute=True, addmain=False, msg="Checking for C99 vsnprintf") conf.CHECK_CODE('#include "tests/shared_mmap.c"', addmain=False, add_headers=False, execute=True, define='HAVE_SHARED_MMAP', msg="Checking for HAVE_SHARED_MMAP") conf.CHECK_CODE('#include "tests/shared_mremap.c"', addmain=False, add_headers=False, execute=True, define='HAVE_MREMAP', msg="Checking for HAVE_MREMAP") # OpenBSD (and I've heard HPUX) doesn't sync between mmap and write. # FIXME: Anything other than a 0 or 1 exit code should abort configure! conf.CHECK_CODE('#include "tests/incoherent_mmap.c"', addmain=False, add_headers=False, execute=True, define='HAVE_INCOHERENT_MMAP', msg="Checking for HAVE_INCOHERENT_MMAP") conf.SAMBA_BUILD_ENV() conf.CHECK_CODE(''' typedef struct {unsigned x;} FOOBAR; #define X_FOOBAR(x) ((FOOBAR) { x }) #define FOO_ONE X_FOOBAR(1) FOOBAR f = FOO_ONE; static const struct { FOOBAR y; } f2[] = { {FOO_ONE} }; static const FOOBAR f3[] = {FOO_ONE}; ''', define='HAVE_IMMEDIATE_STRUCTURES') conf.CHECK_CODE('mkdir("foo",0777)', define='HAVE_MKDIR_MODE', headers='sys/stat.h') conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec', define='HAVE_STAT_TV_NSEC', headers='sys/stat.h') # we need the st_rdev test under two names conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_rdev', define='HAVE_STRUCT_STAT_ST_RDEV', headers='sys/stat.h') conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_rdev', define='HAVE_ST_RDEV', headers='sys/stat.h') conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_storage', 'ss_family', headers='sys/socket.h netinet/in.h') conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_storage', '__ss_family', headers='sys/socket.h netinet/in.h') if conf.CHECK_STRUCTURE_MEMBER('struct sockaddr', 'sa_len', headers='sys/socket.h netinet/in.h', define='HAVE_SOCKADDR_SA_LEN'): # the old build system produced both defines conf.DEFINE('HAVE_STRUCT_SOCKADDR_SA_LEN', 1) conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_in', 'sin_len', headers='sys/socket.h netinet/in.h', define='HAVE_SOCK_SIN_LEN') conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_in6', 'sin6_len', headers='sys/socket.h netinet/in.h', define='HAVE_SOCK_SIN6_LEN') conf.CHECK_CODE('struct sockaddr_un sunaddr; sunaddr.sun_family = AF_UNIX;', define='HAVE_UNIXSOCKET', headers='sys/socket.h sys/un.h') conf.CHECK_CODE(''' struct stat st; char tpl[20]="/tmp/test.XXXXXX"; char tpl2[20]="/tmp/test.XXXXXX"; int fd = mkstemp(tpl); int fd2 = mkstemp(tpl2); if (fd == -1) { if (fd2 != -1) { unlink(tpl2); } exit(1); } if (fd2 == -1) exit(1); unlink(tpl); unlink(tpl2); if (fstat(fd, &st) != 0) exit(1); if ((st.st_mode & 0777) != 0600) exit(1); if (strcmp(tpl, "/tmp/test.XXXXXX") == 0) { exit(1); } if (strcmp(tpl, tpl2) == 0) { exit(1); } exit(0); ''', define='HAVE_SECURE_MKSTEMP', execute=True, mandatory=True) # lets see if we get a mandatory failure for this one # look for a method of finding the list of network interfaces for method in ['HAVE_IFACE_GETIFADDRS', 'HAVE_IFACE_AIX', 'HAVE_IFACE_IFCONF', 'HAVE_IFACE_IFREQ']: bsd_for_strlcpy = '' if strlcpy_in_bsd: bsd_for_strlcpy = ' bsd' if conf.CHECK_CODE(''' #define %s 1 #define NO_CONFIG_H 1 #define AUTOCONF_TEST 1 #include "replace.c" #include "inet_ntop.c" #include "snprintf.c" #include "getifaddrs.c" #define getifaddrs_test main #include "tests/getifaddrs.c" ''' % method, method, lib='nsl socket' + bsd_for_strlcpy, addmain=False, execute=True): break conf.RECURSE('system') conf.SAMBA_CONFIG_H() if conf.CHECK_FUNCS('strerror_r'): # Check if strerror_r is XSI-Compatable, the default GNU implementation # is not conf.CHECK_CODE('int strerror_r(int errnum, char *buf, size_t buflen);', 'STRERROR_R_XSI_NOT_GNU', headers='string.h', addmain=False, link=False, msg="Checking for XSI (rather than GNU) prototype for strerror_r") REPLACEMENT_FUNCTIONS = { 'replace.c': ['ftruncate', 'strlcpy', 'strlcat', 'mktime', 'initgroups', 'memmove', 'strdup', 'setlinebuf', 'vsyslog', 'strnlen', 'strndup', 'waitpid', 'seteuid', 'setegid', 'chroot', 'mkstemp', 'mkdtemp', 'pread', 'pwrite', 'strcasestr', 'strsep', 'strtok_r', 'strtoll', 'strtoull', 'setenv', 'unsetenv', 'utime', 'utimes', 'dup2', 'chown', 'link', 'readlink', 'symlink', 'lchown', 'realpath', 'memmem', 'vdprintf', 'dprintf', 'get_current_dir_name', 'strerror_r', 'clock_gettime', 'memset_s'], 'timegm.c': ['timegm'], # Note: C99_VSNPRINTF is not a function, but a special condition # for replacement 'snprintf.c': ['C99_VSNPRINTF', 'snprintf', 'vsnprintf', 'asprintf', 'vasprintf'], # Note: WORKING_STRPTIME is not a function, but a special condition # for replacement 'strptime.c': ['WORKING_STRPTIME', 'strptime'], } def build(bld): bld.RECURSE('buildtools/wafsamba') REPLACE_HOSTCC_SOURCE = '' for filename in REPLACEMENT_FUNCTIONS.keys(): for function in REPLACEMENT_FUNCTIONS[filename]: if not bld.CONFIG_SET('HAVE_%s' % function.upper()): REPLACE_HOSTCC_SOURCE += ' %s' % filename break extra_libs = '' if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd' if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl' bld.SAMBA_SUBSYSTEM('LIBREPLACE_HOSTCC', REPLACE_HOSTCC_SOURCE, use_hostcc=True, use_global_deps=False, cflags='-D_SAMBA_HOSTCC_', group='compiler_libraries', deps = extra_libs ) REPLACE_SOURCE = REPLACE_HOSTCC_SOURCE REPLACE_SOURCE += ' cwrap.c' if not bld.CONFIG_SET('HAVE_CRYPT'): REPLACE_SOURCE += ' crypt.c' if not bld.CONFIG_SET('HAVE_DLOPEN'): REPLACE_SOURCE += ' dlfcn.c' if not bld.CONFIG_SET('HAVE_POLL'): REPLACE_SOURCE += ' poll.c' if not bld.CONFIG_SET('HAVE_SOCKETPAIR'): REPLACE_SOURCE += ' socketpair.c' if not bld.CONFIG_SET('HAVE_CONNECT'): REPLACE_SOURCE += ' socket.c' if not bld.CONFIG_SET('HAVE_GETIFADDRS'): REPLACE_SOURCE += ' getifaddrs.c' if not bld.CONFIG_SET('HAVE_GETADDRINFO'): REPLACE_SOURCE += ' getaddrinfo.c' if not bld.CONFIG_SET('HAVE_INET_NTOA'): REPLACE_SOURCE += ' inet_ntoa.c' if not bld.CONFIG_SET('HAVE_INET_ATON'): REPLACE_SOURCE += ' inet_aton.c' if not bld.CONFIG_SET('HAVE_INET_NTOP'): REPLACE_SOURCE += ' inet_ntop.c' if not bld.CONFIG_SET('HAVE_INET_PTON'): REPLACE_SOURCE += ' inet_pton.c' if not bld.CONFIG_SET('HAVE_GETXATTR') or bld.CONFIG_SET('XATTR_ADDITIONAL_OPTIONS'): REPLACE_SOURCE += ' xattr.c' if not bld.CONFIG_SET('HAVE_CLOSEFROM'): REPLACE_SOURCE += ' closefrom.c' bld.SAMBA_LIBRARY('replace', source=REPLACE_SOURCE, group='base_libraries', # FIXME: Ideally symbols should be hidden here so they # don't appear in the global namespace when Samba # libraries are loaded, but this doesn't appear to work # at the moment: # hide_symbols=bld.BUILTIN_LIBRARY('replace'), private_library=True, deps='crypt dl attr' + extra_libs) replace_test_cflags = '' if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): replace_test_cflags += " -Wno-format-truncation" bld.SAMBA_SUBSYSTEM('replace-test', source='''tests/testsuite.c tests/strptime.c tests/os2_delete.c tests/getifaddrs.c''', deps='replace', cflags=replace_test_cflags) bld.SAMBA_BINARY('replace_testsuite', source='tests/main.c', deps='replace replace-test', install=False) # build replacements for stdint.h and stdbool.h if needed bld.SAMBA_GENERATOR('replace_stdint_h', rule='cp ${SRC} ${TGT}', source='hdr_replace.h', target='stdint.h', enabled = not bld.CONFIG_SET('HAVE_STDINT_H')) bld.SAMBA_GENERATOR('replace_stdbool_h', rule='cp ${SRC} ${TGT}', source='hdr_replace.h', target='stdbool.h', enabled = not bld.CONFIG_SET('HAVE_STDBOOL_H')) bld.SAMBA_SUBSYSTEM('samba_intl', source='', use_global_deps=False,deps=bld.env.intl_libs) def testonly(ctx): '''run talloc testsuite''' import samba_utils samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') cmd = os.path.join(Context.g_module.out, 'replace_testsuite') ret = samba_utils.RUN_COMMAND(cmd) print("testsuite returned %d" % ret) sys.exit(ret) # WAF doesn't build the unit tests for this, maybe because they don't link with talloc? # This forces it def test(ctx): Options.commands.append('build') Options.commands.append('testonly') def dist(): '''makes a tarball for distribution''' samba_dist.dist() ldb-2.0.8/lib/replace/xattr.c0000660000000000000000000005102413552036070015710 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. replacement routines for xattr implementations Copyright (C) Jeremy Allison 1998-2005 Copyright (C) Timur Bakeyev 2005 Copyright (C) Bjoern Jacke 2006-2007 Copyright (C) Herb Lewis 2003 Copyright (C) Andrew Bartlett 2012 ** NOTE! The following LGPL license applies to the replace ** 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 . */ #define UID_WRAPPER_NOT_REPLACE #include "replace.h" #include "system/filesys.h" #include "system/dir.h" /******** Solaris EA helper function prototypes ********/ #ifdef HAVE_ATTROPEN #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP static int solaris_write_xattr(int attrfd, const char *value, size_t size); static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size); static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size); static int solaris_unlinkat(int attrdirfd, const char *name); static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode); static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode); #endif /************************************************************************** Wrappers for extented attribute calls. Based on the Linux package with support for IRIX and (Net|Free)BSD also. Expand as other systems have them. ****************************************************************************/ ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return getxattr(path, name, value, size); #else /* So that we do not recursivly call this function */ #undef getxattr int options = 0; return getxattr(path, name, value, size, 0, options); #endif #elif defined(HAVE_XATTR_EA) return getea(path, name, value, size); #elif defined(HAVE_XATTR_EXTATTR) ssize_t retval; int attrnamespace; const char *attrname; if (strncmp(name, "system.", 7) == 0) { attrnamespace = EXTATTR_NAMESPACE_SYSTEM; attrname = name + 7; } else if (strncmp(name, "user.", 5) == 0) { attrnamespace = EXTATTR_NAMESPACE_USER; attrname = name + 5; } else { errno = EINVAL; return -1; } /* * The BSD implementation has a nasty habit of silently truncating * the returned value to the size of the buffer, so we have to check * that the buffer is large enough to fit the returned value. */ if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) { if (size == 0) { return retval; } else if (retval > size) { errno = ERANGE; return -1; } if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0) return retval; } return -1; #elif defined(HAVE_XATTR_ATTR) int retval, flags = 0; int valuelength = (int)size; char *attrname = strchr(name,'.') + 1; if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; retval = attr_get(path, attrname, (char *)value, &valuelength, flags); if (size == 0 && retval == -1 && errno == E2BIG) { return valuelength; } return retval ? retval : valuelength; #elif defined(HAVE_ATTROPEN) ssize_t ret = -1; int attrfd = solaris_attropen(path, name, O_RDONLY, 0); if (attrfd >= 0) { ret = solaris_read_xattr(attrfd, value, size); close(attrfd); } return ret; #else errno = ENOSYS; return -1; #endif } ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return fgetxattr(filedes, name, value, size); #else /* So that we do not recursivly call this function */ #undef fgetxattr int options = 0; return fgetxattr(filedes, name, value, size, 0, options); #endif #elif defined(HAVE_XATTR_EA) return fgetea(filedes, name, value, size); #elif defined(HAVE_XATTR_EXTATTR) ssize_t retval; int attrnamespace; const char *attrname; if (strncmp(name, "system.", 7) == 0) { attrnamespace = EXTATTR_NAMESPACE_SYSTEM; attrname = name + 7; } else if (strncmp(name, "user.", 5) == 0) { attrnamespace = EXTATTR_NAMESPACE_USER; attrname = name + 5; } else { errno = EINVAL; return -1; } if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { if (size == 0) { return retval; } else if (retval > size) { errno = ERANGE; return -1; } if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0) return retval; } return -1; #elif defined(HAVE_XATTR_ATTR) int retval, flags = 0; int valuelength = (int)size; char *attrname = strchr(name,'.') + 1; if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags); if (size == 0 && retval == -1 && errno == E2BIG) { return valuelength; } return retval ? retval : valuelength; #elif defined(HAVE_ATTROPEN) ssize_t ret = -1; int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0); if (attrfd >= 0) { ret = solaris_read_xattr(attrfd, value, size); close(attrfd); } return ret; #else errno = ENOSYS; return -1; #endif } #if defined(HAVE_XATTR_EXTATTR) #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1) static struct { int space; const char *name; size_t len; } extattr[] = { { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") }, { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") }, }; typedef union { const char *path; int filedes; } extattr_arg; static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size) { ssize_t list_size, total_size = 0; int i, t, len; char *buf; /* Iterate through extattr(2) namespaces */ for(t = 0; t < ARRAY_SIZE(extattr); t++) { if (t != EXTATTR_NAMESPACE_USER && geteuid() != 0) { /* ignore all but user namespace when we are not root, see bug 10247 */ continue; } switch(type) { case 0: list_size = extattr_list_file(arg.path, extattr[t].space, list, size); break; case 1: list_size = extattr_list_link(arg.path, extattr[t].space, list, size); break; case 2: list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size); break; default: errno = ENOSYS; return -1; } /* Some error happend. Errno should be set by the previous call */ if(list_size < 0) return -1; /* No attributes */ if(list_size == 0) continue; /* XXX: Call with an empty buffer may be used to calculate necessary buffer size. Unfortunately, we can't say, how many attributes were returned, so here is the potential problem with the emulation. */ if(list == NULL) { /* Take the worse case of one char attribute names - two bytes per name plus one more for sanity. */ total_size += list_size + (list_size/2 + 1)*extattr[t].len; continue; } /* Count necessary offset to fit namespace prefixes */ len = 0; for(i = 0; i < list_size; i += list[i] + 1) len += extattr[t].len; total_size += list_size + len; /* Buffer is too small to fit the results */ if(total_size > size) { errno = ERANGE; return -1; } /* Shift results back, so we can prepend prefixes */ buf = (char *)memmove(list + len, list, list_size); for(i = 0; i < list_size; i += len + 1) { len = buf[i]; strncpy(list, extattr[t].name, extattr[t].len + 1); list += extattr[t].len; strncpy(list, buf + i + 1, len); list[len] = '\0'; list += len + 1; } size -= total_size; } return total_size; } #endif #if defined(HAVE_XATTR_ATTR) && (defined(HAVE_SYS_ATTRIBUTES_H) || defined(HAVE_ATTR_ATTRIBUTES_H)) static char attr_buffer[ATTR_MAX_VALUELEN]; static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags) { int retval = 0, index; attrlist_cursor_t *cursor = 0; int total_size = 0; attrlist_t * al = (attrlist_t *)attr_buffer; attrlist_ent_t *ae; size_t ent_size, left = size; char *bp = list; while (true) { if (filedes) retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); else retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); if (retval) break; for (index = 0; index < al->al_count; index++) { ae = ATTR_ENTRY(attr_buffer, index); ent_size = strlen(ae->a_name) + sizeof("user."); if (left >= ent_size) { strncpy(bp, "user.", sizeof("user.")); strncat(bp, ae->a_name, ent_size - sizeof("user.")); bp += ent_size; left -= ent_size; } else if (size) { errno = ERANGE; retval = -1; break; } total_size += ent_size; } if (al->al_more == 0) break; } if (retval == 0) { flags |= ATTR_ROOT; cursor = 0; while (true) { if (filedes) retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); else retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); if (retval) break; for (index = 0; index < al->al_count; index++) { ae = ATTR_ENTRY(attr_buffer, index); ent_size = strlen(ae->a_name) + sizeof("system."); if (left >= ent_size) { strncpy(bp, "system.", sizeof("system.")); strncat(bp, ae->a_name, ent_size - sizeof("system.")); bp += ent_size; left -= ent_size; } else if (size) { errno = ERANGE; retval = -1; break; } total_size += ent_size; } if (al->al_more == 0) break; } } return (ssize_t)(retval ? retval : total_size); } #endif ssize_t rep_listxattr (const char *path, char *list, size_t size) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return listxattr(path, list, size); #else /* So that we do not recursivly call this function */ #undef listxattr int options = 0; return listxattr(path, list, size, options); #endif #elif defined(HAVE_XATTR_EA) return listea(path, list, size); #elif defined(HAVE_XATTR_EXTATTR) extattr_arg arg; arg.path = path; return bsd_attr_list(0, arg, list, size); #elif defined(HAVE_XATTR_ATTR) && defined(HAVE_SYS_ATTRIBUTES_H) return irix_attr_list(path, 0, list, size, 0); #elif defined(HAVE_ATTROPEN) ssize_t ret = -1; int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); if (attrdirfd >= 0) { ret = solaris_list_xattr(attrdirfd, list, size); close(attrdirfd); } return ret; #else errno = ENOSYS; return -1; #endif } ssize_t rep_flistxattr (int filedes, char *list, size_t size) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return flistxattr(filedes, list, size); #else /* So that we do not recursivly call this function */ #undef flistxattr int options = 0; return flistxattr(filedes, list, size, options); #endif #elif defined(HAVE_XATTR_EA) return flistea(filedes, list, size); #elif defined(HAVE_XATTR_EXTATTR) extattr_arg arg; arg.filedes = filedes; return bsd_attr_list(2, arg, list, size); #elif defined(HAVE_XATTR_ATTR) return irix_attr_list(NULL, filedes, list, size, 0); #elif defined(HAVE_ATTROPEN) ssize_t ret = -1; int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); if (attrdirfd >= 0) { ret = solaris_list_xattr(attrdirfd, list, size); close(attrdirfd); } return ret; #else errno = ENOSYS; return -1; #endif } int rep_removexattr (const char *path, const char *name) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return removexattr(path, name); #else /* So that we do not recursivly call this function */ #undef removexattr int options = 0; return removexattr(path, name, options); #endif #elif defined(HAVE_XATTR_EA) return removeea(path, name); #elif defined(HAVE_XATTR_EXTATTR) int attrnamespace; const char *attrname; if (strncmp(name, "system.", 7) == 0) { attrnamespace = EXTATTR_NAMESPACE_SYSTEM; attrname = name + 7; } else if (strncmp(name, "user.", 5) == 0) { attrnamespace = EXTATTR_NAMESPACE_USER; attrname = name + 5; } else { errno = EINVAL; return -1; } return extattr_delete_file(path, attrnamespace, attrname); #elif defined(HAVE_XATTR_ATTR) int flags = 0; char *attrname = strchr(name,'.') + 1; if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; return attr_remove(path, attrname, flags); #elif defined(HAVE_ATTROPEN) int ret = -1; int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); if (attrdirfd >= 0) { ret = solaris_unlinkat(attrdirfd, name); close(attrdirfd); } return ret; #else errno = ENOSYS; return -1; #endif } int rep_fremovexattr (int filedes, const char *name) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return fremovexattr(filedes, name); #else /* So that we do not recursivly call this function */ #undef fremovexattr int options = 0; return fremovexattr(filedes, name, options); #endif #elif defined(HAVE_XATTR_EA) return fremoveea(filedes, name); #elif defined(HAVE_XATTR_EXTATTR) int attrnamespace; const char *attrname; if (strncmp(name, "system.", 7) == 0) { attrnamespace = EXTATTR_NAMESPACE_SYSTEM; attrname = name + 7; } else if (strncmp(name, "user.", 5) == 0) { attrnamespace = EXTATTR_NAMESPACE_USER; attrname = name + 5; } else { errno = EINVAL; return -1; } return extattr_delete_fd(filedes, attrnamespace, attrname); #elif defined(HAVE_XATTR_ATTR) int flags = 0; char *attrname = strchr(name,'.') + 1; if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; return attr_removef(filedes, attrname, flags); #elif defined(HAVE_ATTROPEN) int ret = -1; int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); if (attrdirfd >= 0) { ret = solaris_unlinkat(attrdirfd, name); close(attrdirfd); } return ret; #else errno = ENOSYS; return -1; #endif } int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return setxattr(path, name, value, size, flags); #else /* So that we do not recursivly call this function */ #undef setxattr int options = 0; return setxattr(path, name, value, size, 0, options); #endif #elif defined(HAVE_XATTR_EA) return setea(path, name, value, size, flags); #elif defined(HAVE_XATTR_EXTATTR) int retval = 0; int attrnamespace; const char *attrname; if (strncmp(name, "system.", 7) == 0) { attrnamespace = EXTATTR_NAMESPACE_SYSTEM; attrname = name + 7; } else if (strncmp(name, "user.", 5) == 0) { attrnamespace = EXTATTR_NAMESPACE_USER; attrname = name + 5; } else { errno = EINVAL; return -1; } if (flags) { /* Check attribute existence */ retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0); if (retval < 0) { /* REPLACE attribute, that doesn't exist */ if (flags & XATTR_REPLACE && errno == ENOATTR) { errno = ENOATTR; return -1; } /* Ignore other errors */ } else { /* CREATE attribute, that already exists */ if (flags & XATTR_CREATE) { errno = EEXIST; return -1; } } } retval = extattr_set_file(path, attrnamespace, attrname, value, size); return (retval < 0) ? -1 : 0; #elif defined(HAVE_XATTR_ATTR) int myflags = 0; char *attrname = strchr(name,'.') + 1; if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; return attr_set(path, attrname, (const char *)value, size, myflags); #elif defined(HAVE_ATTROPEN) int ret = -1; int myflags = O_RDWR; int attrfd; if (flags & XATTR_CREATE) myflags |= O_EXCL; if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE); if (attrfd >= 0) { ret = solaris_write_xattr(attrfd, value, size); close(attrfd); } return ret; #else errno = ENOSYS; return -1; #endif } int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags) { #if defined(HAVE_XATTR_XATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return fsetxattr(filedes, name, value, size, flags); #else /* So that we do not recursivly call this function */ #undef fsetxattr int options = 0; return fsetxattr(filedes, name, value, size, 0, options); #endif #elif defined(HAVE_XATTR_EA) return fsetea(filedes, name, value, size, flags); #elif defined(HAVE_XATTR_EXTATTR) int retval = 0; int attrnamespace; const char *attrname; if (strncmp(name, "system.", 7) == 0) { attrnamespace = EXTATTR_NAMESPACE_SYSTEM; attrname = name + 7; } else if (strncmp(name, "user.", 5) == 0) { attrnamespace = EXTATTR_NAMESPACE_USER; attrname = name + 5; } else { errno = EINVAL; return -1; } if (flags) { /* Check attribute existence */ retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0); if (retval < 0) { /* REPLACE attribute, that doesn't exist */ if (flags & XATTR_REPLACE && errno == ENOATTR) { errno = ENOATTR; return -1; } /* Ignore other errors */ } else { /* CREATE attribute, that already exists */ if (flags & XATTR_CREATE) { errno = EEXIST; return -1; } } } retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size); return (retval < 0) ? -1 : 0; #elif defined(HAVE_XATTR_ATTR) int myflags = 0; char *attrname = strchr(name,'.') + 1; if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; return attr_setf(filedes, attrname, (const char *)value, size, myflags); #elif defined(HAVE_ATTROPEN) int ret = -1; int myflags = O_RDWR | O_XATTR; int attrfd; if (flags & XATTR_CREATE) myflags |= O_EXCL; if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE); if (attrfd >= 0) { ret = solaris_write_xattr(attrfd, value, size); close(attrfd); } return ret; #else errno = ENOSYS; return -1; #endif } /************************************************************************** helper functions for Solaris' EA support ****************************************************************************/ #ifdef HAVE_ATTROPEN static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size) { struct stat sbuf; if (fstat(attrfd, &sbuf) == -1) { errno = ENOATTR; return -1; } /* This is to return the current size of the named extended attribute */ if (size == 0) { return sbuf.st_size; } /* check size and read xattr */ if (sbuf.st_size > size) { errno = ERANGE; return -1; } return read(attrfd, value, sbuf.st_size); } static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size) { ssize_t len = 0; DIR *dirp; struct dirent *de; int newfd = dup(attrdirfd); /* CAUTION: The originating file descriptor should not be used again following the call to fdopendir(). For that reason we dup() the file descriptor here to make things more clear. */ dirp = fdopendir(newfd); while ((de = readdir(dirp))) { size_t listlen = strlen(de->d_name) + 1; if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { /* we don't want "." and ".." here: */ continue; } if (size == 0) { /* return the current size of the list of extended attribute names*/ len += listlen; } else { /* check size and copy entrieÑ• + nul into list. */ if ((len + listlen) > size) { errno = ERANGE; len = -1; break; } else { strlcpy(list + len, de->d_name, listlen); len += listlen; } } } if (closedir(dirp) == -1) { return -1; } return len; } static int solaris_unlinkat(int attrdirfd, const char *name) { if (unlinkat(attrdirfd, name, 0) == -1) { if (errno == ENOENT) { errno = ENOATTR; } return -1; } return 0; } static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode) { int filedes = attropen(path, attrpath, oflag, mode); if (filedes == -1) { if (errno == EINVAL) { errno = ENOTSUP; } else { errno = ENOATTR; } } return filedes; } static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode) { int filedes = openat(fildes, path, oflag, mode); if (filedes == -1) { if (errno == EINVAL) { errno = ENOTSUP; } else { errno = ENOATTR; } } return filedes; } static int solaris_write_xattr(int attrfd, const char *value, size_t size) { if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) { return 0; } else { return -1; } } #endif /*HAVE_ATTROPEN*/ ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs0000660000000000000000000000050012406075657020776 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs0000660000000000000000000000050012406075657020777 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs0000660000000000000000000000050012406075657021000 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs0000660000000000000000000000050012406075657020771 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs0000660000000000000000000000050012406075657020772 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs0000660000000000000000000000150413444661620021051 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs0000660000000000000000000000150413444661620021052 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs0000660000000000000000000000150413444661620021053 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs0000660000000000000000000000150413444661620021054 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs0000660000000000000000000000150413444661620021055 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs0000660000000000000000000000150413573675413021066 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs0000660000000000000000000000150413573675413021067 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs0000660000000000000000000000050012477561557021002 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs0000660000000000000000000000050012553526140020763 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs0000660000000000000000000000050012617125140020760 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs0000660000000000000000000000050012617125371020767 0ustar rootroot00000000000000pytalloc_CObject_FromTallocPtr: PyObject *(void *) pytalloc_Check: int (PyObject *) 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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs0000660000000000000000000000120712667552643021010 0ustar rootroot00000000000000_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_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs0000660000000000000000000000120712713047143020773 0ustar rootroot00000000000000_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_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs0000660000000000000000000000120712746330775021010 0ustar rootroot00000000000000_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_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs0000660000000000000000000000150413055076237021003 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs0000660000000000000000000000142113573675413020777 0ustar rootroot00000000000000_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 *) ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs0000660000000000000000000000644312406075657017462 0ustar rootroot00000000000000_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_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_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs0000660000000000000000000000644312406075657017463 0ustar rootroot00000000000000_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_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_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs0000660000000000000000000000644312406075657017464 0ustar rootroot00000000000000_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_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_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs0000660000000000000000000000644312406075657017465 0ustar rootroot00000000000000_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_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_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs0000660000000000000000000000644312406075657017466 0ustar rootroot00000000000000_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_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_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs0000660000000000000000000000644312406075657017467 0ustar rootroot00000000000000_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_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_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs0000660000000000000000000000652312406075657017467 0ustar rootroot00000000000000_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_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs0000660000000000000000000000665312406075657017464 0ustar rootroot00000000000000_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs0000660000000000000000000000665312406075657017465 0ustar rootroot00000000000000_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs0000660000000000000000000000671513444661620017536 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs0000660000000000000000000000671513444661620017537 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs0000660000000000000000000000671513444661620017540 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs0000660000000000000000000000671513444661620017541 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs0000660000000000000000000000671513444661620017542 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs0000660000000000000000000000671513573675413017553 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs0000660000000000000000000000671513573675413017554 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs0000660000000000000000000000665312477561557017475 0ustar rootroot00000000000000_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs0000660000000000000000000000665312553526140017456 0ustar rootroot00000000000000_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_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs0000660000000000000000000000671512617125140017452 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs0000660000000000000000000000671512617125371017461 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs0000660000000000000000000000671512667552643017475 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs0000660000000000000000000000671512713047143017460 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs0000660000000000000000000000671512746330775017475 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs0000660000000000000000000000671513055076237017470 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs0000660000000000000000000000671513573675413017466 0ustar rootroot00000000000000_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) ldb-2.0.8/lib/talloc/Makefile0000660000000000000000000000165613573675413015730 0ustar rootroot00000000000000# simple makefile wrapper to run waf WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` WAF_BINARY=$(PYTHON) $(WAF_BIN) WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) all: $(WAF) build install: $(WAF) install uninstall: $(WAF) uninstall test: $(WAF) test $(TEST_OPTIONS) testenv: $(WAF) test --testenv $(TEST_OPTIONS) quicktest: $(WAF) test --quick $(TEST_OPTIONS) dist: touch .tmplock WAFLOCK=.tmplock $(WAF) dist distcheck: touch .tmplock WAFLOCK=.tmplock $(WAF) distcheck clean: $(WAF) clean distclean: $(WAF) distclean reconfigure: configure $(WAF) reconfigure show_waf_options: $(WAF) --help # some compatibility make targets everything: all testsuite: all check: test torture: all # this should do an install as well, once install is finished installcheck: test etags: $(WAF) etags ctags: $(WAF) ctags pydoctor: $(WAF) pydoctor bin/%:: FORCE $(WAF) --targets=`basename $@` FORCE: ldb-2.0.8/lib/talloc/NEWS0000660000000000000000000000034012406075657014752 0ustar rootroot000000000000001.0.1 26 May 2007 BUGS * Set name of correctly when using talloc_append_string() (metze) LICENSE * Change license of files in lib/replace to LGPL (was GPL). (jelmer) 1.0.0 30 April 2007 Initial release. ldb-2.0.8/lib/talloc/compat/talloc_compat1.c0000660000000000000000000000312512406075657020610 0ustar rootroot00000000000000/* Samba trivial allocation library - compat functions Copyright (C) Stefan Metzmacher 2009 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ /* * This file contains only function to build a * compat talloc.so.1 library on top of talloc.so.2 */ #include "replace.h" #include "talloc.h" void *_talloc_reference(const void *context, const void *ptr); void *_talloc_reference(const void *context, const void *ptr) { return _talloc_reference_loc(context, ptr, "Called from talloc compat1 " "_talloc_reference"); } void *_talloc_steal(const void *new_ctx, const void *ptr); void *_talloc_steal(const void *new_ctx, const void *ptr) { return talloc_reparent(talloc_parent(ptr), new_ctx, ptr); } #undef talloc_free int talloc_free(void *ptr); int talloc_free(void *ptr) { return talloc_unlink(talloc_parent(ptr), ptr); } ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk0000660000000000000000000000122612406075657020775 0ustar rootroot00000000000000talloccompatdir := $(tallocdir)/compat TALLOC_COMPAT1_VERSION_MAJOR = 1 TALLOC_COMPAT1_OBJ = $(talloccompatdir)/talloc_compat1.o TALLOC_COMPAT1_SOLIB = libtalloc-compat1-$(TALLOC_VERSION).$(SHLIBEXT) TALLOC_COMPAT1_SONAME = libtalloc.$(SHLIBEXT).$(TALLOC_COMPAT1_VERSION_MAJOR) $(TALLOC_COMPAT1_SOLIB): $(TALLOC_COMPAT1_OBJ) $(TALLOC_SOLIB) $(SHLD) $(SHLD_FLAGS) -o $@ $(TALLOC_COMPAT1_OBJ) \ $(TALLOC_SOLIB) $(SONAMEFLAG)$(TALLOC_COMPAT1_SONAME) all:: $(TALLOC_COMPAT1_SOLIB) install:: ${INSTALLCMD} -d $(DESTDIR)$(libdir) ${INSTALLCMD} -m 755 $(TALLOC_COMPAT1_SOLIB) $(DESTDIR)$(libdir) clean:: rm -f $(TALLOC_COMPAT1_OBJ) $(TALLOC_COMPAT1_SOLIB) ldb-2.0.8/lib/talloc/configure0000770000000000000000000000066013573675413016170 0ustar rootroot00000000000000#!/bin/sh PREVPATH=`dirname $0` if [ -f $PREVPATH/../../buildtools/bin/waf ]; then WAF=../../buildtools/bin/waf elif [ -f $PREVPATH/buildtools/bin/waf ]; then WAF=./buildtools/bin/waf else echo "replace: Unable to find waf" exit 1 fi # using JOBS=1 gives maximum compatibility with # systems like AIX which have broken threading in python JOBS=1 export JOBS cd . || exit 1 $PYTHON $WAF configure "$@" || exit 1 cd $PREVPATH ldb-2.0.8/lib/talloc/doc/context.png0000660000000000000000000001115312406075657017216 0ustar rootroot00000000000000‰PNG  IHDRx(]È~ pHYsaa¨?§itEXtSoftwareGPL Ghostscript 8.63ô*8YôIDATxœíÜ1sÛFúÇñÕýÂM&{ææ\e6¥K¤¹—àK€»káw ÌuÀ½¢MG´êˆÖs Ѧ㦋Èu'3¸â‰÷ð'!Š’øõýT°»X`Áí‹a húË©;àü=;uŽªišÙlvê^àðþö·¿ýòË/»Ëüýïÿ÷¿ÿ}œþ`ÃÅ“ztº¸¸8u åÆ+ù«¯¾úí·ßŽÓlxZw4âIeëS°Ï÷GÛ¶¿ÿþû:ƒIÌÑàI¨ëúÓ§O§îÅÓEÐàI¨ëú?þðÞŸº#OAƒó×4DLUU§îËõ'ƒŸÔ!?7ël6kšÆc­]¯×ÖÚãuÆ‚g`Ïa}ùòåÇÒ#lâÑ €:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚€:‚æAhšæíÛ·òç»wﲆªªf³Ù¡vá½wþIñÞë°'ö>vÊŽ­Gt+—ñØÅ0 whñ‘’SpÌC®ë:I’= _\üo8ÆËJ»‹#txÇ®ÍÃúòåË?*u`¼wSQ–e–e·­µ»';¶Þç&ërG£«mÛSwç ïûSwá^E}ßWUuê^àÑkÛö±_HÏNݳÕ÷}Y–}ßçynŒqÎ¥ijŒišF 4M“$IE{6DZÔʲÌZ+›êºnÛV6c†²,sÖZï½s.«ëÚZÛ4tÏ{_–eUUrë[UU]×MÓ Ã6Íçsçœô$ÔXžçUU¥i𦩔<Þû¶måtí9pƘ²,¥¤Ü’„çèɛ܅÷¾®ëp!Åq,…ó<—1mÛ6\MÓ4MÇqß÷Þû}ºqÎM>æ×umŒ‘öe_ÛÕ7®+ñîÝ;9¢(Ìð”ÈñyÛkV«Õ0 ëõÚ9w]áñr–e‹ÅB–‹E–ea9I’PÌZ+-oȲ¬( Y^­VÖÚ°‹årê^×ç^Íçóñ·‹E±^¯·»¡gÏa}ñâÅ}öDZœÆ®ëv ÜøÏ,ËÆ§+MSÇënÿ]E.ƒÕjÇñv³ëõz÷i —âF÷Æ»[,iš†2óù<ìwÇu%‡eY×u®ÜÑóó‚fµZu]×uÝr¹Üý‘–…íËÅ#Ÿdç\¸2¤åíHõ0Þãb×åÚ>½šÜÔu]Çã}Çq‚f½^ï3pÃè“¶±~¹\FQ4\?pûïÂ9WÅò3ÙºÑìv­ [‹EH·°)Š¢ðm6u]·ûºêºnyÃ00GslÖÚ<ÏåþvŸò“7À²Ò{ž¡Œ1“7óRòÆbQU•µö±Ï&ìp«›| +w Üž»ðÞGQ&ïfoKž€ö<Šו<úµm+Ï\Úxççø‡v¾â8Þ¸§æ~w4“¶¿y¶w±cù¶›º®»î NÏžÃzÿG§}n¼uã̇[†ënŸ]È…äœ?” ;š6å6m½^︮$ø–Ë¥µ–G§# ç:Ív‚loÚXN’d´mûáÇpž·¯+y yyÙ÷½l­ªê§Ÿ~Š¢ˆ_ãÑ;ù/ƒq#&ƒ¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨#h¨;|Дeyò<(‡š¾ïOÞ€åÀAÓ¶mUU§mÀCó,,•e霳ÖzïsqcêºîûÞ9ç½·Ö&IbŒ©ªªª*)E‘lJÓÔ{/åó<7ÆÄq,eò<—–۶ͲÌZ›çyÓ4ÞûÅbÇñl6óÞ'I’¦éd ·a†aȲ¬( Y^­VÖÚa‹Eš¦ÃgY–-‹ð§µv¹\†å°>´)Š¢È²,´DZ,w]g­]­VÒr×u×µp@ãCÆÙØsX_¼xq„Î`’†a½^cÆuùü;çB” ð\.sÿ«9Úë–¥‘¢(–Ÿ·J¢m¤Ìv DМ%‚æá{fŒñÞc¬µá6'Š¢°~l{ͼ÷Q…' áóe!{ɲ¬išñ®œŸ¿cœsfê]¬ß½f‡¦i¤Êuñ$“AQÉŒÌu-xìþ š,ËÆ¿^‘OxQu]‡•u]Eqc‹r{Ò÷½,E1΋ðF©ïûº®“$‘ãm´à±»Ï2yž[kå¡É9'7/×½uòÞ—e™eYš¦UUɲ¼$’­QIaiDÖcdyž×u-s@Ƙï¾ûÎ{Ÿ¦iš¦Î¹ív´æÿ?¾á ì9¬/_¾üøñãQz„MOêSGМ%‚æáãß:PwþA3›Í˜TNëÙÍEÔÌf³#ì¥iš¦i¾üòË¿þõ¯²Fî´mÿøÇ?~üñÇS÷â ÿÄŠL-'Iòí·ßžºG8¼o¾ùæçŸÞ]fŸ9š¯¾úê·ß~;\¿ð§SÞÑGÇòF,ü)¯ºpNrwܶíï¿ÿ~ÿv°íüƒ†XÁžêºþôéÓ©{qžÎ2ØS]×üñÇþ nDÐÆ#ÿo‰ýxDÐÆŒþÙªªø?îüçh€}È\¿V u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u uÍòÞ¿}ûöâââÔþDÐ<eYÞª¼sn±X(uT]×_ýuß÷'Ù;Aóœê ¦iNÒBÇY–Ykï¹÷»!hº¶m«ª:u/p0§ km–e÷Üõ=;ÕŽ¾²,ó<ŸÏç²¼\.s}ß—eE‘1¦mÛð‘ç¹µVÖ7MS…1¦ªªº®›¦†Á{_–eUUÃ0Hûyž;笵¡¶m›¦ Äq윫ëºïû<Ï1qÇq†aµZÉš,Ë‹…,/—Ki-˲,Ë®ÛÅø$‡å¢(B•Õj%U’$ %»®[.—Û-\Ww±XŒ«¯×ë݃MXkÃaýäñJõ°^þÜ®¾X,Ò4 eæóyèöö‰†A¦–Bá®ëvôÃ>ÃúâÅ‹û”éº.˲ù|¾\.ÃÁÃP…¬Y,Òÿõz-Q KE)lŒÉ>·,Õ³,ëºn½^Ë÷GEëõz½^;çâ8žÏç“-lX­V¡WY–-—ËÐ%)¦©¬_.—I’„³'ý ݸñtí ÙÅ3>Ýòé]Žcdåz½Å6†2hœsáRv¤¢\Lãß°4“uÇŸÒÉZÛ‡vc''wÿêQ?Ãè|nœXQEÈÊqîãA“$IèUÈå "MÓ0 ÛQÖo´|]šËMt×u’D¡ü÷7~c…Ö–Ë¥µV®ÞÉ/°C!hvÙÑñ'mÇÊ}‚f| 0& ÖZç\ˆ›íOõvÝí•÷šÉãÝ¿úd—dÍd³]×ÉE¿^¯7¢öFÚA#™ÂQº×uÝöE‘,_wŠ6ÖïHóaŠ¢ˆ¢hÇ5éÆo,I–®ëÆßO“_`‡Âdð-ÈŒÆÆôÇäÊ}šÚ®RU•ÜÐv]—¦éö[m™œ¬+óG·êÃ>4·?´qõq—dYÚœd­M’¤ªª¶meVèá“^Ù„I«í’“+ol9>Ïâc²,ÛqÆ®#_Wu]Ïf³o¿ýv»KÒæ»wïâ8N’$ô$Š¢ÉnÜAs ι,ËÆï€Ê²tÎÉÇ#¬Ü×puŽ×E1~w Õ›¦ ŸÌñ›HYèû^&ën¬¼íå>iòx÷¯¾Ñ¥º®oüؤiú0_±I·7¢|{eß÷ûçBøÚ0×§yÓ4Y–5M#Óê“-l»ñËS–eÛ¶2ã#¯&¿Àæ€wGÂþNòZd{ÊMÞŒ,—Ëù|nA¥Øä=ç|>— ¶ù|._ Rk±X„;U¹ÅM’¤(ŠÅb!‡u™FOÁlו•¡ò~'MÓÉ)=Ù¦6ß26M︌¬œ¬.H2Á)¥EQì>±· ÛÖºçMš¦áœÈ‘7ÍÑŒ«‡?­µ2(á¹rãT„µZ­Âì²s.Ìn·°!I’ñ¸‡)ùЇÕje­¿â¶Þ'Üvšl·‹á 7Hßl6“,ÐsqñäÎêÉKîÛÖÚgX_¾|ùñãÇû”Éó\š¼÷išÊ fxý/¯ö“$ñÞ‡·õq{ïåÇ ÙUUyïe&.I’¾ïC—Ò4•òÐÔ4MÛ¶rö꺖(cÌußÑCëQ8ì\ú¤'xVïiµZÉwi¸I¼­#ÜÑà>˜£90™bÈóüaÎ5>^$›ýß™Ìbño¿ýÖ¤ !!!>ÌÎÎîíímhhèìì‹Å&-1æÇtppàr¹1° XEá*¼P>lòOz½þÑ£G‰déÒ¥sæÌ¡gΜéää¤V«9!D§Ó9;;ÓŒŒŽŽúúúêt:‹¥×ëéÝ·žžžŽŽŽE‹y{{›œÇ¸Fóâæm „ôöövuu…††:;;[l õkלþóŸ#IJ–e7=€ì€m=;d@v`]àCÅ/µZ-“ɦ_¿ÆÆÆÌÑÙÙ/%%%OÈ`0š››gÏž½páBkh°R©ljjZ»v­««ë“s®^½ñ¶>z2Å7}ÅÅÅ"‘(%%%44Ôz688XRR"“Éöïßïëë‹HÈL7ÍAy²v¤9(@vÀŽ4åÈØ‘æ <Ùqi®¤¤ä?ÿù­kʰ#ÍAy²v¤9(@vМiÊ4jŸÊ4åÙAsP4åÙAsP4åÙAsP€ì4åÈšP€ì 9åÈšP€ì 9åÈšƒò€ì 9(Èšƒò°OÙAsP€ì 9åÈšP€ì 9åÈšP€ì 9åÈšP€ì 9å;“Ý¥K—êëëwìØŽpš¾¾¾?þØÑÑQ p8\`YvåååõõõóæÍ³‰¨T*ggç'dP(}ô"m?ŒÅÄĬ[·îŽÉG©T¾ôÒKo½õÂ4ù8XLÝ¿ÿ´Y>|a¶7~ùË_9rÄ &‘HÊÊÊ )K€ì²È ;¦ƒÁðÃ?ˆÅb&E©Tööö*•ÊÖÖV:E¥Rµ´´ç‘ËåÌKN'‰èã¡¡!©Tª×ë…B¡L&còkµZ¡PØÞÞn0pÍ!;&›3gΔ””<|ø022rëÖ­ ¥¥¥\.7///222**ŠRVVvôèQ±X¼ÿþ;v¨Tª²²² œ;wŽÒÔÔ´bÅŠŒŒ BÈñãǽ½½OŸ>½{÷n@PTTDéììܹs§H$úâ‹/’““qÙ­‡qæ“Ëåccc^^^ôäÖÓÓãïïOObmmm...l6›™ýþýïs¹\wwwzòòððxôèQHH!D*•²Ùl—û÷ï¹¹¹ÑÇÆÆ~üñÇ%K–¸¸¸×;wîÜ,^¼ØÑÑQ«ÕÒ¥˜<æ5`BOOÏÁƒ%‰ƒƒCooïçŸ~óæMBH}}}ccc]]ÝÝ»w[ZZ îÝ»Çb±6nÜšŸŸŸ}þüyú$áááo¼ñÆ7!™™™¥¥¥b±¸¼¼œÅbݼysýúõ111ÕÕÕ^^^111111õõõ¸ò6vg÷¸ÉÍ|£(êØ±c'NœèééÙ´iSmmí… L&Ï÷ßßÛÛ;??÷îÝ loo×jµ™™™EEEGŽ U(L½ !!aß¾}K–,©­­MLLÌÌÌ\¾|¹T*µX#‚ ÌQ(cccôbS¡P0#urrŠŽŽöððذaCMMMPP‹Å"„°Ùl>Ÿÿõ×_Óy˜ó˜GFFÒù#""¸\îƒx<ÞÙ³gò³³½½½qåmìÎî7¿ùÅÉíüùó&“صk×.]ºtëÖ-BˆX,~çwîܹséÒ%fò$„dee•••yzz¾ÿþûE­ZµêܹsŒ‹‹[¿~=EQ!!!ÿøÇ?¶lÙB×ëààpéÒ%Š¢üüü*++«ªª(Šò÷÷ÿûßÿž’’b±FĘ”•••’’ÂãñäryAAóÖŒ3˜e=ƒÒxzzΚ5‹>fvßôzýãªÐh4kÖ¬™7o^{{{MMMeeeaaa__ßÌ™3qýmikqrãñxï¾ûnccclllRR!ä›o¾ÉÍÍuqq¡—®&“'s†eË–BX,VTT”D"qrr (((P©Tl6{``À<çªU«˜ãŸþô§ô,m±FÌñññÙ¶m[jjªq¢Á``DUPP ‹éíšÖÖÖÄÄDBˆ«««P(¤7m.^¼h<Ɔ††èƒ«W¯&''Ï›7¯¸¸8--mÏž={öì –ËåÉÎâän2‰I¥Rÿììl“²Ìäi¡:®±±1--­¾¾ÞËËë»ï¾³øËøÝÌñãjÀ„ŠŠŠöööÏ>ûŒÅb¹¹¹ ‚ÑÑѦ¦&ww÷•+WÆÇÇoÚ´)==Ïççæævwws¹Ü×_’œœÜÛÛ»páBWQQqåÊ•˜˜Bˆ@ hhh˜?~HHH^^!¤­­íøÃ–-[š››ß|óMÚ›À–dgqr3ŸÄÖ®]›™™Ù××GïV 6›m‰íÚµëúõëk׮ݾ};‡Ã öññ1ž< !þóŸE"QyyùâÅ‹ƒ‚‚!ׯ_OII9yòä¶mÛbcc}}}¯\¹²yóæÛ·o777+Š7vttÐÇ«W¯&„ÔÔÔðx<óßxã ĘpöìYOOÏíÛ·3ûqÙÙÙŒ¡þÿ‚ŸŸŸŸŸŸIñY³fÑûwŽŽŽ&ùçÏŸo²þÆ5·:(3>ÿüó––óôááá®®.ƒÁ Ñh´Z­J¥Òét<¸uë–T*5ÎÙÓÓóÏþS©TR¥R©´Z­V«¥_R¥P(t:Z­Öh4Ei4ú¥L&“H$LN§T*µZ­F£Q«ÕÆÇE©Õj­VK›Ôh¡C‡(`OŒŽŽæææš$þío‹ŽŽÖétôࡲ=cE¡¡¡OUd`` ??1šžbÏÎâäfqóñññññaž0˜Lžôçã˜M7úl‡Ù×cŠ<ágM6kÀœøøx‹•““ãåå¥V«½ªx–[ÅÀÀÀÆÆÆ—_~Wxú,c°uø|>ŸÏ^gKMM5y° ¬ìå ;€ì²ëÂòН¾úêþýûÓ£‡jµa¶7Z[[+++­°a£££ˆÎTaá_)J¥ÒŽŽŽiÓCOOÏ€€DÚ~0 ßÿýÍ›7¿ýöÛ}ûöó5·nÝŠ‹‹{A­ª¯¯‰D K—.ÅwȬEvØ.z½¾¼¼üÎ;‰‰‰ã,EQTjjjQQó3'/‚Ó§O+Š}ûöáן ;&Us4gÏžår¹7nœ„vByS 9BˆH$:qâć~8™m¦•§T*322 <È€«¹I[ÀByS¦¹É_ÀByS ¹©ZÀByãÒÜÝ»wžQsS¾€…ò ;^ìÝœU-`‡D"9uê”ÙhîY±ª,”ÙhîùkÎj°PdìTsÏkoΜO>ù$00Ð:°OP^YYÙðððÞ½{¡<Èànn\ Ø>úÈøŸdÛ–òJKKGFF <È@sÓg åAvš³£,”Ùé ¹ŠŠŠÖÖÖ×^{íEkÎÖ°Pdl[s¿úÕ¯x<Þ$Ô8=°Pd 9;ZÀBy€æìhû?•÷ûßÿÿ9²ö¢¹i¿€…ò ;Íý—3gÎ,Z´hÆ vxý¡<ÈØ…æìm åAvÀ5g· Ø'+ott4==Ý>•Ùç¬9¡P¸uëÖ©Õ°PdìBs„Gøàëoç‡~¨V«'PP«Õ>|Øúûhœ|8N^^žmµY(þë_ÿ²(;6" ° ;dÓìÙÿò,ü6Áàà Á`ðôôd±X· ÑÖÖ¦ÓéÜÝÝýýý™D™LÖÕÕÅf³9ÎÒ¥Kqgþ7E544ìÚµËx$M3úûû_}õÕÅ‹ûøø¬[·®¿¿q·!T*UzzzHHHkk«ñ¸½~ýúoû[¥R‰e,}}}÷ïß?räˆÁ`˜®}¬««KJJ’H$"‘h``àèÑ£ˆ» ñÊ+¯ðx¼ÐÐP>Ÿ/“ÉèĹsçîØ±cÍš5+W®„ìlƒÁðÃ?ˆÅb&E©Tööö*•JffS©T---Æy!r¹œIÑét"‘ˆ>’J¥z½^(2c…ÁÇÇ'==}æÌ™Ößljuâë뛚šÊb±|}}zzz0Ìl(|„‡SZZÊáp’’’ôz=“ÈápÆßlÈκ8sæLIIÉÇ###·nÝšPZZÊåróòò"##£¢¢!eeeG‹Åû÷ïß±c‡J¥¢,XpîÜ9BHSSÓŠ+222!Ç÷öö>}úôîÝ»A@@@QQ‘-öñY:¸~ýz毢¥¥åÕW_ÅH³¡ðÑÌž=»ªªª©©iâФÀqèÐ!“”îîîÙ³gkµZŠ¢N:Åãñèô]»v………Éd²ºººæææƒÁ@Q”^¯_¾|ùÿøG:ÛæÍ› éã‚‚‚¸¸8úø'?ùIFF]äÆl6»­­Í¤êÎÎÎÇ †‚‚‚þþþ tphhèèѣϱÏÒAš{÷îmÞ¼™®ýɱ˜è6?mŠÑg _VVVoo/EQ—/_f±XEÉd²˜‡ø/ù‹ÅîàÎΊP(cccô¼B¡ ¥Óœœ¢££=<<6lØPSSD?Od³Ù|>ÿ믿f²1§29ŽŒŒ¤‹DDDp¹ÜØbŸ±ƒCCCüôÓO¬åC±±±ÅÅÅO›b£Cô¹ŒÏØØØ÷Þ{/55õîÝ»OÛx|ôÄŠ ÊÊÊJIIáñxr¹Üø¿Î˜1ƒÙøJ¥Lº§§§ñ·V™‡ ̾†9fÍš56ÚÇ wP£Ñ¼õÖ[§Nš?¾õDü½÷Þ3ù¸ÏxRlwˆ>—ñyøðáï¿ÿžÏç×ÖÖBv6ŒÏ¶mÛRSSMöƒ™QUPP ‹½¼¼!­­­‰‰‰ô[®®®B¡¢Õj/^¼hü ü¡¡!úàêÕ«ÉÉÉóæÍ3©—|z½þ©v|'¹î ^¯ÏÈÈHKKsssëêêR«Õ¾¾¾...Sî°°° ¤Øè}–ñ©Ñh4 }Ìb±JKK×­[—””ôTÛ¯uQQQÑÞÞþÙgŸ±X,777@0::ÚÔÔäîî¾råÊøøøM›6¥§§óùüÜÜÜîîn.—ûúë¯Óe’““{{{.\Èãñ***®\¹C óçÏ 1ÿj÷—_~yþüyBÈ;3˜˜ø¢ïû&ÜÇ wðÀÅÅÅÆ‹ÁÛ·o¯^½ãÍ&ÂWUUuõêU¹\ž™™¹hÑ"BÈÌ™3«ªª~ö³Ÿ=Ý6áAõìþöõõ¥¥¥ýõ¯½uëVuuõÎ;_yå•J¥ÕjµZ­R©drvuu555Éd2“3 wuu F£ÕjU*EQ«V­ª¬¬‹ÅôKs”J¥Z­ÖëõjµZ­V¿ÐÏØÇ‰uP¡P¨T*NG÷Q.—ët:kx@aoCtÂãS§Ó©Õj“'KR©´££cü(pggEœ={ÖÓÓsûöíÌfGvv6³•k¼­îççgqgÖ¬Yôþˆ£££I‘'ìU9;;›l»Xm'ÖAãëŒ3&¡›¢Ï1|ôø4ß`™3gΜ9sÆßx<µ"–-[vçÎzûL£Ñœ9s&''çÙOKÏ¢Ó¸VÕA Q« î쬈øøx‹•““ãåå¥V«APPгOÅ!!!/¿üòô룵uCÔjÃÙY|>ŸÏç?Ǧ¦¦š<8›f}´ÂbˆZgø°ŒØ²€éöì¦ N÷¸´±*Æÿãˆæ¨T*›è#æZD£ÑØDøŒ쬎•+W–””X;ÝÜÜ&PÐÙÙÙÕÕÕ&ú¸bÅ Hs‚‚‚l"|&¼öÚkÓñO²vöì@vÙd@vÙd€ì²È ;€ì`rù´î¯¬×ûIEND®B`‚ldb-2.0.8/lib/talloc/doc/mainpage.dox0000660000000000000000000001073312520121120017272 0ustar rootroot00000000000000/** * @mainpage * * talloc is a hierarchical, reference counted memory pool system with * destructors. It is the core memory allocator used in Samba. * * @section talloc_download Download * * You can download the latest releases of talloc from the * talloc directory * on the samba public source archive. * * @section main-tutorial Tutorial * * You should start by reading @subpage libtalloc_tutorial, then reading the documentation of * the interesting functions as you go. * @section talloc_bugs Discussion and bug reports * * talloc does not currently have its own mailing list or bug tracking system. * For now, please use the * samba-technical * mailing list, and the * Samba bugzilla * bug tracking system. * * @section talloc_devel Development * You can download the latest code either via git or rsync. * * To fetch via git see the following guide: * * Using Git for Samba Development * * Once you have cloned the tree switch to the master branch and cd into the * lib/tevent directory. * * To fetch via rsync use this command: * * rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/talloc . * * @section talloc_preample Preamble * * talloc is a hierarchical, reference counted memory pool system with * destructors. * * Perhaps the biggest difference from other memory pool systems is that there * is no distinction between a "talloc context" and a "talloc pointer". Any * pointer returned from talloc() is itself a valid talloc context. This means * you can do this: * * @code * struct foo *X = talloc(mem_ctx, struct foo); * X->name = talloc_strdup(X, "foo"); * @endcode * * The pointer X->name would be a "child" of the talloc context "X" which is * itself a child of mem_ctx. So if you do talloc_free(mem_ctx) then it is all * destroyed, whereas if you do talloc_free(X) then just X and X->name are * destroyed, and if you do talloc_free(X->name) then just the name element of * X is destroyed. * * If you think about this, then what this effectively gives you is an n-ary * tree, where you can free any part of the tree with talloc_free(). * * If you find this confusing, then run the testsuite to watch talloc in * action. You may also like to add your own tests to testsuite.c to clarify * how some particular situation is handled. * * @section talloc_performance Performance * * All the additional features of talloc() over malloc() do come at a price. We * have a simple performance test in Samba4 that measures talloc() versus * malloc() performance, and it seems that talloc() is about 4% slower than * malloc() on my x86 Debian Linux box. For Samba, the great reduction in code * complexity that we get by using talloc makes this worthwhile, especially as * the total overhead of talloc/malloc in Samba is already quite small. * * @section talloc_named Named blocks * * Every talloc chunk has a name that can be used as a dynamic type-checking * system. If for some reason like a callback function you had to cast a * "struct foo *" to a "void *" variable, later you can safely reassign the * "void *" pointer to a "struct foo *" by using the talloc_get_type() or * talloc_get_type_abort() macros. * * @code * struct foo *X = talloc_get_type_abort(ptr, struct foo); * @endcode * * This will abort if "ptr" does not contain a pointer that has been created * with talloc(mem_ctx, struct foo). * * @section talloc_threading Multi-threading * * talloc itself does not deal with threads. It is thread-safe (assuming the * underlying "malloc" is), as long as each thread uses different memory * contexts. * * If two threads uses the same context then they need to synchronize in order * to be safe. In particular: * * - when using talloc_enable_leak_report(), giving directly NULL as a parent * context implicitly refers to a hidden "null context" global variable, so * this should not be used in a multi-threaded environment without proper * synchronization. In threaded code turn off null tracking using * talloc_disable_null_tracking(). * - the context returned by talloc_autofree_context() is also global so * shouldn't be used by several threads simultaneously without * synchronization. * */ ldb-2.0.8/lib/talloc/doc/stealing.png0000660000000000000000000001552212406075657017344 0ustar rootroot00000000000000‰PNG  IHDR±ž3?£±sRGB®Îé pHYs  šœtIMEÜ 1r·¯ÃtEXtCommentCreated with GIMPW¿IDATxÚíyXSWþÆoB$ˆa‘¨ 2¸Œ”·¢c nTÁAáí¨ƒ:—VpTÔ‚âÂT;µ£ŽâÒªàŠJÇÇE¨e!@ âŽÂ6lYÉýý‘yòC B–›ð~þð1'÷ž“œóý¾Ü÷Üsnh$I‚ :º ‰Mh"@š½€AÙOÖÐÐPZZúúõkùËþýû{xx¸¸¸0  MMM¥¥¥/_¾”/kc2™Çïׯ:Ç¡Qm}"‡ÃùñÇ[ZZlmm===]\\h4AÍÍÍ\.·¬¬L"‘x{{/\¸ÐÂÂãôů¿þzúô醆‹5zôh‚ Z[[KKKKKKE"ј1cBCCˆî‚&ªÃ­[·®^½úÛßþ688¸ë0zòäIZZš™™Ytt´µµ5Fè’G¥¦¦Ž5*$$ÄÖÖ¶‹#‹ŠŠRSSe2YTT›ÍF×AU¥¾¾~ûöí>>>áááò«BU¨¬¬LLLœ6mÚÂ… 1@´´´ìرÃÕÕuÅŠtºªsñuuu»ví3f̲eËЇÐÄî),,üÇ?þ±mÛ¶Áƒ«qú™3g¸\n\\œÜ¹ %ÊËË÷ìÙ³yófggg5N¿zõêƒLMMÑ™ÐÄNyøðá•+WvïÞÝEËÏÏONN>pàfµ–ÈÏÏÿ׿þ•””Äd2Õ®¤¬¬,))éÀæææèRh¢8ÎÑ£G÷ï߯º_äääo¿ý–:=>lØ0mÔ\[[›œœŒØÕ/_¾LLLüþûï{¿æáÅ‹‰‰‰‡VÝzS–°°0õ.™©ᤞhjjŠŒŒ”H$šªðÎ;GŽ!)Cll¬ÁÕ >D$ýùÏšª077wïÞ½FÐ3ÆázûcµsçÎÍ›7kp±áŒ3x<Þ¯¿þŠë AöíÛ·nÝ:333MUèíímjjúŸÿü}KMô£‰yyyÆ srrÒlµ_}õÕßÿþw *Ðåååt:}Ô¨Qš­6** ³ÐÄ÷8vìXDD„Æ«5337nÜãÇ1®@#:thõêÕ¯ÖÄÄdæÌ™ÿþ÷¿ÑÃÐD‚ ˆŠŠŠ#FhiEÂÒ¥K/]º„q½§±±qÀ€ZÚ…tëÖ-t24‘ âìÙ³aaaZªÜÔÔÔÄÄD(R­£[[[/\¸°nÝ:Äœ¡páÂím Óé¶¶¶µµµFÓ]FázÐÄÊÊJ–ÉdUUU=ªêÔ©YYYTëh’$Åbñ 5†BqqñèÑ£µ¨~~~Æt©h4N×}Çõè^óÒ¥K<Ø£&&MšôË/¿P­£-,,&Ož ¡1¤ÜèÉB5ÕËË«  ÀhºËh"\ךøîÝ»®o7Ëd²ÒÒR>Ÿ¯¸ ·±±!B$•””(V˜WWW·´´(­ÁÚÚº¡¡Ê^SSSPP ‹%ÍÍÍùùù@Q"*++AQQäI÷‚®w›t¨ªÇ*ƒÁhkk3ÊÞ3è×õ³«ªªºØ×üàÁƒ+W®˜››gddDEEÙÙÙåææ¾|ù233sÖ¬Y_ýuLLÌÚµkóòòöîÝûÍ7ßtö¸°ÞoŒÑÇŽûé§ŸŠŠŠ¤Ré;wØlvLLŒMNN—Ë-((077?þü_|úèÑ£/^Ó¬“¡Àãñºx’Mºÿþ¼¼¼¨¨(Ub•ÊÚw#\ÇkÄ333¯]»¦ô-‡3kÖ,™LF’dEEÅåË—I’ øî»ïçš™™=~ü8""¢ë}TØéñágxñâ…<ä3/&LˆŽŽ …÷îÝ#IR&“ýæ7¿ÉÈȼdÉ’>ú¨¾¾þöíÛØÇ¢{ŠŠŠNž<©^ ª«=”ÆẾNd2™Ý>þ¼§§§ü/§££c```‡|}}׬Y3sæÌÒÒÒ®÷PíA¹íùøã ‚èׯ߂ =zÄd2“’’„B!NWx1&“9kÖ,‹õÉ'ŸàªM÷0™ÌöF¯Gªz¬R9Pûl„ëz>ÑÆÆ¦®®®³©Æêêê®Og³ÙC† 9zô¨!ÆJ‡hkk7n\VVV@@À矾eËWWW™L¦8•Ò#½ TCÕ¾áºÖD—W¯^)}kúôééééïÞ½{ïóÑéŠùéóçÏ[YY¥¥¥%&&>|ø°³&„B¡w§j‘H$ŸZ&B"‘deeýå/IOO÷ôôd³Ù|>ŸËå*¢J&“µ cº¸S×m ª«F†qD¸®½3ƒÁH$Jß ËÌÌôññY¶lYsssHHÈ”)Süýýããã Î;wéÒ%¶}ûöE‹ýðÃJ¯ºóòòÆOÁ¾njjrssóööþä“O,--9booïççàè蘑‘1{öì§OŸfgg0ÀËËkÁ‚P(*\õ¨¨)))/^üñǻղ²2777cê1#‰pÝOaÆÅÅ566vönEEÅÇ+++%555B¡°ý12™L$‰Åb¥5ÄÇÇ×ÖÖRpZ H¥Òºººêêêöåõõõ555$I …B‰D"•Jåÿ‘H$J§çqE7ìÛ·¯¢¢¢7Úu¬~÷ÝwåååÆtÅ8"\ûX-ZtîܹÎÞuttœ:ujûõ:¶¶¶nL£ÑLMM•>U›$I§X)F)ÌÌÌLLL¬­­ Ô¾œÅbÉêˆÉd2 ù 5'úaaa?üðCoµëX-++1b„1õ˜qD¸4q̘1Ú[¾ûömä3è=NNNïÞ½ÓҲ꼼¼>úLAôó¬0???m<(‰$ÉË—/Ï›7ã 4åiΞ=«šOœ8±xñbô04ñÌŸ??==]ãO¯9}útpp°Qî zaÊ”)¹¹¹ß*zýúu___ü¤4ñ=Ö¯_¿mÛ6 Vøüùó‚‚‚3f`PÙ¸qã–-[4XaUUUFF~”œ²0ôÕ°««ë”)SŽ?¾|ùòÞ×ÖØØ¸wïÞýû÷S§gkjjÒÒÒ´Qsss3Wg888,Z´èÀk×®í}mB¡pÇŽ‰‰‰FÐ3Æázþ}ç”””þýû‡††öR7mÚ´cÇ;;;êDLii©–†ÖÚÚÚÈîWRŸ‹/ÖÖÖ®\¹²7•‚˜˜˜72Äú¤Gžššb®÷UN§NJHHJ¥ê^\\ü§?ý‰Ïçc=Ð*W®\Ù´i“H$Rïô/^,_¾üíÛ·}³÷ hQ-Cïm–,Y’——¹~ýzÕO”J¥ÉÉÉUUU‡ÂÖ` mæÏŸïîîþÅ_¬^½ÚËË«G—'Ož,..>xð`×ÏdT@ÏÞ¹½­8xð`}}ýªU«\\\º>¸­­íÂ… ™™™Ÿþùĉ1Š@gH$’Ç¿~ý:""¢Û?á2™,##ã§Ÿ~Z¸pa¿û·iÓ&C™E¥Š&*fSRRÊÊʆ âëë;zôh‹¥ÐÁ—/_æææÊªtÁ‚òG {Z[[O:ÅápØl¶¯¯ïرc[§H’|õêU^^^vv¶T*;w.6@5@eeevvvIIIcc£ü‰Ç4ÍÅÅeܸq&LÀÂ.@ø|~vvvqqq}}½|a,I’ÎÎÎcÇŽõññùp«4š¨¶oß‹¿@u£ÐD€&4 ‰Mh"@šÐD€&4 ‰Mh"@šÐD€&4 ‰M#†.º§¸¸øÆ#GŽœ?>zà:2™¬ªªJõãMMM¯_¿ž——‡®ÐD`„,]ºôàÁƒªïêêêââ‚~ÐD` H$‡S^^.“Éä%­­­666ФRiaaaSSSû³š››óóó:PýÌ'ÖÔÔäçç«x°@ ¸wÒGµ´´œ4iÆU{¼yófÆ Ë–-+..ÎÍÍ={öìµk×rss_¾|™™™ùÍ7ߤ¥¥1Œ1cƬ\¹2!!ÁÏÏO"‘ÄÄÄØØØäääp¹Ü‚‚ssóÞøô·oß655 8ÐÉɉF£aPôBIIIEE…Š‹Åâ[·n©xððáÃGŽÙ·®srr8ŽŠûûû«(ˆA=zÁªUÎ;Çf³çÎûå—_®ZµŠ ˆÏ>ûlìØ±Ë—/¿|ùriié•+W6lØ0kÖ¬Õ«WÇÄÄÈU,00pË–-W¯^555½ÿ~o>@qqñ‹/jjjÊËËËÊÊ0"ú¢G¹6gÎlkkKIIés׉Aüîw¿ûøã5^ííÛ·¬ZeêÔ©qqqYYYaaaÞ½wï^ccc|||ÿþýX,AL&ÓÙÙ9))I(Òét>Ÿß›‹Äºº:Å˪ª*ggg333Œ‹î155õóóÓxµR©ôáÇ}Q2yòäòòòëׯ§¥¥íß¿¿ªªÊÒÒRñn]]ݰaönÝÚþ”¬¬¬U«Vݹs‡Ífçææ*f!Õ@"‘$Ù¾äÝ»w#FŒÀ¸ÃöÎÀp9räÈàÁƒW¬XqãÆ ‡––‚ ètºü?“&MÊÊÊR¬Ë‘Ë_zzº§§'›Íæóù\.W.j2™L qd2™í%˜ ùÜ"Æà:è‡ÒÒÒèèè9sæ<}ú4**ŠÍfáïï_XXxäÈ‘ÌÌÌI“&…††š˜˜¸¹¹-_¾ÜÏÏ/(((888 ÀÑÑ1##ƒÉdfgg³X¬™3göt eðàÁÏž=S¼$I’ÃáxyyÁAh"Ðûöí{þüyMMMdd¤µµµ¼0:::<<ÜÒÒ’Édž8q¢²²òíÛ·cÇŽ•딿¿EEE[[›­­íâÅ‹MLLÄbqHHI’j\*:::VVVÊ/KåˆÅâ§OŸŽ?žÉdb€€Qyçúúúµk×^¼xCYäW“'OV¢[[[…$988L˜0¡ý…‹Å²µµ•›_ƒannÎ`0úõ맆ŠÑh4ww÷Kp„Ba^^L4²Ø¨4Q$ÅÄÄÌž=ÛÊÊ ºÀÊÊÊÕÕµC¡X,ÎÏϯ©©Aÿ ‹Ä;ŸýôÓ±cÇîÛ·/00ðÃÂ˃ÓÚÚŠNÐc+Má­[·vVïÜ ×¯_wuu•ß[¤ÓéAAA7oÞTZˆ@Jé0¨Â]”C»÷>í·µÚÙÙYYY)-Dð4hШQ£ÐTKá.Êá•Ð~³×´iÓ’’’x<ž|›DQQÑ¢E‹>,Dð©ÇÀétÞÙI’dcc£X,îPÞ¯_?77·Aƒaˆõ›ÅJS¸‹rhbGnÞ¼ùèÑ#ssóÌÌÌiÓ¦ùûûGFFÅÇÇWTT¸¸¸üñ$Bi!Pƒ¡C‡ôç/++ûPÍÍÍ›g€~³¸³î¬šØ‘iÓ¦åçç+6{Ñh´ýû÷WTT¼yó&00PþÈ)‚ ”‚¾Ç«¬¬ìPhmmíéé©ú£6V³¸³î¬šØ¥{¼œœœœœœT)}©TZ^^Þ¡ÐÆÆfôèÑ=`|˜Åe+•³1 Œ7oÞH$’ö%VVVDM}×8¿çt OOO"€&‚¾ˆH$‰DíK\\\ðˆ0M}SSÓö—„t:]¾¤M¡·{,‡¾víZû’¶¶¶=ËDéñ\.ƒjÄÐh´!C†¼~ýZþrĈ¸Ñ¬/ZZZbccUÉÊe±L&Óó…?I¢££ëêê>,ß¶m›@ ø°üoû[^^ úõõõoß¾ýïÿ‹® Ú¸DEE)}+66ViyDD„P(¤Ô· ŠwNKKóõõíÑÕ5kÖ8p„ꃰX,'''ìì¤Û·o‹‹ëÑ)7nŒÇ|bGx<ÞÝ»w{ºÅ‡Á`lÚ´iÏž=ˆEôÎ… |||zº«ÒÝÝÝÎÎîÁƒÐÄ÷HHHøúë¯Õ8ÑÃÃÃÜÜüñãLjHôŸÏ¿uëVxx¸ç®Y³æÄ‰šøÿ®yÚ´ivvvê¾~ýúï¿ÿ=²sçNõ.k‚ Óé7nܹs'4Q}×Ü8h Î5SÖAëYãââÔþó €Þ©®®VÛ5SÓAëSSSSýüüÔvÍpÐè]»võþ²†RZošÈãñîÝ»§©ÇIÂA`ˆ®™‚Zoš¨×  €¡»fª9hýh¢]34íš©æ õ ‰šuÍpкk¦”ƒÖƒ&jÜ5ÃA`è®™:Zך¨%×  €A»fê8hj¢ö\34†îš)â uª‰ZuÍpкk¦‚ƒÖ&¦¦¦Î;W«®ƒvÍTpÐ:ÒD¹k ÔÙƒƒÀ]³Þ´Ž4Qg®CwÍúuкÐD»f8h Ú5ë×Ak]uïšá 0t׬G­uMÔ‹k†ƒÀÐ]³¾´v5Q®ƒvÍúrÐZÔDýºf8h Ý5ëÅAkQõîšá 0t׬{­-M¤ˆk†ƒÀ ]³î´V4‘ÇãÝ¿Ÿ ®µ]óĉ©àš;8èAƒiÕAkEãââvìØAÁaöðð°°°€ƒ@×FÁÏ­U­yM¤ knϺuëà 0,׬K­aM¤¦kþÐAïÞ½q€¹ætff¦hâÖ­[©éš;8hKKK8h”ºæ›7oRÓ5wpÐÇŽkii¡´&¦¦¦PÖ5ÃA Škާþç¤Óéýë_©«‰ÔwÍpкkÖƒ¦‘$©xQVVvéÒ%õ*zöì›Í0`€üåŠ+lmm»=+''çþýûÝÖõõõ555$I …B‰D"•JI’"‘¨­­M$‰D¢§?~¼¤¤„T]»v544tÛbkk«P(”J¥ò[ZZäCAll,©JTúy<ÞÏ?ÿÜÚÚªz=èÕ#¼ë,ÖxNé>‹»NáÎêé~š“Åb)f1…Šçjã1‚¶Ø¿Å»¦¦¦oTéw´··×ø¬z¡of±z)Œg@4 ‰MUy½ýéÓ§Õþ9SµµµŸ~ú©*G>Samba and SSSD developers over the years. These will help you to write code which is better, easier to debug and with as few (hopefully none) memory leaks as possible. @section bp-hierarchy Keep the context hierarchy steady The talloc is a hierarchy memory allocator. The hierarchy nature is what makes the programming more error proof. It makes the memory easier to manage and to free. Therefore, the first thing we should have on our mind is: always project your data structures into the talloc context hierarchy. That means if we have a structure, we should always use it as a parent context for its elements. This way we will not encounter any troubles when freeing the structure or when changing its parent. The same rule applies for arrays. For example, the structure user from section @ref context-hierarchy should be created with the context hierarchy illustrated on the next image. @image html context_tree.png @section bp-tmpctx Every function should use its own context It is a good practice to create a temporary talloc context at the function beginning and free the context just before the return statement. All the data must be allocated on this context or on its children. This ensures that no memory leaks are created as long as we do not forget to free the temporary context. This pattern applies to both situations - when a function does not return any dynamically allocated value and when it does. However, it needs a little extension for the latter case. @subsection bp-tmpctx-1 Functions that do not return any dynamically allocated value If the function does not return any value created on the heap, we will just obey the aforementioned pattern. @code int bar() { int ret; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } /* allocate data on tmp_ctx or on its descendants */ ret = EOK; done: talloc_free(tmp_ctx); return ret; } @endcode @subsection bp-tmpctx-2 Functions returning dynamically allocated values If our function returns any dynamically allocated data, its first parameter should always be the destination talloc context. This context serves as a parent for the output values. But again, we will create the output values as the descendants of the temporary context. If everything goes well, we will change the parent of the output values from the temporary to the destination talloc context. This pattern ensures that if an error occurs (e.g. I/O error or insufficient amount of the memory), all allocated data is freed and no garbage appears on the destination context. @code int struct_foo_init(TALLOC_CTX *mem_ctx, struct foo **_foo) { int ret; struct foo *foo = NULL; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } foo = talloc_zero(tmp_ctx, struct foo); /* ... */ *_foo = talloc_steal(mem_ctx, foo); ret = EOK; done: talloc_free(tmp_ctx); return ret; } @endcode @section bp-null Allocate temporary contexts on NULL As it can be seen on the previous listing, instead of allocating the temporary context directly on mem_ctx, we created a new top level context using NULL as the parameter for talloc_new() function. Take a look at the following example: @code char *create_user_filter(TALLOC_CTX *mem_ctx, uid_t uid, const char *username) { char *filter = NULL; char *sanitized_username = NULL; /* tmp_ctx is a child of mem_ctx */ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return NULL; } sanitized_username = sanitize_string(tmp_ctx, username); if (sanitized_username == NULL) { talloc_free(tmp_ctx); return NULL; } filter = talloc_aprintf(tmp_ctx,"(|(uid=%llu)(uname=%s))", uid, sanitized_username); if (filter == NULL) { return NULL; /* tmp_ctx is not freed */ (*@\label{lst:tmp-ctx-3:leak}@*) } /* filter becomes a child of mem_ctx */ filter = talloc_steal(mem_ctx, filter); talloc_free(tmp_ctx); return filter; } @endcode We forgot to free tmp_ctx before the return statement in the filter == NULL condition. However, it is created as a child of mem_ctx context and as such it will be freed as soon as the mem_ctx is freed. Therefore, no detectable memory leak is created. On the other hand, we do not have any way to access the allocated data and for all we know mem_ctx may exist for the lifetime of our application. For these reasons this should be considered as a memory leak. How can we detect if it is unreferenced but still attached to its parent context? The only way is to notice the mistake in the source code. But if we create the temporary context as a top level context, it will not be freed and memory diagnostic tools (e.g. valgrind) are able to do their job. @section bp-pool Temporary contexts and the talloc pool If we want to take the advantage of the talloc pool but also keep to the pattern introduced in the previous section, we are unable to do it directly. The best thing to do is to create a conditional build where we can decide how do we want to create the temporary context. For example, we can create the following macros: @code #ifdef USE_POOL_CONTEXT #define CREATE_POOL_CTX(ctx, size) talloc_pool(ctx, size) #define CREATE_TMP_CTX(ctx) talloc_new(ctx) #else #define CREATE_POOL_CTX(ctx, size) talloc_new(ctx) #define CREATE_TMP_CTX(ctx) talloc_new(NULL) #endif @endcode Now if our application is under development, we will build it with macro USE_POOL_CONTEXT undefined. This way, we can use memory diagnostic utilities to detect memory leaks. The release version will be compiled with the macro defined. This will enable pool contexts and therefore reduce the malloc() calls, which will end up in a little bit faster processing. @code int struct_foo_init(TALLOC_CTX *mem_ctx, struct foo **_foo) { int ret; struct foo *foo = NULL; TALLOC_CTX *tmp_ctx = CREATE_TMP_CTX(mem_ctx); /* ... */ } errno_t handle_request(TALLOC_CTX mem_ctx) { int ret; struct foo *foo = NULL; TALLOC_CTX *pool_ctx = CREATE_POOL_CTX(NULL, 1024); ret = struct_foo_init(mem_ctx, &foo); /* ... */ } @endcode */ ldb-2.0.8/lib/talloc/doc/tutorial_context.dox0000660000000000000000000001577712406075657021167 0ustar rootroot00000000000000/** @page libtalloc_context Chapter 1: Talloc context @section context Talloc context The talloc context is the most important part of this library and is responsible for every single feature of this memory allocator. It is a logical unit which represents a memory space managed by talloc. From the programmer's point of view, the talloc context is completely equivalent to a pointer that would be returned by the memory routines from the C standard library. This means that every context that is returned from the talloc library can be used directly in functions that do not use talloc internally. For example we can do the following: @code char *str1 = strdup("I am NOT a talloc context"); char *str2 = talloc_strdup(NULL, "I AM a talloc context"); printf("%d\n", strcmp(str1, str2) == 0); free(str1); talloc_free(str2); /* we can not use free() on str2 */ @endcode This is possible because the context is internally handled as a special fixed-length structure called talloc chunk. Each chunk stores context metadata followed by the memory space requested by the programmer. When a talloc function returns a context (pointer), it will in fact return a pointer to the user space portion of the talloc chunk. If we to manipulate this context using talloc functions, the talloc library transforms the user-space pointer back to the starting address of the chunk. This is also the reason why we were unable to use free(str2) in the previous example - because str2 does not point at the beginning of the allocated block of memory. This is illustrated on the next image: @image html context.png The type TALLOC_CTX is defined in talloc.h to identify a talloc context in function parameters. However, this type is just an alias for void and exists only for semantical reasons - thus we can differentiate between void * (arbitrary data) and TALLOC_CTX * (talloc context). @subsection metadata Context meta data Every talloc context carries several pieces of internal information along with the allocated memory: - name - which is used in reports of context hierarchy and to simulate a dynamic type system, - size of the requested memory in bytes - this can be used to determine the number of elements in arrays, - attached destructor - which is executed just before the memory block is about to be freed, - references to the context - children and parent contexts - create the hierarchical view on the memory. @section context-hierarchy Hierarchy of talloc context Every talloc context contains information about its parent and children. Talloc uses this information to create a hierarchical model of memory or to be more precise, it creates an n-ary tree where each node represents a single talloc context. The root node of the tree is referred to as a top level context - a context without any parent. This approach has several advantages: - as a consequence of freeing a talloc context, all of its children will be properly deallocated as well, - the parent of a context can be changed at any time, which results in moving the whole subtree under another node, - it creates a more natural way of managing data structures. @subsection Example We have a structure that stores basic information about a user - his/her name, identification number and groups he/she is a member of: @code struct user { uid_t uid; char *username; size_t num_groups; char **groups; }; @endcode We will allocate this structure using talloc. The result will be the following context tree: @image html context_tree.png @code /* create new top level context */ struct user *user = talloc(NULL, struct user); user->uid = 1000; user->num_groups = N; /* make user the parent of following contexts */ user->username = talloc_strdup(user, "Test user"); user->groups = talloc_array(user, char*, user->num_groups); for (i = 0; i < user->num_groups; i++) { /* make user->groups the parent of following context */ user->groups[i] = talloc_asprintf(user->groups, "Test group %d", i); } @endcode This way, we have gained a lot of additional capabilities, one of which is very simple deallocation of the structure and all of its elements. With the C standard library we need first to iterate over the array of groups and free every element separately. Then we must deallocate the array that stores them. Next we deallocate the username and as the last step free the structure itself. But with talloc, the only operation we need to execute is freeing the structure context. Its descendants will be freed automatically. @code talloc_free(user); @endcode @section keep-hierarchy Always keep the hieararchy steady! The talloc is a hierarchy memory allocator. The hierarchy nature is what makes the programming more error proof. It makes the memory easier to manage and to free. Therefore, the first thing we should have on our mind is: always project our data structures into the talloc context hierarchy. That means if we have a structure, we should always use it as a parent context for its elements. This way we will not encounter any troubles when freeing this structure or when changing its parent. The same rule applies for arrays. @section creating-context Creating a talloc context Here are the most important functions that create a new talloc context. @subsection type-safe Type-safe functions It allocates the size that is necessary for the given type and returns a new, properly-casted pointer. This is the preferred way to create a new context as we can rely on the compiler to detect type mismatches. The name of the context is automatically set to the name of the data type which is used to simulate a dynamic type system. @code struct user *user = talloc(ctx, struct user); /* initialize to default values */ user->uid = 0; user->name = NULL; user->num_groups = 0; user->groups = NULL; /* or we can achieve the same result with */ struct user *user_zero = talloc_zero(ctx, struct user); @endcode @subsection zero-length Zero-length contexts The zero-length context is basically a context without any special semantical meaning. We can use it the same way as any other context. The only difference is that it consists only of the meta data about the context. Therefore, it is strictly of type TALLOC_CTX*. It is often used in cases where we want to aggregate several data structures under one parent (zero-length) context, such as a temporary context to contain memory needed within a single function that is not interesting to the caller. Allocating on a zero-length temporary context will make clean-up of the function simpler. @code TALLOC_CTX *tmp_ctx = NULL; struct foo *foo = NULL; struct bar *bar = NULL; /* new zero-length top level context */ tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } foo = talloc(tmp_ctx, struct foo); bar = talloc(tmp_ctx, struct bar); /* free everything at once */ talloc_free(tmp_ctx); @endcode @subsection context-see-also See also - talloc_size() - talloc_named() - @ref talloc_array - @ref talloc_string */ ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox0000660000000000000000000000765012406075657021425 0ustar rootroot00000000000000/** @page libtalloc_debugging Chapter 6: Debugging Although talloc makes memory management significantly easier than the C standard library, developers are still only humans and can make mistakes. Therefore, it can be handy to know some tools for the inspection of talloc memory usage. @section log-abort Talloc log and abort We have already encountered the abort function in section @ref dts. In that case it was used when a type mismatch was detected. However, talloc calls this abort function in several more situations: - when the provided pointer is not a valid talloc context, - when the meta data is invalid - probably due to memory corruption, - and when an access after free is detected. The third one is probably the most interesting. It can help us with detecting an attempt to double-free a context or any other manipulation with it via talloc functions (using it as a parent, stealing it, etc.). Before the context is freed talloc sets a flag in the meta data. This is then used to detect the access after free. It basically works on the assumption that the memory stays unchanged (at least for a while) even when it is properly deallocated. This will work even if the memory is filled with the value specified in TALLOC_FREE_FILL environment variable, because it fills only the data part and leaves the meta data intact. Apart from the abort function, talloc uses a log function to provide additional information to the aforementioned violations. To enable logging we shall set the log function with one of: - talloc_set_log_fn() - talloc_set_log_stderr() The following code is a sample output of accessing a context after it has been freed: @code talloc_set_log_stderr(); TALLOC_CTX *ctx = talloc_new(NULL); talloc_free(ctx); talloc_free(ctx); results in: talloc: access after free error - first free may be at ../src/main.c:55 Bad talloc magic value - access after free @endcode Another example is an invalid context: @code talloc_set_log_stderr(); TALLOC_CTX *ctx = talloc_new(NULL); char *str = strdup("not a talloc context"); talloc_steal(ctx, str); results in: Bad talloc magic value - unknown value @endcode @section reports Memory usage reports Talloc can print reports of memory usage of a specified talloc context to a file (to stdout or stderr). The report can be simple or full. The simple report provides information only about the context itself and its direct descendants. The full report goes recursively through the entire context tree. See: - talloc_report() - talloc_report_full() We will use the following code to retrieve the sample report: @code struct foo { char *str; }; TALLOC_CTX *ctx = talloc_new(NULL); char *str = talloc_strdup(ctx, "my string"); struct foo *foo = talloc_zero(ctx, struct foo); foo->str = talloc_strdup(foo, "I am Foo"); char *str2 = talloc_strdup(foo, "Foo is my parent"); /* print full report */ talloc_report_full(ctx, stdout); @endcode It will print a full report of ctx to the standard output. The message should be similar to: @code full talloc report on 'talloc_new: ../src/main.c:82' (total 46 bytes in 5 blocks) struct foo contains 34 bytes in 3 blocks (ref 0) 0x1495130 Foo is my parent contains 17 bytes in 1 blocks (ref 0) 0x1495200 I am Foo contains 9 bytes in 1 blocks (ref 0) 0x1495190 my string contains 10 bytes in 1 blocks (ref 0) 0x14950c0 @endcode We can notice in this report that something is wrong with the context containing struct foo. We know that the structure has only one string element. However, we can see in the report that it has two children. This indicates that we have either violated the memory hierarchy or forgotten to free it as temporary data. Looking into the code, we can see that "Foo is my parent" should be attached to ctx. See also: - talloc_enable_null_tracking() - talloc_disable_null_tracking() - talloc_enable_leak_report() - talloc_enable_leak_report_full() */ ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox0000660000000000000000000000464112406075657022050 0ustar rootroot00000000000000/** @page libtalloc_destructors Chapter 4: Using destructors @section destructors Using destructors Destructors are well known methods in the world of object oriented programming. A destructor is a method of an object that is automatically run when the object is destroyed. It is usually used to return resources taken by the object back to the system (e.g. closing file descriptors, terminating connection to a database, deallocating memory). With talloc we can take the advantage of destructors even in C. We can easily attach our own destructor to a talloc context. When the context is freed, the destructor will run automatically. To attach/detach a destructor to a talloc context use: talloc_set_destructor(). @section destructors-example Example Imagine that we have a dynamically created linked list. Before we deallocate an element of the list, we need to make sure that we have successfully removed it from the list. Normally, this would be done by two commands in the exact order: remove it from the list and then free the element. With talloc, we can do this at once by setting a destructor on the element which will remove it from the list and talloc_free() will do the rest. The destructor would be: @code int list_remove(void *ctx) { struct list_el *el = NULL; el = talloc_get_type_abort(ctx, struct list_el); /* remove element from the list */ } @endcode GCC version 3 and newer can check for the types during the compilation. So if it is our major compiler, we can use a more advanced destructor: @code int list_remove(struct list_el *el) { /* remove element from the list */ } @endcode Now we will assign the destructor to the list element. We can do this directly in the function that inserts it. @code struct list_el* list_insert(TALLOC_CTX *mem_ctx, struct list_el *where, void *ptr) { struct list_el *el = talloc(mem_ctx, struct list_el); el->data = ptr; /* insert into list */ talloc_set_destructor(el, list_remove); return el; } @endcode Because talloc is a hierarchical memory allocator, we can go a step further and free the data with the element as well: @code struct list_el* list_insert_free(TALLOC_CTX *mem_ctx, struct list_el *where, void *ptr) { struct list_el *el = NULL; el = list_insert(mem_ctx, where, ptr); talloc_steal(el, ptr); return el; } @endcode */ ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox0000660000000000000000000000632112406075657020256 0ustar rootroot00000000000000/** @page libtalloc_dts Chapter 3: Dynamic type system @section dts Dynamic type system Generic programming in the C language is very difficult. There is no inheritance nor templates known from object oriented languages. There is no dynamic type system. Therefore, generic programming in this language is usually done by type-casting a variable to void* and transferring it through a generic function to a specialized callback as illustrated on the next listing. @code void generic_function(callback_fn cb, void *pvt) { /* do some stuff and call the callback */ cb(pvt); } void specific_callback(void *pvt) { struct specific_struct *data; data = (struct specific_struct*)pvt; /* ... */ } void specific_function() { struct specific_struct data; generic_function(callback, &data); } @endcode Unfortunately, the type information is lost as a result of this type cast. The compiler cannot check the type during the compilation nor are we able to do it at runtime. Providing an invalid data type to the callback will result in unexpected behaviour (not necessarily a crash) of the application. This mistake is usually hard to detect because it is not the first thing which comes the mind. As we already know, every talloc context contains a name. This name is available at any time and it can be used to determine the type of a context even if we lose the type of a variable. Although the name of the context can be set to any arbitrary string, the best way of using it to simulate the dynamic type system is to set it directly to the type of the variable. It is recommended to use one of talloc() and talloc_array() (or its variants) to create the context as they set its name to the name of the given type automatically. If we have a context with such as a name, we can use two similar functions that do both the type check and the type cast for us: - talloc_get_type() - talloc_get_type_abort() @section dts-examples Examples The following example will show how generic programming with talloc is handled - if we provide invalid data to the callback, the program will be aborted. This is a sufficient reaction for such an error in most applications. @code void foo_callback(void *pvt) { struct foo *data = talloc_get_type_abort(pvt, struct foo); /* ... */ } int do_foo() { struct foo *data = talloc_zero(NULL, struct foo); /* ... */ return generic_function(foo_callback, data); } @endcode But what if we are creating a service application that should be running for the uptime of a server, we may want to abort the application during the development process (to make sure the error is not overlooked) and try to recover from the error in the customer release. This can be achieved by creating a custom abort function with a conditional build. @code void my_abort(const char *reason) { fprintf(stderr, "talloc abort: %s\n", reason); #ifdef ABORT_ON_TYPE_MISMATCH abort(); #endif } @endcode The usage of talloc_get_type_abort() would be then: @code talloc_set_abort_fn(my_abort); TALLOC_CTX *ctx = talloc_new(NULL); char *str = talloc_get_type_abort(ctx, char); if (str == NULL) { /* recovery code */ } /* talloc abort: ../src/main.c:25: Type mismatch: name[talloc_new: ../src/main.c:24] expected[char] */ @endcode */ ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox0000660000000000000000000000267612520121120022164 0ustar rootroot00000000000000/** @page libtalloc_tutorial The Tutorial @section introduction Introduction Talloc is a hierarchical, reference counted memory pool system with destructors. It is built atop the C standard library and it defines a set of utility functions that altogether simplifies allocation and deallocation of data, especially for complex structures that contain many dynamically allocated elements such as strings and arrays. The main goals of this library are: removing the needs for creating a cleanup function for every complex structure, providing a logical organization of allocated memory blocks and reducing the likelihood of creating memory leaks in long-running applications. All of this is achieved by allocating memory in a hierarchical structure of talloc contexts such that deallocating one context recursively frees all of its descendants as well. @section main-features Main features - An open source project - A hierarchical memory model - Natural projection of data structures into the memory space - Simplifies memory management of large data structures - Automatic execution of a destructor before the memory is freed - Simulates a dynamic type system - Implements a transparent memory pool @section toc Table of contents: @subpage libtalloc_context @subpage libtalloc_stealing @subpage libtalloc_dts @subpage libtalloc_destructors @subpage libtalloc_pools @subpage libtalloc_debugging @subpage libtalloc_bestpractices @subpage libtalloc_threads */ ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox0000660000000000000000000000711412406075657020621 0ustar rootroot00000000000000/** @page libtalloc_pools Chapter 5: Memory pools @section pools Memory pools Allocation of a new memory is an expensive operation and large programs can contain thousands of calls of malloc() for a single computation, where every call allocates only a very small amount of the memory. This can result in an undesirable slowdown of the application. We can avoid this slowdown by decreasing the number of malloc() calls by using a memory pool. A memory pool is a preallocated memory space with a fixed size. If we need to allocate new data we will take the desired amount of the memory from the pool instead of requesting a new memory from the system. This is done by creating a pointer that points inside the preallocated memory. Such a pool must not be reallocated as it would change its location - pointers that were pointing inside the pool would become invalid. Therefore, a memory pool requires a very good estimate of the required memory space. The talloc library contains its own implementation of a memory pool. It is highly transparent for the programmer. The only thing that needs to be done is an initialization of a new pool context using talloc_pool() - which can be used in the same way as any other context. Refactoring of existing code (that uses talloc) to take the advantage of a memory pool is quite simple due to the following properties of the pool context: - if we are allocating data on a pool context, it takes the desired amount of memory from the pool, - if the context is a descendant of the pool context, it takes the space from the pool as well, - if the pool does not have sufficient portion of memory left, it will create a new non-pool context, leaving the pool intact @code /* allocate 1KiB in a pool */ TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); /* Take 512B from the pool, 512B is left there */ void *ptr = talloc_size(pool_ctx, 512); /* 1024B > 512B, this will create new talloc chunk outside the pool */ void *ptr2 = talloc_size(ptr, 1024); /* The pool still contains 512 free bytes * this will take 200B from them. */ void *ptr3 = talloc_size(ptr, 200); /* This will destroy context 'ptr3' but the memory * is not freed, the available space in the pool * will increase to 512B. */ talloc_free(ptr3); /* This will free memory taken by 'pool_ctx' * and 'ptr2' as well. */ talloc_free(pool_ctx); @endcode The above given is very convenient, but there is one big issue to be kept in mind. If the parent of a talloc pool child is changed to a parent that is outside of this pool, the whole pool memory will not be freed until the child is freed. For this reason we must be very careful when stealing a descendant of a pool context. @code TALLOC_CTX *mem_ctx = talloc_new(NULL); TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); struct foo *foo = talloc(pool_ctx, struct foo); /* mem_ctx is not in the pool */ talloc_steal(mem_ctx, foo); /* pool_ctx is marked as freed but the memory is not deallocated, accessing the pool_ctx again will cause an error */ talloc_free(pool_ctx); /* This deallocates the pool_ctx. */ talloc_free(mem_ctx); @endcode It may often be better to copy the memory we want instead of stealing it to avoid this problem. If we do not need to retain the context name (to keep the type information), we can use talloc_memdup() to do this. Copying the memory out of the pool may, however, discard all the performance boost given by the pool, depending on the size of the copied memory. Therefore, the code should be well profiled before taking this path. In general, the golden rule is: if we need to steal from the pool context, we should not use a pool context. */ ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox0000660000000000000000000000362412406075657021275 0ustar rootroot00000000000000/** @page libtalloc_stealing Chapter 2: Stealing a context @section stealing Stealing a context Talloc has the ability to change the parent of a talloc context to another one. This operation is commonly referred to as stealing and it is one of the most important actions performed with talloc contexts. Stealing a context is necessary if we want the pointer to outlive the context it is created on. This has many possible use cases, for instance stealing a result of a database search to an in-memory cache context, changing the parent of a field of a generic structure to a more specific one or vice-versa. The most common scenario, at least in Samba, is to steal output data from a function-specific context to the output context given as an argument of that function. @code struct foo { char *a1; char *a2; char *a3; }; struct bar { char *wurst; struct foo *foo; }; struct foo *foo = talloc_zero(ctx, struct foo); foo->a1 = talloc_strdup(foo, "a1"); foo->a2 = talloc_strdup(foo, "a2"); foo->a3 = talloc_strdup(foo, "a3"); struct bar *bar = talloc_zero(NULL, struct bar); /* change parent of foo from ctx to bar */ bar->foo = talloc_steal(bar, foo); /* or do the same but assign foo = NULL */ bar->foo = talloc_move(bar, &foo); @endcode The talloc_move() function is similar to the talloc_steal() function but additionally sets the source pointer to NULL. In general, the source pointer itself is not changed (it only replaces the parent in the meta data). But the common usage is that the result is assigned to another variable, thus further accessing the pointer from the original variable should be avoided unless it is necessary. In this case talloc_move() is the preferred way of stealing a context. Additionally sets the source pointer to NULL, thus.protects the pointer from being accidentally freed and accessed using the old variable after its parent has been changed. @image html stealing.png */ ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox0000660000000000000000000001123012520121120021057 0ustar rootroot00000000000000/** @page libtalloc_threads Chapter 8: Using threads with talloc @section Talloc and thread safety The talloc library is not internally thread-safe, in that accesses to variables on a talloc context are not controlled by mutexes or other thread-safe primitives. However, so long as talloc_disable_null_tracking() is called from the main thread to disable global variable access within talloc, then each thread can safely use its own top level talloc context allocated off the NULL context. For example: @code static void *thread_fn(void *arg) { const char *ctx_name = (const char *)arg; /* * Create a new top level talloc hierarchy in * this thread. */ void *top_ctx = talloc_named_const(NULL, 0, "top"); if (top_ctx == NULL) { return NULL; } sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); if (sub_ctx == NULL) { return NULL; } /* * Do more processing/talloc calls on top_ctx * and its children. */ ...... talloc_free(top_ctx); return value; } @endcode is a perfectly safe use of talloc within a thread. The problem comes when one thread wishes to move some memory allocated on its local top level talloc context to another thread. Care must be taken to add data access exclusion to prevent memory corruption. One method would be to lock a mutex before any talloc call on each thread, but this would push the burden of total talloc thread-safety on the poor user of the library. A much easier way to transfer talloced memory between threads is by the use of an intermediate, mutex locked, intermediate variable. An example of this is below - taken from test code inside the talloc testsuite. The main thread creates 1000 sub-threads, and then accepts the transfer of some thread-talloc'ed memory onto its top level context from each thread in turn. A pthread mutex and condition variable are used to synchronize the transfer via the intermediate_ptr variable. @code /* Required sync variables. */ static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; /* Intermediate talloc pointer for transfer. */ static void *intermediate_ptr; /* Subthread. */ static void *thread_fn(void *arg) { int ret; const char *ctx_name = (const char *)arg; void *sub_ctx = NULL; /* * Do stuff that creates a new talloc hierarchy in * this thread. */ void *top_ctx = talloc_named_const(NULL, 0, "top"); if (top_ctx == NULL) { return NULL; } sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); if (sub_ctx == NULL) { return NULL; } /* * Now transfer a pointer from our hierarchy * onto the intermediate ptr. */ ret = pthread_mutex_lock(&mtx); if (ret != 0) { talloc_free(top_ctx); return NULL; } /* Wait for intermediate_ptr to be free. */ while (intermediate_ptr != NULL) { ret = pthread_cond_wait(&condvar, &mtx); if (ret != 0) { talloc_free(top_ctx); return NULL; } } /* and move our memory onto it from our toplevel hierarchy. */ intermediate_ptr = talloc_move(NULL, &sub_ctx); /* Tell the main thread it's ready for pickup. */ pthread_cond_broadcast(&condvar); pthread_mutex_unlock(&mtx); talloc_free(top_ctx); return NULL; } /* Main thread. */ #define NUM_THREADS 1000 static bool test_pthread_talloc_passing(void) { int i; int ret; char str_array[NUM_THREADS][20]; pthread_t thread_id; void *mem_ctx; /* * Important ! Null tracking breaks threaded talloc. * It *must* be turned off. */ talloc_disable_null_tracking(); /* Main thread toplevel context. */ mem_ctx = talloc_named_const(NULL, 0, "toplevel"); if (mem_ctx == NULL) { return false; } /* * Spin off NUM_THREADS threads. * They will use their own toplevel contexts. */ for (i = 0; i < NUM_THREADS; i++) { (void)snprintf(str_array[i], 20, "thread:%d", i); if (str_array[i] == NULL) { return false; } ret = pthread_create(&thread_id, NULL, thread_fn, str_array[i]); if (ret != 0) { return false; } } /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */ for (i = 0; i < NUM_THREADS; i++) { ret = pthread_mutex_lock(&mtx); if (ret != 0) { talloc_free(mem_ctx); return false; } /* Wait for intermediate_ptr to have our data. */ while (intermediate_ptr == NULL) { ret = pthread_cond_wait(&condvar, &mtx); if (ret != 0) { talloc_free(mem_ctx); return false; } } /* and move it onto our toplevel hierarchy. */ (void)talloc_move(mem_ctx, &intermediate_ptr); /* Tell the sub-threads we're ready for another. */ pthread_cond_broadcast(&condvar); pthread_mutex_unlock(&mtx); } /* Dump the hierarchy. */ talloc_report(mem_ctx, stdout); talloc_free(mem_ctx); return true; } @endcode */ ldb-2.0.8/lib/talloc/doxy.config0000660000000000000000000022571612406075657016445 0ustar rootroot00000000000000# Doxyfile 1.8.0 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = talloc # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 2.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = . \ doc # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # style sheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NONE # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN \ PRINTF_ATTRIBUTE(x,y)= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES ldb-2.0.8/lib/talloc/man/talloc.3.xml0000660000000000000000000010702013573675413017174 0ustar rootroot00000000000000 2015-04-10 talloc 3 Samba System Administration tools 4.0 talloc hierarchical reference counted memory pool system with destructors #include <talloc.h> DESCRIPTION If you are used to talloc from Samba3 then please read this carefully, as talloc has changed a lot. The new talloc is a hierarchical, reference counted memory pool system with destructors. Quite a mouthful really, but not too bad once you get used to it. Perhaps the biggest change from Samba3 is that there is no distinction between a "talloc context" and a "talloc pointer". Any pointer returned from talloc() is itself a valid talloc context. This means you can do this: struct foo *X = talloc(mem_ctx, struct foo); X->name = talloc_strdup(X, "foo"); and the pointer X->name would be a "child" of the talloc context X which is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) then it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if you do talloc_free(X->name) then just the name element of X is destroyed. If you think about this, then what this effectively gives you is an n-ary tree, where you can free any part of the tree with talloc_free(). If you find this confusing, then I suggest you run the testsuite program to watch talloc in action. You may also like to add your own tests to testsuite.c to clarify how some particular situation is handled. TALLOC API The following is a complete guide to the talloc API. Read it all at least twice. (type *)talloc(const void *ctx, type); The talloc() macro is the core of the talloc library. It takes a memory ctx and a type, and returns a pointer to a new area of memory of the given type. The returned pointer is itself a talloc context, so you can use it as the ctx argument to more calls to talloc() if you wish. The returned pointer is a "child" of the supplied context. This means that if you talloc_free() the ctx then the new child disappears as well. Alternatively you can free just the child. The ctx argument to talloc() can be NULL, in which case a new top level context is created. void *talloc_size(const void *ctx, size_t size); The function talloc_size() should be used when you don't have a convenient type to pass to talloc(). Unlike talloc(), it is not type safe (as it returns a void *), so you are on your own for type checking. (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); The talloc_ptrtype() macro should be used when you have a pointer and want to allocate memory to point at with this pointer. When compiling with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() and talloc_get_name() will return the current location in the source file. and not the type. int talloc_free(void *ptr); The talloc_free() function frees a piece of talloc memory, and all its children. You can call talloc_free() on any pointer returned by talloc(). The return value of talloc_free() indicates success or failure, with 0 returned for success and -1 for failure. The only possible failure condition is if ptr had a destructor attached to it and the destructor returned -1. See talloc_set_destructor() for details on destructors. If this pointer has an additional parent when talloc_free() is called then the memory is not actually released, but instead the most recently established parent is destroyed. See talloc_reference() for details on establishing additional parents. For more control on which parent is removed, see talloc_unlink(). talloc_free() operates recursively on its children. From the 2.0 version of talloc, as a special case, talloc_free() is refused on pointers that have more than one parent, as talloc would have no way of knowing which parent should be removed. To free a pointer that has more than one parent please use talloc_unlink(). To help you find problems in your code caused by this behaviour, if you do try and free a pointer with more than one parent then the talloc logging function will be called to give output like this: ERROR: talloc_free with references at some_dir/source/foo.c:123 reference at some_dir/source/other.c:325 reference at some_dir/source/third.c:121 Please see the documentation for talloc_set_log_fn() and talloc_set_log_stderr() for more information on talloc logging functions. void *talloc_reference(const void *ctx, const void *ptr); The talloc_reference() function makes ctx an additional parent of ptr. The return value of talloc_reference() is always the original pointer ptr, unless talloc ran out of memory in creating the reference in which case it will return NULL (each additional reference consumes around 48 bytes of memory on intel x86 platforms). If ptr is NULL, then the function is a no-op, and simply returns NULL. After creating a reference you can free it in one of the following ways: you can talloc_free() any parent of the original pointer. That will reduce the number of parents of this pointer by 1, and will cause this pointer to be freed if it runs out of parents. you can talloc_free() the pointer itself if it has at maximum one parent. This behaviour has been changed since the release of version 2.0. Further information in the description of "talloc_free". For more control on which parent to remove, see talloc_unlink(). int talloc_unlink(const void *ctx, void *ptr); The talloc_unlink() function removes a specific parent from ptr. The ctx passed must either be a context used in talloc_reference() with this pointer, or must be a direct parent of ptr. Note that if the parent has already been removed using talloc_free() then this function will fail and will return -1. Likewise, if ptr is NULL, then the function will make no modifications and return -1. Usually you can just use talloc_free() instead of talloc_unlink(), but sometimes it is useful to have the additional control on which parent is removed. void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); The function talloc_set_destructor() sets the destructor for the pointer ptr. A destructor is a function that is called when the memory used by a pointer is about to be released. The destructor receives ptr as an argument, and should return 0 for success and -1 for failure. The destructor can do anything it wants to, including freeing other pieces of memory. A common use for destructors is to clean up operating system resources (such as open file descriptors) contained in the structure the destructor is placed on. You can only place one destructor on a pointer. If you need more than one destructor then you can create a zero-length child of the pointer and place an additional destructor on that. To remove a destructor call talloc_set_destructor() with NULL for the destructor. If your destructor attempts to talloc_free() the pointer that it is the destructor for then talloc_free() will return -1 and the free will be ignored. This would be a pointless operation anyway, as the destructor is only called when the memory is just about to go away. int talloc_increase_ref_count(const void *<emphasis role="italic">ptr</emphasis>); The talloc_increase_ref_count(ptr) function is exactly equivalent to: talloc_reference(NULL, ptr); You can use either syntax, depending on which you think is clearer in your code. It returns 0 on success and -1 on failure. size_t talloc_reference_count(const void *<emphasis role="italic">ptr</emphasis>); Return the number of references to the pointer. void talloc_set_name(const void *ptr, const char *fmt, ...); Each talloc pointer has a "name". The name is used principally for debugging purposes, although it is also possible to set and get the name on a pointer in as a way of "marking" pointers in your code. The main use for names on pointer is for "talloc reports". See talloc_report_depth_cb(), talloc_report_depth_file(), talloc_report() talloc_report() and talloc_report_full() for details. Also see talloc_enable_leak_report() and talloc_enable_leak_report_full(). The talloc_set_name() function allocates memory as a child of the pointer. It is logically equivalent to: talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); Note that multiple calls to talloc_set_name() will allocate more memory without releasing the name. All of the memory is released when the ptr is freed using talloc_free(). void talloc_set_name_const(const void *<emphasis role="italic">ptr</emphasis>, const char *<emphasis role="italic">name</emphasis>); The function talloc_set_name_const() is just like talloc_set_name(), but it takes a string constant, and is much faster. It is extensively used by the "auto naming" macros, such as talloc_p(). This function does not allocate any memory. It just copies the supplied pointer into the internal representation of the talloc ptr. This means you must not pass a name pointer to memory that will disappear before ptr is freed with talloc_free(). void *talloc_named(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); The talloc_named() function creates a named talloc pointer. It is equivalent to: ptr = talloc_size(ctx, size); talloc_set_name(ptr, fmt, ....); void *talloc_named_const(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">name</emphasis>); This is equivalent to: ptr = talloc_size(ctx, size); talloc_set_name_const(ptr, name); const char *talloc_get_name(const void *<emphasis role="italic">ptr</emphasis>); This returns the current name for the given talloc pointer, ptr. See talloc_set_name() for details. void *talloc_init(const char *<emphasis role="italic">fmt</emphasis>, ...); This function creates a zero length named talloc context as a top level context. It is equivalent to: talloc_named(NULL, 0, fmt, ...); void *talloc_new(void *<emphasis role="italic">ctx</emphasis>); This is a utility macro that creates a new memory context hanging off an existing context, automatically naming it "talloc_new: __location__" where __location__ is the source line it is called from. It is particularly useful for creating a new temporary working context. (<emphasis role="italic">type</emphasis> *)talloc_realloc(const void *<emphasis role="italic">ctx</emphasis>, void *<emphasis role="italic">ptr</emphasis>, <emphasis role="italic">type</emphasis>, <emphasis role="italic">count</emphasis>); The talloc_realloc() macro changes the size of a talloc pointer. It has the following equivalences: talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); The ctx argument is only used if ptr is not NULL, otherwise it is ignored. talloc_realloc() returns the new pointer, or NULL on failure. The call will fail either due to a lack of memory, or because the pointer has more than one parent (see talloc_reference()). void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); the talloc_realloc_size() function is useful when the type is not known so the type-safe talloc_realloc() cannot be used. TYPE *talloc_steal(const void *<emphasis role="italic">new_ctx</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); The talloc_steal() function changes the parent context of a talloc pointer. It is typically used when the context that the pointer is currently a child of is going to be freed and you wish to keep the memory for a longer time. The talloc_steal() function returns the pointer that you pass it. It does not have any failure modes. It is possible to produce loops in the parent/child relationship if you are not careful with talloc_steal(). No guarantees are provided as to your sanity or the safety of your data if you do this. Note that if you try and call talloc_steal() on a pointer that has more than one parent then the result is ambiguous. Talloc will choose to remove the parent that is currently indicated by talloc_parent() and replace it with the chosen parent. You will also get a message like this via the talloc logging functions: WARNING: talloc_steal with references at some_dir/source/foo.c:123 reference at some_dir/source/other.c:325 reference at some_dir/source/third.c:121 To unambiguously change the parent of a pointer please see the function talloc_reparent(). See the talloc_set_log_fn() documentation for more information on talloc logging. TYPE *talloc_reparent(const void *<emphasis role="italic">old_parent</emphasis>, const void *<emphasis role="italic">new_parent</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); The talloc_reparent() function changes the parent context of a talloc pointer. It is typically used when the context that the pointer is currently a child of is going to be freed and you wish to keep the memory for a longer time. The talloc_reparent() function returns the pointer that you pass it. It does not have any failure modes. The difference between talloc_reparent() and talloc_steal() is that talloc_reparent() can specify which parent you wish to change. This is useful when a pointer has multiple parents via references. TYPE *talloc_move(const void *<emphasis role="italic">new_ctx</emphasis>, TYPE **<emphasis role="italic">ptr</emphasis>); The talloc_move() function is a wrapper around talloc_steal() which zeros the source pointer after the move. This avoids a potential source of bugs where a programmer leaves a pointer in two structures, and uses the pointer from the old structure after it has been moved to a new one. size_t talloc_total_size(const void *<emphasis role="italic">ptr</emphasis>); The talloc_total_size() function returns the total size in bytes used by this pointer and all child pointers. Mostly useful for debugging. Passing NULL is allowed, but it will only give a meaningful result if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. size_t talloc_total_blocks(const void *<emphasis role="italic">ptr</emphasis>); The talloc_total_blocks() function returns the total memory block count used by this pointer and all child pointers. Mostly useful for debugging. Passing NULL is allowed, but it will only give a meaningful result if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. void talloc_report(const void *ptr, FILE *f); The talloc_report() function prints a summary report of all memory used by ptr. One line of report is printed for each immediate child of ptr, showing the total memory and number of blocks used by that child. You can pass NULL for the pointer, in which case a report is printed for the top level memory context, but only if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. void talloc_report_full(const void *<emphasis role="italic">ptr</emphasis>, FILE *<emphasis role="italic">f</emphasis>); This provides a more detailed report than talloc_report(). It will recursively print the entire tree of memory referenced by the pointer. References in the tree are shown by giving the name of the pointer that is referenced. You can pass NULL for the pointer, in which case a report is printed for the top level memory context, but only if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. void talloc_report_depth_cb const void *ptr int depth int max_depth void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv) void *priv This provides a more flexible reports than talloc_report(). It will recursively call the callback for the entire tree of memory referenced by the pointer. References in the tree are passed with is_ref = 1 and the pointer that is referenced. You can pass NULL for the pointer, in which case a report is printed for the top level memory context, but only if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. The recursion is stopped when depth >= max_depth. max_depth = -1 means only stop at leaf nodes. void talloc_report_depth_file const void *ptr int depth int max_depth FILE *f This provides a more flexible reports than talloc_report(). It will let you specify the depth and max_depth. void talloc_enable_leak_report(void); This enables calling of talloc_report(NULL, stderr) when the program exits. In Samba4 this is enabled by using the --leak-report command line option. For it to be useful, this function must be called before any other talloc function as it establishes a "null context" that acts as the top of the tree. If you don't call this function first then passing NULL to talloc_report() or talloc_report_full() won't give you the full tree printout. Here is a typical talloc report: talloc report on 'null_context' (total 267 bytes in 15 blocks) libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks iconv(UTF8,CP850) contains 42 bytes in 2 blocks libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks iconv(CP850,UTF8) contains 42 bytes in 2 blocks iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks void talloc_enable_leak_report_full(void); This enables calling of talloc_report_full(NULL, stderr) when the program exits. In Samba4 this is enabled by using the --leak-report-full command line option. For it to be useful, this function must be called before any other talloc function as it establishes a "null context" that acts as the top of the tree. If you don't call this function first then passing NULL to talloc_report() or talloc_report_full() won't give you the full tree printout. Here is a typical full report: full talloc report on 'root' (total 18 bytes in 8 blocks) p1 contains 18 bytes in 7 blocks (ref 0) r1 contains 13 bytes in 2 blocks (ref 0) reference to: p2 p2 contains 1 bytes in 1 blocks (ref 1) x3 contains 1 bytes in 1 blocks (ref 0) x2 contains 1 bytes in 1 blocks (ref 0) x1 contains 1 bytes in 1 blocks (ref 0) (<emphasis role="italic">type</emphasis> *)talloc_zero(const void *<emphasis role="italic">ctx</emphasis>, <emphasis role="italic">type</emphasis>); The talloc_zero() macro is equivalent to: ptr = talloc(ctx, type); if (ptr) memset(ptr, 0, sizeof(type)); void *talloc_zero_size(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>) The talloc_zero_size() function is useful when you don't have a known type. void *talloc_memdup(const void *<emphasis role="italic">ctx</emphasis>, const void *<emphasis role="italic">p</emphasis>, size_t size); The talloc_memdup() function is equivalent to: ptr = talloc_size(ctx, size); if (ptr) memcpy(ptr, p, size); char *talloc_strdup(const void *<emphasis role="italic">ctx</emphasis>, const char *<emphasis role="italic">p</emphasis>); The talloc_strdup() function is equivalent to: ptr = talloc_size(ctx, strlen(p)+1); if (ptr) memcpy(ptr, p, strlen(p)+1); This function sets the name of the new pointer to the passed string. This is equivalent to: talloc_set_name_const(ptr, ptr) char *talloc_strndup(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">p</emphasis>, size_t <emphasis role="italic">n</emphasis>); The talloc_strndup() function is the talloc equivalent of the C library function strndup(3). This function sets the name of the new pointer to the passed string. This is equivalent to: talloc_set_name_const(ptr, ptr) char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>); The talloc_vasprintf() function is the talloc equivalent of the C library function vasprintf(3). This function sets the name of the new pointer to the new string. This is equivalent to: talloc_set_name_const(ptr, ptr) char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); The talloc_asprintf() function is the talloc equivalent of the C library function asprintf(3). This function sets the name of the new pointer to the passed string. This is equivalent to: talloc_set_name_const(ptr, ptr) char *talloc_asprintf_append(char *s, const char *fmt, ...); The talloc_asprintf_append() function appends the given formatted string to the given string. This function sets the name of the new pointer to the new string. This is equivalent to: talloc_set_name_const(ptr, ptr) (type *)talloc_array(const void *ctx, type, unsigned int count); The talloc_array() macro is equivalent to: (type *)talloc_size(ctx, sizeof(type) * count); except that it provides integer overflow protection for the multiply, returning NULL if the multiply overflows. void *talloc_array_size(const void *ctx, size_t size, unsigned int count); The talloc_array_size() function is useful when the type is not known. It operates in the same way as talloc_array(), but takes a size instead of a type. (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); The talloc_ptrtype() macro should be used when you have a pointer to an array and want to allocate memory of an array to point at with this pointer. When compiling with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() and talloc_get_name() will return the current location in the source file. and not the type. void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size) This is a non-macro version of talloc_realloc(), which is useful as libraries sometimes want a realloc function pointer. A realloc(3) implementation encapsulates the functionality of malloc(3), free(3) and realloc(3) in one call, which is why it is useful to be able to pass around a single function pointer. void *talloc_autofree_context(void); This is a handy utility function that returns a talloc context which will be automatically freed on program exit. This can be used to reduce the noise in memory leak reports. void *talloc_check_name(const void *ptr, const char *name); This function checks if a pointer has the specified name. If it does then the pointer is returned. It it doesn't then NULL is returned. (type *)talloc_get_type(const void *ptr, type); This macro allows you to do type checking on talloc pointers. It is particularly useful for void* private pointers. It is equivalent to this: (type *)talloc_check_name(ptr, #type) talloc_set_type(const void *ptr, type); This macro allows you to force the name of a pointer to be a particular type. This can be used in conjunction with talloc_get_type() to do type checking on void* pointers. It is equivalent to this: talloc_set_name_const(ptr, #type) talloc_set_log_fn(void (*log_fn)(const char *message)); This function sets a logging function that talloc will use for warnings and errors. By default talloc will not print any warnings or errors. talloc_set_log_stderr(void); This sets the talloc log function to write log messages to stderr PERFORMANCE All the additional features of talloc(3) over malloc(3) do come at a price. We have a simple performance test in Samba4 that measures talloc() versus malloc() performance, and it seems that talloc() is about 10% slower than malloc() on my x86 Debian Linux box. For Samba, the great reduction in code complexity that we get by using talloc makes this worthwhile, especially as the total overhead of talloc/malloc in Samba is already quite small. SEE ALSO malloc(3), strndup(3), vasprintf(3), asprintf(3), AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. COPYRIGHT/LICENSE Copyright (C) Andrew Tridgell 2004 This program 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 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/. ldb-2.0.8/lib/talloc/pytalloc-util.pc.in0000660000000000000000000000053113100601766017774 0ustar rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: pytalloc-util@PYTHON_SO_ABI_FLAG@ Description: Utility functions for using talloc objects with Python Version: @TALLOC_VERSION@ Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util@PYTHON_LIBNAME_SO_ABI_FLAG@ Cflags: -I${includedir} URL: http://talloc.samba.org/ ldb-2.0.8/lib/talloc/pytalloc.c0000660000000000000000000002100513573675413016251 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python Talloc Module Copyright (C) Jelmer Vernooij 2010-2011 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 . */ #include #include #include #include "pytalloc_private.h" static PyTypeObject TallocObject_Type; /* print a talloc tree report for a talloc python object */ static PyObject *pytalloc_report_full(PyObject *self, PyObject *args) { PyObject *py_obj = Py_None; if (!PyArg_ParseTuple(args, "|O", &py_obj)) return NULL; if (py_obj == Py_None) { talloc_report_full(NULL, stdout); } else { talloc_report_full(pytalloc_get_mem_ctx(py_obj), stdout); } return Py_None; } /* enable null tracking */ static PyObject *pytalloc_enable_null_tracking(PyObject *self, PyObject *Py_UNUSED(ignored)) { talloc_enable_null_tracking(); return Py_None; } /* return the number of talloc blocks */ static PyObject *pytalloc_total_blocks(PyObject *self, PyObject *args) { PyObject *py_obj = Py_None; if (!PyArg_ParseTuple(args, "|O", &py_obj)) return NULL; if (py_obj == Py_None) { return PyLong_FromLong(talloc_total_blocks(NULL)); } return PyLong_FromLong(talloc_total_blocks(pytalloc_get_mem_ctx(py_obj))); } static PyMethodDef talloc_methods[] = { { "report_full", (PyCFunction)pytalloc_report_full, METH_VARARGS, "show a talloc tree for an object"}, { "enable_null_tracking", (PyCFunction)pytalloc_enable_null_tracking, METH_NOARGS, "enable tracking of the NULL object"}, { "total_blocks", (PyCFunction)pytalloc_total_blocks, METH_VARARGS, "return talloc block count"}, { NULL } }; /** * Default (but only slightly more useful than the default) implementation of Repr(). */ static PyObject *pytalloc_default_repr(PyObject *obj) { pytalloc_Object *talloc_obj = (pytalloc_Object *)obj; PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj); return PyUnicode_FromFormat("<%s talloc object at %p>", type->tp_name, talloc_obj->ptr); } /** * Simple dealloc for talloc-wrapping PyObjects */ static void pytalloc_dealloc(PyObject* self) { pytalloc_Object *obj = (pytalloc_Object *)self; assert(talloc_unlink(NULL, obj->talloc_ctx) != -1); obj->talloc_ctx = NULL; self->ob_type->tp_free(self); } /** * Default (but only slightly more useful than the default) implementation of cmp. */ #if PY_MAJOR_VERSION >= 3 static PyObject *pytalloc_default_richcmp(PyObject *obj1, PyObject *obj2, int op) { void *ptr1; void *ptr2; if (Py_TYPE(obj1) == Py_TYPE(obj2)) { /* When types match, compare pointers */ ptr1 = pytalloc_get_ptr(obj1); ptr2 = pytalloc_get_ptr(obj2); } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) { /* Otherwise, compare types */ ptr1 = Py_TYPE(obj1); ptr2 = Py_TYPE(obj2); } else { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } switch (op) { case Py_EQ: return PyBool_FromLong(ptr1 == ptr2); case Py_NE: return PyBool_FromLong(ptr1 != ptr2); case Py_LT: return PyBool_FromLong(ptr1 < ptr2); case Py_GT: return PyBool_FromLong(ptr1 > ptr2); case Py_LE: return PyBool_FromLong(ptr1 <= ptr2); case Py_GE: return PyBool_FromLong(ptr1 >= ptr2); } Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } #else static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2) { pytalloc_Object *obj1 = (pytalloc_Object *)_obj1, *obj2 = (pytalloc_Object *)_obj2; if (obj1->ob_type != obj2->ob_type) return ((char *)obj1->ob_type - (char *)obj2->ob_type); return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2)); } #endif static PyTypeObject TallocObject_Type = { .tp_name = "talloc.Object", .tp_doc = "Python wrapper for a talloc-maintained object.", .tp_basicsize = sizeof(pytalloc_Object), .tp_dealloc = (destructor)pytalloc_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_repr = pytalloc_default_repr, #if PY_MAJOR_VERSION >= 3 .tp_richcompare = pytalloc_default_richcmp, #else .tp_compare = pytalloc_default_cmp, #endif }; /** * Default (but only slightly more useful than the default) implementation of Repr(). */ static PyObject *pytalloc_base_default_repr(PyObject *obj) { pytalloc_BaseObject *talloc_obj = (pytalloc_BaseObject *)obj; PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj); return PyUnicode_FromFormat("<%s talloc based object at %p>", type->tp_name, talloc_obj->ptr); } /** * Simple dealloc for talloc-wrapping PyObjects */ static void pytalloc_base_dealloc(PyObject* self) { pytalloc_BaseObject *obj = (pytalloc_BaseObject *)self; assert(talloc_unlink(NULL, obj->talloc_ctx) != -1); obj->talloc_ctx = NULL; self->ob_type->tp_free(self); } /** * Default (but only slightly more useful than the default) implementation of cmp. */ #if PY_MAJOR_VERSION >= 3 static PyObject *pytalloc_base_default_richcmp(PyObject *obj1, PyObject *obj2, int op) { void *ptr1; void *ptr2; if (Py_TYPE(obj1) == Py_TYPE(obj2)) { /* When types match, compare pointers */ ptr1 = pytalloc_get_ptr(obj1); ptr2 = pytalloc_get_ptr(obj2); } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) { /* Otherwise, compare types */ ptr1 = Py_TYPE(obj1); ptr2 = Py_TYPE(obj2); } else { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } switch (op) { case Py_EQ: return PyBool_FromLong(ptr1 == ptr2); case Py_NE: return PyBool_FromLong(ptr1 != ptr2); case Py_LT: return PyBool_FromLong(ptr1 < ptr2); case Py_GT: return PyBool_FromLong(ptr1 > ptr2); case Py_LE: return PyBool_FromLong(ptr1 <= ptr2); case Py_GE: return PyBool_FromLong(ptr1 >= ptr2); } Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } #else static int pytalloc_base_default_cmp(PyObject *_obj1, PyObject *_obj2) { pytalloc_BaseObject *obj1 = (pytalloc_BaseObject *)_obj1, *obj2 = (pytalloc_BaseObject *)_obj2; if (obj1->ob_type != obj2->ob_type) return ((char *)obj1->ob_type - (char *)obj2->ob_type); return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2)); } #endif static PyTypeObject TallocBaseObject_Type = { .tp_name = "talloc.BaseObject", .tp_doc = "Python wrapper for a talloc-maintained object.", .tp_basicsize = sizeof(pytalloc_BaseObject), .tp_dealloc = (destructor)pytalloc_base_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_repr = pytalloc_base_default_repr, #if PY_MAJOR_VERSION >= 3 .tp_richcompare = pytalloc_base_default_richcmp, #else .tp_compare = pytalloc_base_default_cmp, #endif }; static PyTypeObject TallocGenericObject_Type = { .tp_name = "talloc.GenericObject", .tp_doc = "Python wrapper for a talloc-maintained object.", .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_base = &TallocBaseObject_Type, .tp_basicsize = sizeof(pytalloc_BaseObject), }; #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, .m_name = "talloc", .m_doc = MODULE_DOC, .m_size = -1, .m_methods = talloc_methods, }; #endif static PyObject *module_init(void); static PyObject *module_init(void) { PyObject *m; if (PyType_Ready(&TallocObject_Type) < 0) return NULL; if (PyType_Ready(&TallocBaseObject_Type) < 0) return NULL; if (PyType_Ready(&TallocGenericObject_Type) < 0) return NULL; #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); #else m = Py_InitModule3("talloc", talloc_methods, MODULE_DOC); #endif if (m == NULL) return NULL; Py_INCREF(&TallocObject_Type); if (PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type)) { goto err; } Py_INCREF(&TallocBaseObject_Type); if (PyModule_AddObject(m, "BaseObject", (PyObject *)&TallocBaseObject_Type)) { goto err; } Py_INCREF(&TallocGenericObject_Type); if (PyModule_AddObject(m, "GenericObject", (PyObject *)&TallocGenericObject_Type)) { goto err; } return m; err: Py_DECREF(m); return NULL; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit_talloc(void); PyMODINIT_FUNC PyInit_talloc(void) { return module_init(); } #else void inittalloc(void); void inittalloc(void) { module_init(); } #endif ldb-2.0.8/lib/talloc/pytalloc.h0000660000000000000000000000602613573675413016264 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij 2008 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 . */ #ifndef _PYTALLOC_H_ #define _PYTALLOC_H_ #include #include typedef struct { PyObject_HEAD TALLOC_CTX *talloc_ctx; void *ptr; /* eg the array element */ } pytalloc_Object; /* Return the PyTypeObject for pytalloc_Object. Returns a borrowed reference. */ PyTypeObject *pytalloc_GetObjectType(void); /* Return the PyTypeObject for pytalloc_BaseObject. Returns a borrowed reference. */ PyTypeObject *pytalloc_GetBaseObjectType(void); /* Check whether a specific object is a talloc Object. */ int pytalloc_Check(PyObject *); int pytalloc_BaseObject_check(PyObject *); int _pytalloc_check_type(PyObject *py_obj, const char *type_name); #define pytalloc_check_type(py_obj, type) \ _pytalloc_check_type((PyObject *)(py_obj), #type) /* Retrieve the pointer for a pytalloc_object. Like talloc_get_type() * but for pytalloc_Objects. */ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name); #define pytalloc_get_type(py_obj, type) ((type *)_pytalloc_get_type((PyObject *)(py_obj), #type)) void *_pytalloc_get_ptr(PyObject *py_obj); #define pytalloc_get_ptr(py_obj) _pytalloc_get_ptr((PyObject *)(py_obj)) TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj); #define pytalloc_get_mem_ctx(py_obj) _pytalloc_get_mem_ctx((PyObject *)(py_obj)) PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr); PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); #define pytalloc_reference(py_type, talloc_ptr) pytalloc_reference_ex(py_type, talloc_ptr, talloc_ptr) #define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type)) /* * Wrap a generic talloc pointer into a talloc.GenericObject, * this is a subclass of talloc.BaseObject. */ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr); #define pytalloc_GenericObject_steal(talloc_ptr) \ pytalloc_GenericObject_steal_ex(talloc_ptr, talloc_ptr) PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr); #define pytalloc_GenericObject_reference(talloc_ptr) \ pytalloc_GenericObject_reference_ex(talloc_ptr, talloc_ptr) size_t pytalloc_BaseObject_size(void); int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type); #endif /* _PYTALLOC_H_ */ ldb-2.0.8/lib/talloc/pytalloc_guide.txt0000660000000000000000000002536513055076237020032 0ustar rootroot00000000000000Using talloc in Samba4 ====================== .. contents:: Jelmer Vernooij August 2013 The most current version of this document is available at http://samba.org/ftp/unpacked/talloc/pytalloc_guide.txt pytalloc is a small library that provides glue for wrapping talloc-allocated objects from C in Python objects. What is pytalloc, and what is it not? ------------------------------------- pytalloc is merely a helper library - it provides a convenient base type object for objects that wrap talloc-maintained memory in C. It won't write your bindings for you but it will make it easier to write C bindings that involve talloc, and take away some of the boiler plate. Python 3 -------- pytalloc can be used with Python 3. Usage from Python extension remains the same, but for the C utilities, the library to link to is tagged with Python's PEP3149 ABI tag, for example "pytalloc.cpython34m". To make a build for Python 3, configure with PYTHON=/usr/bin/python3. . =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- pytalloc_Object / pytalloc_BaseObject This is the new base class that all Python objects that wrap talloc pointers derive from. It is itself a subclass of the "Object" type that all objects in Python derive from. Note that you will almost never create objects of the pytalloc_Object type itself, as they are just opaque pointers that can not be accessed from Python. A common pattern is other objects that subclass pytalloc_Object and rely on it for their memory management. Each `pytalloc_Object` wraps two core of information - a talloc context and a pointer. The pointer is the actual data that is wrapped. The talloc context is used for memory management purposes only; when the wrapping Python object goes away, it unlinks the talloc context. The talloc context pointer and the ptr can (and often do) have the same value. Each pytalloc_Object has a custom __repr__ implementation that describes that it is a talloc object and the location of the pointer it is wrapping. it also has a custom __cmp__/__eq__/__neq__ method that compares the pointers the object is wrapping rather than the objects themselves (since there can be multiple objects that wrap the same talloc pointer). It is preferred to use pytalloc_BaseObject as this implementation exposes less in the C ABI and correctly supports pointers in C arrays in the way needed by PIDL. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyTypeObject *pytalloc_GetObjectType(void) Obtain a pointer to the PyTypeObject for `pytalloc_Object`. The reference counter for the object will be NOT incremented, so the caller MUST NOT decrement it when it no longer needs it (eg by using `Py_DECREF`). =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyTypeObject *pytalloc_GetBaseObjectType(void) Obtain a pointer to the PyTypeObject for `pytalloc_BaseObject`. The reference counter for the object will be NOT incremented, so the caller MUST NOT decrement it when it no longer needs it (eg by using `Py_DECREF`). =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type); Wrapper for PyType_Ready() that will set the correct values into the PyTypeObject to create a BaseObject =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- int pytalloc_Check(PyObject *) Check whether a specific object is a talloc Object. Returns non-zero if it is a pytalloc_Object and zero otherwise. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- int pytalloc_BaseObject_Check(PyObject *) Check whether a specific object is a talloc BaseObject. Returns non-zero if it is a pytalloc_BaseObject and zero otherwise. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- int pytalloc_check_type(PyObject *py_obj, type) Check if the object based on `pytalloc_*Object` py_obj. type should be a C type, similar to a type passed to `talloc_get_type`. This can be used as a check before using pytalloc_get_type() or an alternative codepath. Returns non-zero if it is an object of the expected type and zero otherwise. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- type *pytalloc_get_type(PyObject *py_obj, type) Retrieve the pointer from a `pytalloc_Object` py_obj. type should be a C type, similar to a type passed to `talloc_get_type`. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- pytalloc_get_ptr(PyObject *py_obj) Retrieve the pointer from a `pytalloc_Object` or `pytalloc_BaseObject` py_obj. There is no type checking - use `pytalloc_get_type` if possible. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- TALLOC_CTX *pytalloc_get_mem_ctx(PyObject *py_obj) Retrieve the talloc context associated with a pytalloc_Object or pytalloc_BaseObject. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) Create a new Python wrapping object for a talloc pointer and context, with py_type as associated Python sub type object. This typically used when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. `pytalloc_get_ptr()` can be used to get the pointer out of the object again. This will *not* increment the reference counter for the talloc context, so the caller should make sure such an increment has happened. When the Python object goes away, it will unreference the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) Create a new Python wrapping object for a talloc pointer and context, with py_type as associated Python sub type object. The pointer will also be used as the talloc context. `pytalloc_get_type()` can be used to get the pointer out of the object again. This will *not* increment the reference counter for the talloc context, so the caller should make sure such an increment has happened. When the Python object goes away, it will unreference the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) Create a new Python wrapping object for a talloc pointer and context, with py_type as associated Python sub type object. This typically used when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. `pytalloc_get_ptr()` can be used to get the pointer out of the object again. This will increment the reference counter for the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_reference(PyTypeObject *py_type, void *talloc_ptr) Create a new Python wrapping object for a talloc pointer, with py_type as associated Python sub type object. The pointer will also be used as the talloc context. `pytalloc_get_type()` can be used to get the pointer out of the object again. This will increment the reference counter for the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_new(type, PyTypeObject *typeobj) Create a new, empty pytalloc_Object with the specified Python type object. type should be a C type, similar to talloc_new(). =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_GenericObject_steal_ex(void *ptr) Create a new Python wrapping object for a generic talloc pointer, as sub type of `pytalloc_BaseObject`. This typically used when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. `pytalloc_get_ptr()` can be used to get the pointer out of the object again. This will *not* increment the reference counter for the talloc context, so the caller should make sure such an increment has happened. When the Python object goes away, it will unreference the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_GenericObject_steal(void *ptr) Create a new Python wrapping object for a generic talloc pointer, as sub type of `pytalloc_BaseObject`. The pointer will also be used as the talloc context. `pytalloc_get_type()` can be used to get the pointer out of the object again. This will *not* increment the reference counter for the talloc context, so the caller should make sure such an increment has happened. When the Python object goes away, it will unreference the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_GenericObject_reference_ex(void *ptr) Create a new Python wrapping object for a generic talloc pointer, as sub type of `pytalloc_BaseObject`. This typically used when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. `pytalloc_get_ptr()` can be used to get the pointer out of the object again. This will increment the reference counter for the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- PyObject *pytalloc_GenericObject_reference(void *ptr) Create a new Python wrapping object for a generic talloc pointer, as sub type of `pytalloc_BaseObject`. The pointer will also be used as the talloc context. `pytalloc_get_type()` can be used to get the pointer out of the object again. This will increment the reference counter for the talloc context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- DEPRECATED! PyObject *pytalloc_CObject_FromTallocPtr(void *); Create a new pytalloc_Object for an abitrary talloc-maintained C pointer. This will use a generic VoidPtr Python type, which just provides an opaque object in Python. The caller is responsible for incrementing the talloc reference count before calling this function - it will dereference the talloc pointer when it is garbage collected. This function is deprecated and only available on Python 2. Use pytalloc_GenericObject_{reference,steal}[_ex]() instead. Debug function for talloc in Python ----------------------------------- The "talloc" module in Python provides a couple of functions that can be used to debug issues with objects wrapped by pytalloc. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- report_full(obj?) Print a full report on a specific object or on all allocated objects by Python. Same behaviour as the `talloc_report_full()` function that is provided by C talloc. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- enable_null_tracking() This enables tracking of the NULL memory context without enabling leak reporting on exit. Useful for when you want to do your own leak reporting call via talloc_report_null_full(). This must be done in the top level script, not an imported module. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- pytalloc_total_blocks(obj?) Return the talloc block count for all allocated objects or a specific object if specified. ldb-2.0.8/lib/talloc/pytalloc_private.h0000660000000000000000000000175612667552643020025 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij 2008 Copyright (C) Andrew Bartlett 2016 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 . */ typedef struct { PyObject_HEAD TALLOC_CTX *talloc_ctx; TALLOC_CTX *talloc_ptr_ctx; /* eg the start of the array */ void *ptr; /* eg the array element */ } pytalloc_BaseObject; ldb-2.0.8/lib/talloc/pytalloc_util.c0000660000000000000000000001721413573675413017315 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python/Talloc glue Copyright (C) Jelmer Vernooij 2008 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 . */ #include #include "replace.h" #include #include "pytalloc.h" #include #include "pytalloc_private.h" static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr, bool steal); _PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void) { static PyTypeObject *type = NULL; PyObject *mod; if (type != NULL) { return type; } mod = PyImport_ImportModule("talloc"); if (mod == NULL) { return NULL; } type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object"); Py_DECREF(mod); return type; } _PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void) { static PyTypeObject *type = NULL; PyObject *mod; if (type != NULL) { return type; } mod = PyImport_ImportModule("talloc"); if (mod == NULL) { return NULL; } type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject"); Py_DECREF(mod); return type; } static PyTypeObject *pytalloc_GetGenericObjectType(void) { static PyTypeObject *type = NULL; PyObject *mod; if (type != NULL) { return type; } mod = PyImport_ImportModule("talloc"); if (mod == NULL) { return NULL; } type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject"); Py_DECREF(mod); return type; } /** * Import an existing talloc pointer into a Python object. */ _PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, true); } /** * Import an existing talloc pointer into a Python object. */ _PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) { return pytalloc_steal_or_reference(py_type, ptr, ptr, true); } /** * Import an existing talloc pointer into a Python object, leaving the * original parent, and creating a reference to the object in the python * object. * * We remember the object we hold the reference to (a * possibly-non-talloc pointer), the existing parent (typically the * start of the array) and the new referenced parent. That way we can * cope with the fact that we will have multiple parents, one per time * python sees the object. */ _PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, false); } /** * Internal function that either steals or referecences the talloc * pointer into a new talloc context. */ static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr, bool steal) { bool ok = false; TALLOC_CTX *talloc_ctx = NULL; bool is_baseobject = false; PyObject *obj = NULL; PyTypeObject *BaseObjectType = NULL, *ObjectType = NULL; BaseObjectType = pytalloc_GetBaseObjectType(); if (BaseObjectType == NULL) { goto err; } ObjectType = pytalloc_GetObjectType(); if (ObjectType == NULL) { goto err; } /* this should have been tested by caller */ if (mem_ctx == NULL) { return PyErr_NoMemory(); } is_baseobject = PyType_IsSubtype(py_type, BaseObjectType); if (!is_baseobject) { if (!PyType_IsSubtype(py_type, ObjectType)) { PyErr_SetString(PyExc_TypeError, "Expected type based on talloc"); return NULL; } } obj = py_type->tp_alloc(py_type, 0); if (obj == NULL) { goto err; } talloc_ctx = talloc_new(NULL); if (talloc_ctx == NULL) { PyErr_NoMemory(); goto err; } if (steal) { ok = (talloc_steal(talloc_ctx, mem_ctx) != NULL); } else { ok = (talloc_reference(talloc_ctx, mem_ctx) != NULL); } if (!ok) { goto err; } talloc_set_name_const(talloc_ctx, py_type->tp_name); if (is_baseobject) { pytalloc_BaseObject *ret = (pytalloc_BaseObject*)obj; ret->talloc_ctx = talloc_ctx; ret->talloc_ptr_ctx = mem_ctx; ret->ptr = ptr; } else { pytalloc_Object *ret = (pytalloc_Object*)obj; ret->talloc_ctx = talloc_ctx; ret->ptr = ptr; } return obj; err: TALLOC_FREE(talloc_ctx); Py_XDECREF(obj); return NULL; } /* * Wrap a generic talloc pointer into a talloc.GenericObject, * this is a subclass of talloc.BaseObject. */ _PUBLIC_ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr) { PyTypeObject *tp = pytalloc_GetGenericObjectType(); return pytalloc_steal_ex(tp, mem_ctx, ptr); } /* * Wrap a generic talloc pointer into a talloc.GenericObject, * this is a subclass of talloc.BaseObject. */ _PUBLIC_ PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr) { PyTypeObject *tp = pytalloc_GetGenericObjectType(); return pytalloc_reference_ex(tp, mem_ctx, ptr); } _PUBLIC_ int pytalloc_Check(PyObject *obj) { PyTypeObject *tp = pytalloc_GetObjectType(); return PyObject_TypeCheck(obj, tp); } _PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj) { PyTypeObject *tp = pytalloc_GetBaseObjectType(); return PyObject_TypeCheck(obj, tp); } _PUBLIC_ size_t pytalloc_BaseObject_size(void) { return sizeof(pytalloc_BaseObject); } static void *_pytalloc_get_checked_type(PyObject *py_obj, const char *type_name, bool check_only, const char *function) { TALLOC_CTX *mem_ctx; void *ptr = NULL; void *type_obj = talloc_check_name(ptr, type_name); mem_ctx = _pytalloc_get_mem_ctx(py_obj); ptr = _pytalloc_get_ptr(py_obj); if (mem_ctx != ptr) { if (check_only) { return NULL; } PyErr_Format(PyExc_TypeError, "%s: expected %s, " "but the pointer is no talloc pointer, " "pytalloc_get_ptr() would get the raw pointer.", function, type_name); return NULL; } type_obj = talloc_check_name(ptr, type_name); if (type_obj == NULL) { const char *name = NULL; if (check_only) { return NULL; } name = talloc_get_name(ptr); PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s", function, type_name, name); return NULL; } return ptr; } _PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name) { void *ptr = NULL; ptr = _pytalloc_get_checked_type(py_obj, type_name, true, /* check_only */ "pytalloc_check_type"); if (ptr == NULL) { return 0; } return 1; } _PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name) { return _pytalloc_get_checked_type(py_obj, type_name, false, /* not check_only */ "pytalloc_get_type"); } _PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj) { if (pytalloc_BaseObject_check(py_obj)) { return ((pytalloc_BaseObject *)py_obj)->ptr; } if (pytalloc_Check(py_obj)) { return ((pytalloc_Object *)py_obj)->ptr; } return NULL; } _PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj) { if (pytalloc_BaseObject_check(py_obj)) { return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx; } if (pytalloc_Check(py_obj)) { return ((pytalloc_Object *)py_obj)->talloc_ctx; } return NULL; } _PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type) { PyTypeObject *talloc_type = pytalloc_GetBaseObjectType(); if (talloc_type == NULL) { return -1; } type->tp_base = talloc_type; type->tp_basicsize = pytalloc_BaseObject_size(); return PyType_Ready(type); } ldb-2.0.8/lib/talloc/talloc.c0000660000000000000000000021562213573675413015712 0ustar rootroot00000000000000/* Samba Unix SMB/CIFS implementation. Samba trivial allocation library - new interface NOTE: Please read talloc_guide.txt for full documentation Copyright (C) Andrew Tridgell 2004 Copyright (C) Stefan Metzmacher 2006 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ /* inspired by http://swapped.cc/halloc/ */ #include "replace.h" #include "talloc.h" #ifdef HAVE_SYS_AUXV_H #include #endif #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR) #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR" #endif #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR) #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR" #endif /* Special macros that are no-ops except when run under Valgrind on * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */ #ifdef HAVE_VALGRIND_MEMCHECK_H /* memcheck.h includes valgrind.h */ #include #elif defined(HAVE_VALGRIND_H) #include #endif /* use this to force every realloc to change the pointer, to stress test code that might not cope */ #define ALWAYS_REALLOC 0 #define MAX_TALLOC_SIZE 0x10000000 #define TALLOC_FLAG_FREE 0x01 #define TALLOC_FLAG_LOOP 0x02 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ /* * Bits above this are random, used to make it harder to fake talloc * headers during an attack. Try not to change this without good reason. */ #define TALLOC_FLAG_MASK 0x0F #define TALLOC_MAGIC_REFERENCE ((const char *)1) #define TALLOC_MAGIC_BASE 0xe814ec70 #define TALLOC_MAGIC_NON_RANDOM ( \ ~TALLOC_FLAG_MASK & ( \ TALLOC_MAGIC_BASE + \ (TALLOC_BUILD_VERSION_MAJOR << 24) + \ (TALLOC_BUILD_VERSION_MINOR << 16) + \ (TALLOC_BUILD_VERSION_RELEASE << 8))) static unsigned int talloc_magic = TALLOC_MAGIC_NON_RANDOM; /* by default we abort when given a bad pointer (such as when talloc_free() is called on a pointer that came from malloc() */ #ifndef TALLOC_ABORT #define TALLOC_ABORT(reason) abort() #endif #ifndef discard_const_p #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) #else # define discard_const_p(type, ptr) ((type *)(ptr)) #endif #endif /* these macros gain us a few percent of speed on gcc */ #if (__GNUC__ >= 3) /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 as its first argument */ #ifndef likely #define likely(x) __builtin_expect(!!(x), 1) #endif #ifndef unlikely #define unlikely(x) __builtin_expect(!!(x), 0) #endif #else #ifndef likely #define likely(x) (x) #endif #ifndef unlikely #define unlikely(x) (x) #endif #endif /* this null_context is only used if talloc_enable_leak_report() or talloc_enable_leak_report_full() is called, otherwise it remains 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 */ static struct { bool initialised; bool enabled; uint8_t fill_value; } talloc_fill; #define TALLOC_FILL_ENV "TALLOC_FREE_FILL" /* * do not wipe the header, to allow the * double-free logic to still work */ #define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \ if (unlikely(talloc_fill.enabled)) { \ size_t _flen = (_tc)->size; \ char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ memset(_fptr, talloc_fill.fill_value, _flen); \ } \ } while (0) #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) /* Mark the whole chunk as not accessable */ #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \ size_t _flen = TC_HDR_SIZE + (_tc)->size; \ char *_fptr = (char *)(_tc); \ VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \ } while(0) #else #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0) #endif #define TC_INVALIDATE_FULL_CHUNK(_tc) do { \ TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \ TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \ } while (0) #define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \ if (unlikely(talloc_fill.enabled)) { \ size_t _flen = (_tc)->size - (_new_size); \ char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ _fptr += (_new_size); \ memset(_fptr, talloc_fill.fill_value, _flen); \ } \ } while (0) #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) /* Mark the unused bytes not accessable */ #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \ size_t _flen = (_tc)->size - (_new_size); \ char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ _fptr += (_new_size); \ VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \ } while (0) #else #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) #endif #define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \ TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \ TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \ } while (0) #define TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \ if (unlikely(talloc_fill.enabled)) { \ size_t _flen = (_tc)->size - (_new_size); \ char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ _fptr += (_new_size); \ memset(_fptr, talloc_fill.fill_value, _flen); \ } \ } while (0) #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) /* Mark the unused bytes as undefined */ #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \ size_t _flen = (_tc)->size - (_new_size); \ char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ _fptr += (_new_size); \ VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \ } while (0) #else #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) #endif #define TC_UNDEFINE_SHRINK_CHUNK(_tc, _new_size) do { \ TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size); \ TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \ } while (0) #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) /* Mark the new bytes as undefined */ #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { \ size_t _old_used = TC_HDR_SIZE + (_tc)->size; \ size_t _new_used = TC_HDR_SIZE + (_new_size); \ size_t _flen = _new_used - _old_used; \ char *_fptr = _old_used + (char *)(_tc); \ VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \ } while (0) #else #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) #endif #define TC_UNDEFINE_GROW_CHUNK(_tc, _new_size) do { \ TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \ } while (0) struct talloc_reference_handle { struct talloc_reference_handle *next, *prev; void *ptr; const char *location; }; struct talloc_memlimit { struct talloc_chunk *parent; struct talloc_memlimit *upper; size_t max_size; size_t cur_size; }; static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); static inline void talloc_memlimit_grow(struct talloc_memlimit *limit, size_t size); static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit, size_t size); static inline void tc_memlimit_update_on_free(struct talloc_chunk *tc); static inline void _tc_set_name_const(struct talloc_chunk *tc, const char *name); static struct talloc_chunk *_vasprintf_tc(const void *t, const char *fmt, va_list ap); typedef int (*talloc_destructor_t)(void *); struct talloc_pool_hdr; struct talloc_chunk { /* * flags includes the talloc magic, which is randomised to * make overwrite attacks harder */ unsigned flags; /* * If you have a logical tree like: * * * / | \ * / | \ * / | \ * * * The actual talloc tree is: * * * | * - - * * The children are linked with next/prev pointers, and * child 1 is linked to the parent with parent/child * pointers. */ struct talloc_chunk *next, *prev; struct talloc_chunk *parent, *child; struct talloc_reference_handle *refs; talloc_destructor_t destructor; const char *name; size_t size; /* * limit semantics: * if 'limit' is set it means all *new* children of the context will * be limited to a total aggregate size ox max_size for memory * allocations. * cur_size is used to keep track of the current use */ struct talloc_memlimit *limit; /* * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" * is a pointer to the struct talloc_chunk of the pool that it was * allocated from. This way children can quickly find the pool to chew * from. */ struct talloc_pool_hdr *pool; }; union talloc_chunk_cast_u { uint8_t *ptr; struct talloc_chunk *chunk; }; /* 16 byte alignment seems to keep everyone happy */ #define TC_ALIGN16(s) (((s)+15)&~15) #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk)) #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) _PUBLIC_ int talloc_version_major(void) { return TALLOC_VERSION_MAJOR; } _PUBLIC_ int talloc_version_minor(void) { return TALLOC_VERSION_MINOR; } _PUBLIC_ int talloc_test_get_magic(void) { return talloc_magic; } static inline void _talloc_chunk_set_free(struct talloc_chunk *tc, const char *location) { /* * Mark this memory as free, and also over-stamp the talloc * magic with the old-style magic. * * Why? This tries to avoid a memory read use-after-free from * disclosing our talloc magic, which would then allow an * attacker to prepare a valid header and so run a destructor. * */ tc->flags = TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE | (tc->flags & TALLOC_FLAG_MASK); /* we mark the freed memory with where we called the free * from. This means on a double free error we can report where * the first free came from */ if (location) { tc->name = location; } } static inline void _talloc_chunk_set_not_free(struct talloc_chunk *tc) { /* * Mark this memory as not free. * * Why? This is memory either in a pool (and so available for * talloc's re-use or after the realloc(). We need to mark * the memory as free() before any realloc() call as we can't * write to the memory after that. * * We put back the normal magic instead of the 'not random' * magic. */ tc->flags = talloc_magic | ((tc->flags & TALLOC_FLAG_MASK) & ~TALLOC_FLAG_FREE); } static void (*talloc_log_fn)(const char *message); _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message)) { talloc_log_fn = log_fn; } #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE void talloc_lib_init(void) __attribute__((constructor)); void talloc_lib_init(void) { uint32_t random_value; #if defined(HAVE_GETAUXVAL) && defined(AT_RANDOM) uint8_t *p; /* * Use the kernel-provided random values used for * ASLR. This won't change per-exec, which is ideal for us */ p = (uint8_t *) getauxval(AT_RANDOM); if (p) { /* * We get 16 bytes from getauxval. By calling rand(), * a totally insecure PRNG, but one that will * deterministically have a different value when called * twice, we ensure that if two talloc-like libraries * are somehow loaded in the same address space, that * because we choose different bytes, we will keep the * protection against collision of multiple talloc * libs. * * This protection is important because the effects of * passing a talloc pointer from one to the other may * be very hard to determine. */ int offset = rand() % (16 - sizeof(random_value)); memcpy(&random_value, p + offset, sizeof(random_value)); } else #endif { /* * Otherwise, hope the location we are loaded in * memory is randomised by someone else */ random_value = ((uintptr_t)talloc_lib_init & 0xFFFFFFFF); } talloc_magic = random_value & ~TALLOC_FLAG_MASK; } #else #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, ...) { va_list ap; char *message; if (!talloc_log_fn) { return; } va_start(ap, fmt); message = talloc_vasprintf(NULL, fmt, ap); va_end(ap); talloc_log_fn(message); talloc_free(message); } static void talloc_log_stderr(const char *message) { fprintf(stderr, "%s", message); } _PUBLIC_ void talloc_set_log_stderr(void) { talloc_set_log_fn(talloc_log_stderr); } static void (*talloc_abort_fn)(const char *reason); _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason)) { talloc_abort_fn = abort_fn; } static void talloc_abort(const char *reason) { talloc_log("%s\n", reason); if (!talloc_abort_fn) { TALLOC_ABORT(reason); } talloc_abort_fn(reason); } static void talloc_abort_access_after_free(void) { talloc_abort("Bad talloc magic value - access after free"); } static void talloc_abort_unknown_value(void) { talloc_abort("Bad talloc magic value - unknown value"); } /* panic if we get a bad magic value */ static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) { const char *pp = (const char *)ptr; struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) != talloc_magic)) { if ((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) == (TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE)) { talloc_log("talloc: access after free error - first free may be at %s\n", tc->name); talloc_abort_access_after_free(); return NULL; } talloc_abort_unknown_value(); return NULL; } return tc; } /* hook into the front of the list */ #define _TLIST_ADD(list, p) \ do { \ if (!(list)) { \ (list) = (p); \ (p)->next = (p)->prev = NULL; \ } else { \ (list)->prev = (p); \ (p)->next = (list); \ (p)->prev = NULL; \ (list) = (p); \ }\ } while (0) /* remove an element from a list - element doesn't have to be in list. */ #define _TLIST_REMOVE(list, p) \ do { \ if ((p) == (list)) { \ (list) = (p)->next; \ if (list) (list)->prev = NULL; \ } else { \ if ((p)->prev) (p)->prev->next = (p)->next; \ if ((p)->next) (p)->next->prev = (p)->prev; \ } \ if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ } while (0) /* return the parent chunk of a pointer */ static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) { struct talloc_chunk *tc; if (unlikely(ptr == NULL)) { return NULL; } tc = talloc_chunk_from_ptr(ptr); while (tc->prev) tc=tc->prev; return tc->parent; } _PUBLIC_ void *talloc_parent(const void *ptr) { struct talloc_chunk *tc = talloc_parent_chunk(ptr); return tc? TC_PTR_FROM_CHUNK(tc) : NULL; } /* find parents name */ _PUBLIC_ const char *talloc_parent_name(const void *ptr) { struct talloc_chunk *tc = talloc_parent_chunk(ptr); return tc? tc->name : NULL; } /* A pool carries an in-pool object count count in the first 16 bytes. bytes. This is done to support talloc_steal() to a parent outside of the pool. The count includes the pool itself, so a talloc_free() on a pool will only destroy the pool if the count has dropped to zero. A talloc_free() of a pool member will reduce the count, and eventually also call free(3) on the pool memory. The object count is not put into "struct talloc_chunk" because it is only relevant for talloc pools and the alignment to 16 bytes would increase the memory footprint of each talloc chunk by those 16 bytes. */ struct talloc_pool_hdr { void *end; unsigned int object_count; size_t poolsize; }; union talloc_pool_hdr_cast_u { uint8_t *ptr; struct talloc_pool_hdr *hdr; }; #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) { union talloc_chunk_cast_u tcc = { .chunk = c }; union talloc_pool_hdr_cast_u tphc = { tcc.ptr - TP_HDR_SIZE }; return tphc.hdr; } static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) { union talloc_pool_hdr_cast_u tphc = { .hdr = h }; union talloc_chunk_cast_u tcc = { .ptr = tphc.ptr + TP_HDR_SIZE }; return tcc.chunk; } static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) { struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize; } static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) { return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; } /* If tc is inside a pool, this gives the next neighbour. */ static inline void *tc_next_chunk(struct talloc_chunk *tc) { return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); } static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) { struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); return tc_next_chunk(tc); } /* Mark the whole remaining pool as not accessable */ static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) { size_t flen = tc_pool_space_left(pool_hdr); if (unlikely(talloc_fill.enabled)) { memset(pool_hdr->end, talloc_fill.fill_value, flen); } #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen); #endif } /* Allocate from a pool */ static inline struct talloc_chunk *tc_alloc_pool(struct talloc_chunk *parent, size_t size, size_t prefix_len) { struct talloc_pool_hdr *pool_hdr = NULL; union talloc_chunk_cast_u tcc; size_t space_left; struct talloc_chunk *result; size_t chunk_size; if (parent == NULL) { return NULL; } if (parent->flags & TALLOC_FLAG_POOL) { pool_hdr = talloc_pool_from_chunk(parent); } else if (parent->flags & TALLOC_FLAG_POOLMEM) { pool_hdr = parent->pool; } if (pool_hdr == NULL) { return NULL; } space_left = tc_pool_space_left(pool_hdr); /* * Align size to 16 bytes */ chunk_size = TC_ALIGN16(size + prefix_len); if (space_left < chunk_size) { return NULL; } tcc = (union talloc_chunk_cast_u) { .ptr = ((uint8_t *)pool_hdr->end) + prefix_len }; result = tcc.chunk; #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size); #endif pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size); result->flags = talloc_magic | TALLOC_FLAG_POOLMEM; result->pool = pool_hdr; pool_hdr->object_count++; return result; } /* Allocate a bit of memory as a child of an existing pointer */ static inline void *__talloc_with_prefix(const void *context, size_t size, size_t prefix_len, struct talloc_chunk **tc_ret) { struct talloc_chunk *tc = NULL; struct talloc_memlimit *limit = NULL; size_t total_len = TC_HDR_SIZE + size + prefix_len; struct talloc_chunk *parent = NULL; if (unlikely(context == NULL)) { context = null_context; } if (unlikely(size >= MAX_TALLOC_SIZE)) { return NULL; } if (unlikely(total_len < TC_HDR_SIZE)) { return NULL; } if (likely(context != NULL)) { parent = talloc_chunk_from_ptr(context); if (parent->limit != NULL) { limit = parent->limit; } tc = tc_alloc_pool(parent, TC_HDR_SIZE+size, prefix_len); } if (tc == NULL) { uint8_t *ptr = NULL; union talloc_chunk_cast_u tcc; /* * Only do the memlimit check/update on actual allocation. */ if (!talloc_memlimit_check(limit, total_len)) { errno = ENOMEM; return NULL; } ptr = malloc(total_len); if (unlikely(ptr == NULL)) { return NULL; } tcc = (union talloc_chunk_cast_u) { .ptr = ptr + prefix_len }; tc = tcc.chunk; tc->flags = talloc_magic; tc->pool = NULL; talloc_memlimit_grow(limit, total_len); } tc->limit = limit; tc->size = size; tc->destructor = NULL; tc->child = NULL; tc->name = NULL; tc->refs = NULL; if (likely(context != NULL)) { if (parent->child) { parent->child->parent = NULL; tc->next = parent->child; tc->next->prev = tc; } else { tc->next = NULL; } tc->parent = parent; tc->prev = NULL; parent->child = tc; } else { tc->next = tc->prev = tc->parent = NULL; } *tc_ret = tc; return TC_PTR_FROM_CHUNK(tc); } static inline void *__talloc(const void *context, size_t size, struct talloc_chunk **tc) { return __talloc_with_prefix(context, size, 0, tc); } /* * Create a talloc pool */ static inline void *_talloc_pool(const void *context, size_t size) { struct talloc_chunk *tc; struct talloc_pool_hdr *pool_hdr; void *result; result = __talloc_with_prefix(context, size, TP_HDR_SIZE, &tc); if (unlikely(result == NULL)) { return NULL; } pool_hdr = talloc_pool_from_chunk(tc); tc->flags |= TALLOC_FLAG_POOL; tc->size = 0; pool_hdr->object_count = 1; pool_hdr->end = result; pool_hdr->poolsize = size; tc_invalidate_pool(pool_hdr); return result; } _PUBLIC_ void *talloc_pool(const void *context, size_t size) { return _talloc_pool(context, size); } /* * Create a talloc pool correctly sized for a basic size plus * a number of subobjects whose total size is given. Essentially * a custom allocator for talloc to reduce fragmentation. */ _PUBLIC_ void *_talloc_pooled_object(const void *ctx, size_t type_size, const char *type_name, unsigned num_subobjects, size_t total_subobjects_size) { size_t poolsize, subobjects_slack, tmp; struct talloc_chunk *tc; struct talloc_pool_hdr *pool_hdr; void *ret; poolsize = type_size + total_subobjects_size; if ((poolsize < type_size) || (poolsize < total_subobjects_size)) { goto overflow; } if (num_subobjects == UINT_MAX) { goto overflow; } num_subobjects += 1; /* the object body itself */ /* * Alignment can increase the pool size by at most 15 bytes per object * plus alignment for the object itself */ subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects; if (subobjects_slack < num_subobjects) { goto overflow; } tmp = poolsize + subobjects_slack; if ((tmp < poolsize) || (tmp < subobjects_slack)) { goto overflow; } poolsize = tmp; ret = _talloc_pool(ctx, poolsize); if (ret == NULL) { return NULL; } tc = talloc_chunk_from_ptr(ret); tc->size = type_size; pool_hdr = talloc_pool_from_chunk(tc); #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size); #endif pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size)); _tc_set_name_const(tc, type_name); return ret; overflow: return NULL; } /* setup a destructor to be called on free of a pointer the destructor should return 0 on success, or -1 on failure. if the destructor fails then the free is failed, and the memory can be continued to be used */ _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) { struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); tc->destructor = destructor; } /* increase the reference count on a piece of memory. */ _PUBLIC_ int talloc_increase_ref_count(const void *ptr) { if (unlikely(!talloc_reference(null_context, ptr))) { return -1; } return 0; } /* helper for talloc_reference() this is referenced by a function pointer and should not be inline */ static int talloc_reference_destructor(struct talloc_reference_handle *handle) { struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr); _TLIST_REMOVE(ptr_tc->refs, handle); return 0; } /* more efficient way to add a name to a pointer - the name must point to a true string constant */ static inline void _tc_set_name_const(struct talloc_chunk *tc, const char *name) { tc->name = name; } /* internal talloc_named_const() */ static inline void *_talloc_named_const(const void *context, size_t size, const char *name) { void *ptr; struct talloc_chunk *tc; ptr = __talloc(context, size, &tc); if (unlikely(ptr == NULL)) { return NULL; } _tc_set_name_const(tc, name); return ptr; } /* make a secondary reference to a pointer, hanging off the given context. the pointer remains valid until both the original caller and this given context are freed. the major use for this is when two different structures need to reference the same underlying data, and you want to be able to free the two instances separately, and in either order */ _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location) { struct talloc_chunk *tc; struct talloc_reference_handle *handle; if (unlikely(ptr == NULL)) return NULL; tc = talloc_chunk_from_ptr(ptr); handle = (struct talloc_reference_handle *)_talloc_named_const(context, sizeof(struct talloc_reference_handle), TALLOC_MAGIC_REFERENCE); if (unlikely(handle == NULL)) return NULL; /* note that we hang the destructor off the handle, not the main context as that allows the caller to still setup their own destructor on the context if they want to */ talloc_set_destructor(handle, talloc_reference_destructor); handle->ptr = discard_const_p(void, ptr); handle->location = location; _TLIST_ADD(tc->refs, handle); return handle->ptr; } static void *_talloc_steal_internal(const void *new_ctx, const void *ptr); static inline void _tc_free_poolmem(struct talloc_chunk *tc, const char *location) { struct talloc_pool_hdr *pool; struct talloc_chunk *pool_tc; void *next_tc; pool = tc->pool; pool_tc = talloc_chunk_from_pool(pool); next_tc = tc_next_chunk(tc); _talloc_chunk_set_free(tc, location); TC_INVALIDATE_FULL_CHUNK(tc); if (unlikely(pool->object_count == 0)) { talloc_abort("Pool object count zero!"); return; } pool->object_count--; if (unlikely(pool->object_count == 1 && !(pool_tc->flags & TALLOC_FLAG_FREE))) { /* * if there is just one object left in the pool * and pool->flags does not have TALLOC_FLAG_FREE, * it means this is the pool itself and * the rest is available for new objects * again. */ pool->end = tc_pool_first_chunk(pool); tc_invalidate_pool(pool); return; } if (unlikely(pool->object_count == 0)) { /* * we mark the freed memory with where we called the free * from. This means on a double free error we can report where * the first free came from */ pool_tc->name = location; if (pool_tc->flags & TALLOC_FLAG_POOLMEM) { _tc_free_poolmem(pool_tc, location); } else { /* * The tc_memlimit_update_on_free() * call takes into account the * prefix TP_HDR_SIZE allocated before * the pool talloc_chunk. */ tc_memlimit_update_on_free(pool_tc); TC_INVALIDATE_FULL_CHUNK(pool_tc); free(pool); } return; } if (pool->end == next_tc) { /* * if pool->pool still points to end of * 'tc' (which is stored in the 'next_tc' variable), * we can reclaim the memory of 'tc'. */ pool->end = tc; return; } /* * Do nothing. The memory is just "wasted", waiting for the pool * itself to be freed. */ } static inline void _tc_free_children_internal(struct talloc_chunk *tc, void *ptr, const char *location); static inline int _talloc_free_internal(void *ptr, const char *location); /* internal free call that takes a struct talloc_chunk *. */ static inline int _tc_free_internal(struct talloc_chunk *tc, const char *location) { void *ptr_to_free; void *ptr = TC_PTR_FROM_CHUNK(tc); if (unlikely(tc->refs)) { int is_child; /* check if this is a reference from a child or * grandchild back to it's parent or grandparent * * in that case we need to remove the reference and * call another instance of talloc_free() on the current * pointer. */ is_child = talloc_is_parent(tc->refs, ptr); _talloc_free_internal(tc->refs, location); if (is_child) { return _talloc_free_internal(ptr, location); } return -1; } if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) { /* we have a free loop - stop looping */ return 0; } if (unlikely(tc->destructor)) { talloc_destructor_t d = tc->destructor; /* * Protect the destructor against some overwrite * attacks, by explicitly checking it has the right * magic here. */ if (talloc_chunk_from_ptr(ptr) != tc) { /* * This can't actually happen, the * call itself will panic. */ TALLOC_ABORT("talloc_chunk_from_ptr failed!"); } if (d == (talloc_destructor_t)-1) { return -1; } tc->destructor = (talloc_destructor_t)-1; if (d(ptr) == -1) { /* * Only replace the destructor pointer if * calling the destructor didn't modify it. */ if (tc->destructor == (talloc_destructor_t)-1) { tc->destructor = d; } return -1; } tc->destructor = NULL; } if (tc->parent) { _TLIST_REMOVE(tc->parent->child, tc); if (tc->parent->child) { tc->parent->child->parent = tc->parent; } } else { if (tc->prev) tc->prev->next = tc->next; if (tc->next) tc->next->prev = tc->prev; tc->prev = tc->next = NULL; } tc->flags |= TALLOC_FLAG_LOOP; _tc_free_children_internal(tc, ptr, location); _talloc_chunk_set_free(tc, location); if (tc->flags & TALLOC_FLAG_POOL) { struct talloc_pool_hdr *pool; pool = talloc_pool_from_chunk(tc); if (unlikely(pool->object_count == 0)) { talloc_abort("Pool object count zero!"); return 0; } pool->object_count--; if (likely(pool->object_count != 0)) { return 0; } /* * With object_count==0, a pool becomes a normal piece of * memory to free. If it's allocated inside a pool, it needs * to be freed as poolmem, else it needs to be just freed. */ ptr_to_free = pool; } else { ptr_to_free = tc; } if (tc->flags & TALLOC_FLAG_POOLMEM) { _tc_free_poolmem(tc, location); return 0; } tc_memlimit_update_on_free(tc); TC_INVALIDATE_FULL_CHUNK(tc); free(ptr_to_free); return 0; } /* internal talloc_free call */ static inline int _talloc_free_internal(void *ptr, const char *location) { struct talloc_chunk *tc; if (unlikely(ptr == NULL)) { return -1; } /* possibly initialised the talloc fill value */ if (unlikely(!talloc_fill.initialised)) { const char *fill = getenv(TALLOC_FILL_ENV); if (fill != NULL) { talloc_fill.enabled = true; talloc_fill.fill_value = strtoul(fill, NULL, 0); } talloc_fill.initialised = true; } tc = talloc_chunk_from_ptr(ptr); return _tc_free_internal(tc, location); } static inline size_t _talloc_total_limit_size(const void *ptr, struct talloc_memlimit *old_limit, struct talloc_memlimit *new_limit); /* move a lump of memory from one talloc context to another return the ptr on success, or NULL if it could not be transferred. passing NULL as ptr will always return NULL with no side effects. */ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) { struct talloc_chunk *tc, *new_tc; size_t ctx_size = 0; if (unlikely(!ptr)) { return NULL; } if (unlikely(new_ctx == NULL)) { new_ctx = null_context; } tc = talloc_chunk_from_ptr(ptr); if (tc->limit != NULL) { ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); /* Decrement the memory limit from the source .. */ talloc_memlimit_shrink(tc->limit->upper, ctx_size); if (tc->limit->parent == tc) { tc->limit->upper = NULL; } else { tc->limit = NULL; } } if (unlikely(new_ctx == NULL)) { if (tc->parent) { _TLIST_REMOVE(tc->parent->child, tc); if (tc->parent->child) { tc->parent->child->parent = tc->parent; } } else { if (tc->prev) tc->prev->next = tc->next; if (tc->next) tc->next->prev = tc->prev; } tc->parent = tc->next = tc->prev = NULL; return discard_const_p(void, ptr); } new_tc = talloc_chunk_from_ptr(new_ctx); if (unlikely(tc == new_tc || tc->parent == new_tc)) { return discard_const_p(void, ptr); } if (tc->parent) { _TLIST_REMOVE(tc->parent->child, tc); if (tc->parent->child) { tc->parent->child->parent = tc->parent; } } else { if (tc->prev) tc->prev->next = tc->next; if (tc->next) tc->next->prev = tc->prev; tc->prev = tc->next = NULL; } tc->parent = new_tc; if (new_tc->child) new_tc->child->parent = NULL; _TLIST_ADD(new_tc->child, tc); if (tc->limit || new_tc->limit) { ctx_size = _talloc_total_limit_size(ptr, tc->limit, new_tc->limit); /* .. and increment it in the destination. */ if (new_tc->limit) { talloc_memlimit_grow(new_tc->limit, ctx_size); } } return discard_const_p(void, ptr); } /* move a lump of memory from one talloc context to another return the ptr on success, or NULL if it could not be transferred. passing NULL as ptr will always return NULL with no side effects. */ _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location) { struct talloc_chunk *tc; if (unlikely(ptr == NULL)) { return NULL; } tc = talloc_chunk_from_ptr(ptr); if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) { struct talloc_reference_handle *h; talloc_log("WARNING: talloc_steal with references at %s\n", location); for (h=tc->refs; h; h=h->next) { talloc_log("\treference at %s\n", h->location); } } #if 0 /* this test is probably too expensive to have on in the normal build, but it useful for debugging */ if (talloc_is_parent(new_ctx, ptr)) { talloc_log("WARNING: stealing into talloc child at %s\n", location); } #endif return _talloc_steal_internal(new_ctx, ptr); } /* this is like a talloc_steal(), but you must supply the old parent. This resolves the ambiguity in a talloc_steal() which is called on a context that has more than one parent (via references) The old parent can be either a reference or a parent */ _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr) { struct talloc_chunk *tc; struct talloc_reference_handle *h; if (unlikely(ptr == NULL)) { return NULL; } if (old_parent == talloc_parent(ptr)) { return _talloc_steal_internal(new_parent, ptr); } tc = talloc_chunk_from_ptr(ptr); for (h=tc->refs;h;h=h->next) { if (talloc_parent(h) == old_parent) { if (_talloc_steal_internal(new_parent, h) != h) { return NULL; } return discard_const_p(void, ptr); } } /* it wasn't a parent */ return NULL; } /* remove a secondary reference to a pointer. This undo's what talloc_reference() has done. The context and pointer arguments must match those given to a talloc_reference() */ static inline int talloc_unreference(const void *context, const void *ptr) { struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); struct talloc_reference_handle *h; if (unlikely(context == NULL)) { context = null_context; } for (h=tc->refs;h;h=h->next) { struct talloc_chunk *p = talloc_parent_chunk(h); if (p == NULL) { if (context == NULL) break; } else if (TC_PTR_FROM_CHUNK(p) == context) { break; } } if (h == NULL) { return -1; } return _talloc_free_internal(h, __location__); } /* remove a specific parent context from a pointer. This is a more controlled variant of talloc_free() */ _PUBLIC_ int talloc_unlink(const void *context, void *ptr) { struct talloc_chunk *tc_p, *new_p, *tc_c; void *new_parent; if (ptr == NULL) { return -1; } if (context == NULL) { context = null_context; } if (talloc_unreference(context, ptr) == 0) { return 0; } if (context != NULL) { tc_c = talloc_chunk_from_ptr(context); } else { tc_c = NULL; } if (tc_c != talloc_parent_chunk(ptr)) { return -1; } tc_p = talloc_chunk_from_ptr(ptr); if (tc_p->refs == NULL) { return _talloc_free_internal(ptr, __location__); } new_p = talloc_parent_chunk(tc_p->refs); if (new_p) { new_parent = TC_PTR_FROM_CHUNK(new_p); } else { new_parent = NULL; } if (talloc_unreference(new_parent, ptr) != 0) { return -1; } _talloc_steal_internal(new_parent, ptr); return 0; } /* add a name to an existing pointer - va_list version */ static inline const char *tc_set_name_v(struct talloc_chunk *tc, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); static inline const char *tc_set_name_v(struct talloc_chunk *tc, const char *fmt, va_list ap) { struct talloc_chunk *name_tc = _vasprintf_tc(TC_PTR_FROM_CHUNK(tc), fmt, ap); if (likely(name_tc)) { tc->name = TC_PTR_FROM_CHUNK(name_tc); _tc_set_name_const(name_tc, ".name"); } else { tc->name = NULL; } return tc->name; } /* add a name to an existing pointer */ _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...) { struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); const char *name; va_list ap; va_start(ap, fmt); name = tc_set_name_v(tc, fmt, ap); va_end(ap); return name; } /* create a named talloc pointer. Any talloc pointer can be named, and talloc_named() operates just like talloc() except that it allows you to name the pointer. */ _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...) { va_list ap; void *ptr; const char *name; struct talloc_chunk *tc; ptr = __talloc(context, size, &tc); if (unlikely(ptr == NULL)) return NULL; va_start(ap, fmt); name = tc_set_name_v(tc, fmt, ap); va_end(ap); if (unlikely(name == NULL)) { _talloc_free_internal(ptr, __location__); return NULL; } return ptr; } /* return the name of a talloc ptr, or "UNNAMED" */ static inline const char *__talloc_get_name(const void *ptr) { struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { return ".reference"; } if (likely(tc->name)) { return tc->name; } return "UNNAMED"; } _PUBLIC_ const char *talloc_get_name(const void *ptr) { return __talloc_get_name(ptr); } /* check if a pointer has the given name. If it does, return the pointer, otherwise return NULL */ _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name) { const char *pname; if (unlikely(ptr == NULL)) return NULL; pname = __talloc_get_name(ptr); if (likely(pname == name || strcmp(pname, name) == 0)) { return discard_const_p(void, ptr); } return NULL; } static void talloc_abort_type_mismatch(const char *location, const char *name, const char *expected) { const char *reason; reason = talloc_asprintf(NULL, "%s: Type mismatch: name[%s] expected[%s]", location, name?name:"NULL", expected); if (!reason) { reason = "Type mismatch"; } talloc_abort(reason); } _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location) { const char *pname; if (unlikely(ptr == NULL)) { talloc_abort_type_mismatch(location, NULL, name); return NULL; } pname = __talloc_get_name(ptr); if (likely(pname == name || strcmp(pname, name) == 0)) { return discard_const_p(void, ptr); } talloc_abort_type_mismatch(location, pname, name); return NULL; } /* this is for compatibility with older versions of talloc */ _PUBLIC_ void *talloc_init(const char *fmt, ...) { va_list ap; void *ptr; const char *name; struct talloc_chunk *tc; ptr = __talloc(NULL, 0, &tc); if (unlikely(ptr == NULL)) return NULL; va_start(ap, fmt); name = tc_set_name_v(tc, fmt, ap); va_end(ap); if (unlikely(name == NULL)) { _talloc_free_internal(ptr, __location__); return NULL; } return ptr; } static inline void _tc_free_children_internal(struct talloc_chunk *tc, void *ptr, const char *location) { while (tc->child) { /* we need to work out who will own an abandoned child if it cannot be freed. In priority order, the first choice is owner of any remaining reference to this pointer, the second choice is our parent, and the final choice is the null context. */ void *child = TC_PTR_FROM_CHUNK(tc->child); const void *new_parent = null_context; if (unlikely(tc->child->refs)) { struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); if (p) new_parent = TC_PTR_FROM_CHUNK(p); } if (unlikely(_tc_free_internal(tc->child, location) == -1)) { if (talloc_parent_chunk(child) != tc) { /* * Destructor already reparented this child. * No further reparenting needed. */ continue; } if (new_parent == null_context) { struct talloc_chunk *p = talloc_parent_chunk(ptr); if (p) new_parent = TC_PTR_FROM_CHUNK(p); } _talloc_steal_internal(new_parent, child); } } } /* this is a replacement for the Samba3 talloc_destroy_pool functionality. It should probably not be used in new code. It's in here to keep the talloc code consistent across Samba 3 and 4. */ _PUBLIC_ void talloc_free_children(void *ptr) { struct talloc_chunk *tc_name = NULL; struct talloc_chunk *tc; if (unlikely(ptr == NULL)) { return; } tc = talloc_chunk_from_ptr(ptr); /* we do not want to free the context name if it is a child .. */ if (likely(tc->child)) { for (tc_name = tc->child; tc_name; tc_name = tc_name->next) { if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break; } if (tc_name) { _TLIST_REMOVE(tc->child, tc_name); if (tc->child) { tc->child->parent = tc; } } } _tc_free_children_internal(tc, ptr, __location__); /* .. so we put it back after all other children have been freed */ if (tc_name) { if (tc->child) { tc->child->parent = NULL; } tc_name->parent = tc; _TLIST_ADD(tc->child, tc_name); } } /* Allocate a bit of memory as a child of an existing pointer */ _PUBLIC_ void *_talloc(const void *context, size_t size) { struct talloc_chunk *tc; return __talloc(context, size, &tc); } /* externally callable talloc_set_name_const() */ _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name) { _tc_set_name_const(talloc_chunk_from_ptr(ptr), name); } /* create a named talloc pointer. Any talloc pointer can be named, and talloc_named() operates just like talloc() except that it allows you to name the pointer. */ _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name) { return _talloc_named_const(context, size, name); } /* free a talloc pointer. This also frees all child pointers of this pointer recursively return 0 if the memory is actually freed, otherwise -1. The memory will not be freed if the ref_count is > 1 or the destructor (if any) returns non-zero */ _PUBLIC_ int _talloc_free(void *ptr, const char *location) { struct talloc_chunk *tc; if (unlikely(ptr == NULL)) { return -1; } tc = talloc_chunk_from_ptr(ptr); if (unlikely(tc->refs != NULL)) { struct talloc_reference_handle *h; if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) { /* in this case we do know which parent should get this pointer, as there is really only one parent */ return talloc_unlink(null_context, ptr); } talloc_log("ERROR: talloc_free with references at %s\n", location); for (h=tc->refs; h; h=h->next) { talloc_log("\treference at %s\n", h->location); } return -1; } return _talloc_free_internal(ptr, location); } /* A talloc version of realloc. The context argument is only used if ptr is NULL */ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) { struct talloc_chunk *tc; void *new_ptr; bool malloced = false; struct talloc_pool_hdr *pool_hdr = NULL; size_t old_size = 0; size_t new_size = 0; /* size zero is equivalent to free() */ if (unlikely(size == 0)) { talloc_unlink(context, ptr); return NULL; } if (unlikely(size >= MAX_TALLOC_SIZE)) { return NULL; } /* realloc(NULL) is equivalent to malloc() */ if (ptr == NULL) { return _talloc_named_const(context, size, name); } tc = talloc_chunk_from_ptr(ptr); /* don't allow realloc on referenced pointers */ if (unlikely(tc->refs)) { return NULL; } /* don't let anybody try to realloc a talloc_pool */ if (unlikely(tc->flags & TALLOC_FLAG_POOL)) { return NULL; } if (tc->limit && (size > tc->size)) { if (!talloc_memlimit_check(tc->limit, (size - tc->size))) { errno = ENOMEM; return NULL; } } /* handle realloc inside a talloc_pool */ if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { pool_hdr = tc->pool; } #if (ALWAYS_REALLOC == 0) /* don't shrink if we have less than 1k to gain */ if (size < tc->size && tc->limit == NULL) { if (pool_hdr) { void *next_tc = tc_next_chunk(tc); TC_INVALIDATE_SHRINK_CHUNK(tc, size); tc->size = size; if (next_tc == pool_hdr->end) { /* note: tc->size has changed, so this works */ pool_hdr->end = tc_next_chunk(tc); } return ptr; } else if ((tc->size - size) < 1024) { /* * if we call TC_INVALIDATE_SHRINK_CHUNK() here * we would need to call TC_UNDEFINE_GROW_CHUNK() * after each realloc call, which slows down * testing a lot :-(. * * That is why we only mark memory as undefined here. */ TC_UNDEFINE_SHRINK_CHUNK(tc, size); /* do not shrink if we have less than 1k to gain */ tc->size = size; return ptr; } } else if (tc->size == size) { /* * do not change the pointer if it is exactly * the same size. */ return ptr; } #endif /* * by resetting magic we catch users of the old memory * * We mark this memory as free, and also over-stamp the talloc * magic with the old-style magic. * * Why? This tries to avoid a memory read use-after-free from * disclosing our talloc magic, which would then allow an * attacker to prepare a valid header and so run a destructor. * * What else? We have to re-stamp back a valid normal magic * on this memory once realloc() is done, as it will have done * a memcpy() into the new valid memory. We can't do this in * reverse as that would be a real use-after-free. */ _talloc_chunk_set_free(tc, NULL); #if ALWAYS_REALLOC if (pool_hdr) { new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0); pool_hdr->object_count--; if (new_ptr == NULL) { new_ptr = malloc(TC_HDR_SIZE+size); malloced = true; new_size = size; } if (new_ptr) { memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); TC_INVALIDATE_FULL_CHUNK(tc); } } else { /* We're doing malloc then free here, so record the difference. */ old_size = tc->size; new_size = size; new_ptr = malloc(size + TC_HDR_SIZE); if (new_ptr) { memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE); free(tc); } } #else if (pool_hdr) { struct talloc_chunk *pool_tc; void *next_tc = tc_next_chunk(tc); size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size); size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size); size_t space_needed; size_t space_left; unsigned int chunk_count = pool_hdr->object_count; pool_tc = talloc_chunk_from_pool(pool_hdr); if (!(pool_tc->flags & TALLOC_FLAG_FREE)) { chunk_count -= 1; } if (chunk_count == 1) { /* * optimize for the case where 'tc' is the only * chunk in the pool. */ char *start = tc_pool_first_chunk(pool_hdr); space_needed = new_chunk_size; space_left = (char *)tc_pool_end(pool_hdr) - start; if (space_left >= space_needed) { size_t old_used = TC_HDR_SIZE + tc->size; size_t new_used = TC_HDR_SIZE + size; new_ptr = start; #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) { /* * The area from * start -> tc may have * been freed and thus been marked as * VALGRIND_MEM_NOACCESS. Set it to * VALGRIND_MEM_UNDEFINED so we can * copy into it without valgrind errors. * We can't just mark * new_ptr -> new_ptr + old_used * as this may overlap on top of tc, * (which is why we use memmove, not * memcpy below) hence the MIN. */ size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used); VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len); } #endif memmove(new_ptr, tc, old_used); tc = (struct talloc_chunk *)new_ptr; TC_UNDEFINE_GROW_CHUNK(tc, size); /* * first we do not align the pool pointer * because we want to invalidate the padding * too. */ pool_hdr->end = new_used + (char *)new_ptr; tc_invalidate_pool(pool_hdr); /* now the aligned pointer */ pool_hdr->end = new_chunk_size + (char *)new_ptr; goto got_new_ptr; } next_tc = NULL; } if (new_chunk_size == old_chunk_size) { TC_UNDEFINE_GROW_CHUNK(tc, size); _talloc_chunk_set_not_free(tc); tc->size = size; return ptr; } if (next_tc == pool_hdr->end) { /* * optimize for the case where 'tc' is the last * chunk in the pool. */ space_needed = new_chunk_size - old_chunk_size; space_left = tc_pool_space_left(pool_hdr); if (space_left >= space_needed) { TC_UNDEFINE_GROW_CHUNK(tc, size); _talloc_chunk_set_not_free(tc); tc->size = size; pool_hdr->end = tc_next_chunk(tc); return ptr; } } new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0); if (new_ptr == NULL) { new_ptr = malloc(TC_HDR_SIZE+size); malloced = true; new_size = size; } if (new_ptr) { memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); _tc_free_poolmem(tc, __location__ "_talloc_realloc"); } } else { /* We're doing realloc here, so record the difference. */ old_size = tc->size; new_size = size; new_ptr = realloc(tc, size + TC_HDR_SIZE); } got_new_ptr: #endif if (unlikely(!new_ptr)) { /* * Ok, this is a strange spot. We have to put back * the old talloc_magic and any flags, except the * TALLOC_FLAG_FREE as this was not free'ed by the * realloc() call after all */ _talloc_chunk_set_not_free(tc); return NULL; } /* * tc is now the new value from realloc(), the old memory we * can't access any more and was preemptively marked as * TALLOC_FLAG_FREE before the call. Now we mark it as not * free again */ tc = (struct talloc_chunk *)new_ptr; _talloc_chunk_set_not_free(tc); if (malloced) { tc->flags &= ~TALLOC_FLAG_POOLMEM; } if (tc->parent) { tc->parent->child = tc; } if (tc->child) { tc->child->parent = tc; } if (tc->prev) { tc->prev->next = tc; } if (tc->next) { tc->next->prev = tc; } if (new_size > old_size) { talloc_memlimit_grow(tc->limit, new_size - old_size); } else if (new_size < old_size) { talloc_memlimit_shrink(tc->limit, old_size - new_size); } tc->size = size; _tc_set_name_const(tc, name); return TC_PTR_FROM_CHUNK(tc); } /* a wrapper around talloc_steal() for situations where you are moving a pointer between two structures, and want the old pointer to be set to NULL */ _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr) { const void **pptr = discard_const_p(const void *,_pptr); void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr)); (*pptr) = NULL; return ret; } enum talloc_mem_count_type { TOTAL_MEM_SIZE, TOTAL_MEM_BLOCKS, TOTAL_MEM_LIMIT, }; static inline size_t _talloc_total_mem_internal(const void *ptr, enum talloc_mem_count_type type, struct talloc_memlimit *old_limit, struct talloc_memlimit *new_limit) { size_t total = 0; struct talloc_chunk *c, *tc; if (ptr == NULL) { ptr = null_context; } if (ptr == NULL) { return 0; } tc = talloc_chunk_from_ptr(ptr); if (old_limit || new_limit) { if (tc->limit && tc->limit->upper == old_limit) { tc->limit->upper = new_limit; } } /* optimize in the memlimits case */ if (type == TOTAL_MEM_LIMIT && tc->limit != NULL && tc->limit != old_limit && tc->limit->parent == tc) { return tc->limit->cur_size; } if (tc->flags & TALLOC_FLAG_LOOP) { return 0; } tc->flags |= TALLOC_FLAG_LOOP; if (old_limit || new_limit) { if (old_limit == tc->limit) { tc->limit = new_limit; } } switch (type) { case TOTAL_MEM_SIZE: if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { total = tc->size; } break; case TOTAL_MEM_BLOCKS: total++; break; case TOTAL_MEM_LIMIT: if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { /* * Don't count memory allocated from a pool * when calculating limits. Only count the * pool itself. */ if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { if (tc->flags & TALLOC_FLAG_POOL) { /* * If this is a pool, the allocated * size is in the pool header, and * remember to add in the prefix * length. */ struct talloc_pool_hdr *pool_hdr = talloc_pool_from_chunk(tc); total = pool_hdr->poolsize + TC_HDR_SIZE + TP_HDR_SIZE; } else { total = tc->size + TC_HDR_SIZE; } } } break; } for (c = tc->child; c; c = c->next) { total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type, old_limit, new_limit); } tc->flags &= ~TALLOC_FLAG_LOOP; return total; } /* return the total size of a talloc pool (subtree) */ _PUBLIC_ size_t talloc_total_size(const void *ptr) { return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL); } /* return the total number of blocks in a talloc pool (subtree) */ _PUBLIC_ size_t talloc_total_blocks(const void *ptr) { return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL); } /* return the number of external references to a pointer */ _PUBLIC_ size_t talloc_reference_count(const void *ptr) { struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); struct talloc_reference_handle *h; size_t ret = 0; for (h=tc->refs;h;h=h->next) { ret++; } return ret; } /* report on memory usage by all children of a pointer, giving a full tree view */ _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *private_data), void *private_data) { struct talloc_chunk *c, *tc; if (ptr == NULL) { ptr = null_context; } if (ptr == NULL) return; tc = talloc_chunk_from_ptr(ptr); if (tc->flags & TALLOC_FLAG_LOOP) { return; } callback(ptr, depth, max_depth, 0, private_data); if (max_depth >= 0 && depth >= max_depth) { return; } tc->flags |= TALLOC_FLAG_LOOP; for (c=tc->child;c;c=c->next) { if (c->name == TALLOC_MAGIC_REFERENCE) { struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c); callback(h->ptr, depth + 1, max_depth, 1, private_data); } else { talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data); } } tc->flags &= ~TALLOC_FLAG_LOOP; } static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) { const char *name = __talloc_get_name(ptr); struct talloc_chunk *tc; FILE *f = (FILE *)_f; if (is_ref) { fprintf(f, "%*sreference to: %s\n", depth*4, "", name); return; } tc = talloc_chunk_from_ptr(ptr); if (tc->limit && tc->limit->parent == tc) { fprintf(f, "%*s%-30s is a memlimit context" " (max_size = %lu bytes, cur_size = %lu bytes)\n", depth*4, "", name, (unsigned long)tc->limit->max_size, (unsigned long)tc->limit->cur_size); } if (depth == 0) { fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", (max_depth < 0 ? "full " :""), name, (unsigned long)talloc_total_size(ptr), (unsigned long)talloc_total_blocks(ptr)); return; } fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", depth*4, "", name, (unsigned long)talloc_total_size(ptr), (unsigned long)talloc_total_blocks(ptr), (int)talloc_reference_count(ptr), ptr); #if 0 fprintf(f, "content: "); if (talloc_total_size(ptr)) { int tot = talloc_total_size(ptr); int i; for (i = 0; i < tot; i++) { if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { fprintf(f, "%c", ((char *)ptr)[i]); } else { fprintf(f, "~%02x", ((char *)ptr)[i]); } } } fprintf(f, "\n"); #endif } /* report on memory usage by all children of a pointer, giving a full tree view */ _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f) { if (f) { talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); fflush(f); } } /* report on memory usage by all children of a pointer, giving a full tree view */ _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f) { talloc_report_depth_file(ptr, 0, -1, f); } /* report on memory usage by all children of a pointer */ _PUBLIC_ void talloc_report(const void *ptr, FILE *f) { talloc_report_depth_file(ptr, 0, 1, f); } /* enable tracking of the NULL context */ _PUBLIC_ void talloc_enable_null_tracking(void) { if (null_context == NULL) { null_context = _talloc_named_const(NULL, 0, "null_context"); if (autofree_context != NULL) { talloc_reparent(NULL, null_context, autofree_context); } } } /* enable tracking of the NULL context, not moving the autofree context into the NULL context. This is needed for the talloc testsuite */ _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void) { if (null_context == NULL) { null_context = _talloc_named_const(NULL, 0, "null_context"); } } /* disable tracking of the NULL context */ _PUBLIC_ void talloc_disable_null_tracking(void) { if (null_context != NULL) { /* we have to move any children onto the real NULL context */ struct talloc_chunk *tc, *tc2; tc = talloc_chunk_from_ptr(null_context); for (tc2 = tc->child; tc2; tc2=tc2->next) { if (tc2->parent == tc) tc2->parent = NULL; if (tc2->prev == tc) tc2->prev = NULL; } for (tc2 = tc->next; tc2; tc2=tc2->next) { if (tc2->parent == tc) tc2->parent = NULL; if (tc2->prev == tc) tc2->prev = NULL; } tc->child = NULL; tc->next = NULL; } talloc_free(null_context); null_context = NULL; } /* enable leak reporting on exit */ _PUBLIC_ void talloc_enable_leak_report(void) { talloc_enable_null_tracking(); talloc_report_null = true; talloc_setup_atexit(); } /* enable full leak reporting on exit */ _PUBLIC_ void talloc_enable_leak_report_full(void) { talloc_enable_null_tracking(); talloc_report_null_full = true; talloc_setup_atexit(); } /* talloc and zero memory. */ _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name) { void *p = _talloc_named_const(ctx, size, name); if (p) { memset(p, '\0', size); } return p; } /* memdup with a talloc. */ _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) { void *newp = NULL; if (likely(size > 0) && unlikely(p == NULL)) { return NULL; } newp = _talloc_named_const(t, size, name); if (likely(newp != NULL) && likely(size > 0)) { memcpy(newp, p, size); } return newp; } static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) { char *ret; struct talloc_chunk *tc; ret = (char *)__talloc(t, len + 1, &tc); if (unlikely(!ret)) return NULL; memcpy(ret, p, len); ret[len] = 0; _tc_set_name_const(tc, ret); return ret; } /* strdup with a talloc */ _PUBLIC_ char *talloc_strdup(const void *t, const char *p) { if (unlikely(!p)) return NULL; return __talloc_strlendup(t, p, strlen(p)); } /* strndup with a talloc */ _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n) { if (unlikely(!p)) return NULL; return __talloc_strlendup(t, p, strnlen(p, n)); } static inline char *__talloc_strlendup_append(char *s, size_t slen, const char *a, size_t alen) { char *ret; ret = talloc_realloc(NULL, s, char, slen + alen + 1); if (unlikely(!ret)) return NULL; /* append the string and the trailing \0 */ memcpy(&ret[slen], a, alen); ret[slen+alen] = 0; _tc_set_name_const(talloc_chunk_from_ptr(ret), ret); return ret; } /* * Appends at the end of the string. */ _PUBLIC_ char *talloc_strdup_append(char *s, const char *a) { if (unlikely(!s)) { return talloc_strdup(NULL, a); } if (unlikely(!a)) { return s; } return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); } /* * Appends at the end of the talloc'ed buffer, * not the end of the string. */ _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a) { size_t slen; if (unlikely(!s)) { return talloc_strdup(NULL, a); } if (unlikely(!a)) { return s; } slen = talloc_get_size(s); if (likely(slen > 0)) { slen--; } return __talloc_strlendup_append(s, slen, a, strlen(a)); } /* * Appends at the end of the string. */ _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n) { if (unlikely(!s)) { return talloc_strndup(NULL, a, n); } if (unlikely(!a)) { return s; } return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); } /* * Appends at the end of the talloc'ed buffer, * not the end of the string. */ _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) { size_t slen; if (unlikely(!s)) { return talloc_strndup(NULL, a, n); } if (unlikely(!a)) { return s; } slen = talloc_get_size(s); if (likely(slen > 0)) { slen--; } return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); } #ifndef HAVE_VA_COPY #ifdef HAVE___VA_COPY #define va_copy(dest, src) __va_copy(dest, src) #else #define va_copy(dest, src) (dest) = (src) #endif #endif static struct talloc_chunk *_vasprintf_tc(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); static struct talloc_chunk *_vasprintf_tc(const void *t, const char *fmt, va_list ap) { int vlen; size_t len; char *ret; va_list ap2; struct talloc_chunk *tc; char buf[1024]; /* this call looks strange, but it makes it work on older solaris boxes */ va_copy(ap2, ap); vlen = vsnprintf(buf, sizeof(buf), fmt, ap2); va_end(ap2); if (unlikely(vlen < 0)) { return NULL; } len = vlen; if (unlikely(len + 1 < len)) { return NULL; } ret = (char *)__talloc(t, len+1, &tc); if (unlikely(!ret)) return NULL; if (len < sizeof(buf)) { memcpy(ret, buf, len+1); } else { va_copy(ap2, ap); vsnprintf(ret, len+1, fmt, ap2); va_end(ap2); } _tc_set_name_const(tc, ret); return tc; } _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) { struct talloc_chunk *tc = _vasprintf_tc(t, fmt, ap); if (tc == NULL) { return NULL; } return TC_PTR_FROM_CHUNK(tc); } /* Perform string formatting, and return a pointer to newly allocated memory holding the result, inside a memory pool. */ _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...) { va_list ap; char *ret; va_start(ap, fmt); ret = talloc_vasprintf(t, fmt, ap); va_end(ap); return ret; } static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, const char *fmt, va_list ap) { ssize_t alen; va_list ap2; char c; va_copy(ap2, ap); alen = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); if (alen <= 0) { /* Either the vsnprintf failed or the format resulted in * no characters being formatted. In the former case, we * ought to return NULL, in the latter we ought to return * the original string. Most current callers of this * function expect it to never return NULL. */ return s; } s = talloc_realloc(NULL, s, char, slen + alen + 1); if (!s) return NULL; va_copy(ap2, ap); vsnprintf(s + slen, alen + 1, fmt, ap2); va_end(ap2); _tc_set_name_const(talloc_chunk_from_ptr(s), s); return s; } /** * Realloc @p s to append the formatted result of @p fmt and @p ap, * and return @p s, which may have moved. Good for gradually * accumulating output into a string buffer. Appends at the end * of the string. **/ _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) { if (unlikely(!s)) { return talloc_vasprintf(NULL, fmt, ap); } return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); } /** * Realloc @p s to append the formatted result of @p fmt and @p ap, * and return @p s, which may have moved. Always appends at the * end of the talloc'ed buffer, not the end of the string. **/ _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) { size_t slen; if (unlikely(!s)) { return talloc_vasprintf(NULL, fmt, ap); } slen = talloc_get_size(s); if (likely(slen > 0)) { slen--; } return __talloc_vaslenprintf_append(s, slen, fmt, ap); } /* Realloc @p s to append the formatted result of @p fmt and return @p s, which may have moved. Good for gradually accumulating output into a string buffer. */ _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...) { va_list ap; va_start(ap, fmt); s = talloc_vasprintf_append(s, fmt, ap); va_end(ap); return s; } /* Realloc @p s to append the formatted result of @p fmt and return @p s, which may have moved. Good for gradually accumulating output into a buffer. */ _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) { va_list ap; va_start(ap, fmt); s = talloc_vasprintf_append_buffer(s, fmt, ap); va_end(ap); return s; } /* alloc an array, checking for integer overflow in the array size */ _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) { if (count >= MAX_TALLOC_SIZE/el_size) { return NULL; } return _talloc_named_const(ctx, el_size * count, name); } /* alloc an zero array, checking for integer overflow in the array size */ _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) { if (count >= MAX_TALLOC_SIZE/el_size) { return NULL; } return _talloc_zero(ctx, el_size * count, name); } /* realloc an array, checking for integer overflow in the array size */ _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) { if (count >= MAX_TALLOC_SIZE/el_size) { return NULL; } return _talloc_realloc(ctx, ptr, el_size * count, name); } /* a function version of talloc_realloc(), so it can be passed as a function pointer to libraries that want a realloc function (a realloc function encapsulates all the basic capabilities of an allocation library, which is why this is useful) */ _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size) { return _talloc_realloc(context, ptr, size, NULL); } static int talloc_autofree_destructor(void *ptr) { autofree_context = NULL; return 0; } /* return a context which will be auto-freed on exit this is useful for reducing the noise in leak reports */ _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(); } return autofree_context; } _PUBLIC_ size_t talloc_get_size(const void *context) { struct talloc_chunk *tc; if (context == NULL) { return 0; } tc = talloc_chunk_from_ptr(context); return tc->size; } /* find a parent of this context that has the given name, if any */ _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name) { struct talloc_chunk *tc; if (context == NULL) { return NULL; } tc = talloc_chunk_from_ptr(context); while (tc) { if (tc->name && strcmp(tc->name, name) == 0) { return TC_PTR_FROM_CHUNK(tc); } while (tc && tc->prev) tc = tc->prev; if (tc) { tc = tc->parent; } } return NULL; } /* show the parentage of a context */ _PUBLIC_ void talloc_show_parents(const void *context, FILE *file) { struct talloc_chunk *tc; if (context == NULL) { fprintf(file, "talloc no parents for NULL\n"); return; } tc = talloc_chunk_from_ptr(context); fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context)); while (tc) { fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc))); while (tc && tc->prev) tc = tc->prev; if (tc) { tc = tc->parent; } } fflush(file); } /* return 1 if ptr is a parent of context */ static int _talloc_is_parent(const void *context, const void *ptr, int depth) { struct talloc_chunk *tc; if (context == NULL) { return 0; } tc = talloc_chunk_from_ptr(context); while (tc) { if (depth <= 0) { return 0; } if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; while (tc && tc->prev) tc = tc->prev; if (tc) { tc = tc->parent; depth--; } } return 0; } /* return 1 if ptr is a parent of context */ _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr) { return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH); } /* return the total size of memory used by this context and all children */ static inline size_t _talloc_total_limit_size(const void *ptr, struct talloc_memlimit *old_limit, struct talloc_memlimit *new_limit) { return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT, old_limit, new_limit); } static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) { struct talloc_memlimit *l; for (l = limit; l != NULL; l = l->upper) { if (l->max_size != 0 && ((l->max_size <= l->cur_size) || (l->max_size - l->cur_size < size))) { return false; } } return true; } /* Update memory limits when freeing a talloc_chunk. */ static void tc_memlimit_update_on_free(struct talloc_chunk *tc) { size_t limit_shrink_size; if (!tc->limit) { return; } /* * Pool entries don't count. Only the pools * themselves are counted as part of the memory * limits. Note that this also takes care of * nested pools which have both flags * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set. */ if (tc->flags & TALLOC_FLAG_POOLMEM) { return; } /* * If we are part of a memory limited context hierarchy * we need to subtract the memory used from the counters */ limit_shrink_size = tc->size+TC_HDR_SIZE; /* * If we're deallocating a pool, take into * account the prefix size added for the pool. */ if (tc->flags & TALLOC_FLAG_POOL) { limit_shrink_size += TP_HDR_SIZE; } talloc_memlimit_shrink(tc->limit, limit_shrink_size); if (tc->limit->parent == tc) { free(tc->limit); } tc->limit = NULL; } /* Increase memory limit accounting after a malloc/realloc. */ static void talloc_memlimit_grow(struct talloc_memlimit *limit, size_t size) { struct talloc_memlimit *l; for (l = limit; l != NULL; l = l->upper) { size_t new_cur_size = l->cur_size + size; if (new_cur_size < l->cur_size) { talloc_abort("logic error in talloc_memlimit_grow\n"); return; } l->cur_size = new_cur_size; } } /* Decrease memory limit accounting after a free/realloc. */ static void talloc_memlimit_shrink(struct talloc_memlimit *limit, size_t size) { struct talloc_memlimit *l; for (l = limit; l != NULL; l = l->upper) { if (l->cur_size < size) { talloc_abort("logic error in talloc_memlimit_shrink\n"); return; } l->cur_size = l->cur_size - size; } } _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) { struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx); struct talloc_memlimit *orig_limit; struct talloc_memlimit *limit = NULL; if (tc->limit && tc->limit->parent == tc) { tc->limit->max_size = max_size; return 0; } orig_limit = tc->limit; limit = malloc(sizeof(struct talloc_memlimit)); if (limit == NULL) { return 1; } limit->parent = tc; limit->max_size = max_size; limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit); if (orig_limit) { limit->upper = orig_limit; } else { limit->upper = NULL; } return 0; } ldb-2.0.8/lib/talloc/talloc.h0000660000000000000000000017466213573675413015727 0ustar rootroot00000000000000#ifndef _TALLOC_H_ #define _TALLOC_H_ /* Unix SMB/CIFS implementation. Samba temporary memory allocation functions Copyright (C) Andrew Tridgell 2004-2005 Copyright (C) Stefan Metzmacher 2006 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @defgroup talloc The talloc API * * talloc is a hierarchical, reference counted memory pool system with * destructors. It is the core memory allocator used in Samba. * * @{ */ #define TALLOC_VERSION_MAJOR 2 #define TALLOC_VERSION_MINOR 2 int talloc_version_major(void); int talloc_version_minor(void); /* This is mostly useful only for testing */ int talloc_test_get_magic(void); /** * @brief Define a talloc parent type * * As talloc is a hierarchial memory allocator, every talloc chunk is a * potential parent to other talloc chunks. So defining a separate type for a * talloc chunk is not strictly necessary. TALLOC_CTX is defined nevertheless, * as it provides an indicator for function arguments. You will frequently * write code like * * @code * struct foo *foo_create(TALLOC_CTX *mem_ctx) * { * struct foo *result; * result = talloc(mem_ctx, struct foo); * if (result == NULL) return NULL; * ... initialize foo ... * return result; * } * @endcode * * In this type of allocating functions it is handy to have a general * TALLOC_CTX type to indicate which parent to put allocated structures on. */ typedef void TALLOC_CTX; /* this uses a little trick to allow __LINE__ to be stringified */ #ifndef __location__ #define __TALLOC_STRING_LINE1__(s) #s #define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s) #define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__) #define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__ #endif #ifndef TALLOC_DEPRECATED #define TALLOC_DEPRECATED 0 #endif #ifndef PRINTF_ATTRIBUTE #if (__GNUC__ >= 3) /** Use gcc attribute to check printf fns. a1 is the 1-based index of * the parameter containing the format, and a2 the index of the first * argument. Note that some gcc 2.x versions don't handle this * properly **/ #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) #else #define PRINTF_ATTRIBUTE(a1, a2) #endif #endif #ifndef _DEPRECATED_ #ifdef HAVE___ATTRIBUTE__ #define _DEPRECATED_ __attribute__ ((deprecated)) #else #define _DEPRECATED_ #endif #endif #ifdef DOXYGEN /** * @brief Create a new talloc context. * * The talloc() macro is the core of the talloc library. It takes a memory * context and a type, and returns a pointer to a new area of memory of the * given type. * * The returned pointer is itself a talloc context, so you can use it as the * context argument to more calls to talloc if you wish. * * The returned pointer is a "child" of the supplied context. This means that if * you talloc_free() the context then the new child disappears as well. * Alternatively you can free just the child. * * @param[in] ctx A talloc context to create a new reference on or NULL to * create a new top level context. * * @param[in] type The type of memory to allocate. * * @return A type casted talloc context or NULL on error. * * @code * unsigned int *a, *b; * * a = talloc(NULL, unsigned int); * b = talloc(a, unsigned int); * @endcode * * @see talloc_zero * @see talloc_array * @see talloc_steal * @see talloc_free */ void *talloc(const void *ctx, #type); #else #define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) void *_talloc(const void *context, size_t size); #endif /** * @brief Create a new top level talloc context. * * This function creates a zero length named talloc context as a top level * context. It is equivalent to: * * @code * talloc_named(NULL, 0, fmt, ...); * @endcode * @param[in] fmt Format string for the name. * * @param[in] ... Additional printf-style arguments. * * @return The allocated memory chunk, NULL on error. * * @see talloc_named() */ void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); #ifdef DOXYGEN /** * @brief Free a chunk of talloc memory. * * The talloc_free() function frees a piece of talloc memory, and all its * children. You can call talloc_free() on any pointer returned by * talloc(). * * The return value of talloc_free() indicates success or failure, with 0 * returned for success and -1 for failure. A possible failure condition * is if the pointer had a destructor attached to it and the destructor * returned -1. See talloc_set_destructor() for details on * destructors. Likewise, if "ptr" is NULL, then the function will make * no modifications and return -1. * * From version 2.0 and onwards, as a special case, talloc_free() is * refused on pointers that have more than one parent associated, as talloc * would have no way of knowing which parent should be removed. This is * different from older versions in the sense that always the reference to * the most recently established parent has been destroyed. Hence to free a * pointer that has more than one parent please use talloc_unlink(). * * To help you find problems in your code caused by this behaviour, if * you do try and free a pointer with more than one parent then the * talloc logging function will be called to give output like this: * * @code * ERROR: talloc_free with references at some_dir/source/foo.c:123 * reference at some_dir/source/other.c:325 * reference at some_dir/source/third.c:121 * @endcode * * Please see the documentation for talloc_set_log_fn() and * talloc_set_log_stderr() for more information on talloc logging * functions. * * If TALLOC_FREE_FILL environment variable is set, * the memory occupied by the context is filled with the value of this variable. * The value should be a numeric representation of the character you want to * use. * * talloc_free() operates recursively on its children. * * @param[in] ptr The chunk to be freed. * * @return Returns 0 on success and -1 on error. A possible * failure condition is if the pointer had a destructor * attached to it and the destructor returned -1. Likewise, * if "ptr" is NULL, then the function will make no * modifications and returns -1. * * Example: * @code * unsigned int *a, *b; * a = talloc(NULL, unsigned int); * b = talloc(a, unsigned int); * * talloc_free(a); // Frees a and b * @endcode * * @see talloc_set_destructor() * @see talloc_unlink() */ int talloc_free(void *ptr); #else #define talloc_free(ctx) _talloc_free(ctx, __location__) int _talloc_free(void *ptr, const char *location); #endif /** * @brief Free a talloc chunk's children. * * The function walks along the list of all children of a talloc context and * talloc_free()s only the children, not the context itself. * * A NULL argument is handled as no-op. * * @param[in] ptr The chunk that you want to free the children of * (NULL is allowed too) */ void talloc_free_children(void *ptr); #ifdef DOXYGEN /** * @brief Assign a destructor function to be called when a chunk is freed. * * The function talloc_set_destructor() sets the "destructor" for the pointer * "ptr". A destructor is a function that is called when the memory used by a * pointer is about to be released. The destructor receives the pointer as an * argument, and should return 0 for success and -1 for failure. * * The destructor can do anything it wants to, including freeing other pieces * of memory. A common use for destructors is to clean up operating system * resources (such as open file descriptors) contained in the structure the * destructor is placed on. * * You can only place one destructor on a pointer. If you need more than one * destructor then you can create a zero-length child of the pointer and place * an additional destructor on that. * * To remove a destructor call talloc_set_destructor() with NULL for the * destructor. * * If your destructor attempts to talloc_free() the pointer that it is the * destructor for then talloc_free() will return -1 and the free will be * ignored. This would be a pointless operation anyway, as the destructor is * only called when the memory is just about to go away. * * @param[in] ptr The talloc chunk to add a destructor to. * * @param[in] destructor The destructor function to be called. NULL to remove * it. * * Example: * @code * static int destroy_fd(int *fd) { * close(*fd); * return 0; * } * * int *open_file(const char *filename) { * int *fd = talloc(NULL, int); * *fd = open(filename, O_RDONLY); * if (*fd < 0) { * talloc_free(fd); * return NULL; * } * // Whenever they free this, we close the file. * talloc_set_destructor(fd, destroy_fd); * return fd; * } * @endcode * * @see talloc() * @see talloc_free() */ void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); /** * @brief Change a talloc chunk's parent. * * The talloc_steal() function changes the parent context of a talloc * pointer. It is typically used when the context that the pointer is * currently a child of is going to be freed and you wish to keep the * memory for a longer time. * * To make the changed hierarchy less error-prone, you might consider to use * talloc_move(). * * If you try and call talloc_steal() on a pointer that has more than one * parent then the result is ambiguous. Talloc will choose to remove the * parent that is currently indicated by talloc_parent() and replace it with * the chosen parent. You will also get a message like this via the talloc * logging functions: * * @code * WARNING: talloc_steal with references at some_dir/source/foo.c:123 * reference at some_dir/source/other.c:325 * reference at some_dir/source/third.c:121 * @endcode * * To unambiguously change the parent of a pointer please see the function * talloc_reparent(). See the talloc_set_log_fn() documentation for more * information on talloc logging. * * @param[in] new_ctx The new parent context. * * @param[in] ptr The talloc chunk to move. * * @return Returns the pointer that you pass it. It does not have * any failure modes. * * @note It is possible to produce loops in the parent/child relationship * if you are not careful with talloc_steal(). No guarantees are provided * as to your sanity or the safety of your data if you do this. */ void *talloc_steal(const void *new_ctx, const void *ptr); #else /* DOXYGEN */ /* try to make talloc_set_destructor() and talloc_steal() type safe, if we have a recent gcc */ #if (__GNUC__ >= 3) #define _TALLOC_TYPEOF(ptr) __typeof__(ptr) #define talloc_set_destructor(ptr, function) \ do { \ int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \ _talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \ } while(0) /* this extremely strange macro is to avoid some braindamaged warning stupidity in gcc 4.1.x */ #define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__); __talloc_steal_ret; }) #else /* __GNUC__ >= 3 */ #define talloc_set_destructor(ptr, function) \ _talloc_set_destructor((ptr), (int (*)(void *))(function)) #define _TALLOC_TYPEOF(ptr) void * #define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__) #endif /* __GNUC__ >= 3 */ void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *)); void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location); #endif /* DOXYGEN */ /** * @brief Assign a name to a talloc chunk. * * Each talloc pointer has a "name". The name is used principally for * debugging purposes, although it is also possible to set and get the name on * a pointer in as a way of "marking" pointers in your code. * * The main use for names on pointer is for "talloc reports". See * talloc_report() and talloc_report_full() for details. Also see * talloc_enable_leak_report() and talloc_enable_leak_report_full(). * * The talloc_set_name() function allocates memory as a child of the * pointer. It is logically equivalent to: * * @code * talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); * @endcode * * @param[in] ptr The talloc chunk to assign a name to. * * @param[in] fmt Format string for the name. * * @param[in] ... Add printf-style additional arguments. * * @return The assigned name, NULL on error. * * @note Multiple calls to talloc_set_name() will allocate more memory without * releasing the name. All of the memory is released when the ptr is freed * using talloc_free(). */ const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); #ifdef DOXYGEN /** * @brief Change a talloc chunk's parent. * * This function has the same effect as talloc_steal(), and additionally sets * the source pointer to NULL. You would use it like this: * * @code * struct foo *X = talloc(tmp_ctx, struct foo); * struct foo *Y; * Y = talloc_move(new_ctx, &X); * @endcode * * @param[in] new_ctx The new parent context. * * @param[in] pptr Pointer to a pointer to the talloc chunk to move. * * @return The pointer to the talloc chunk that moved. * It does not have any failure modes. * */ void *talloc_move(const void *new_ctx, void **pptr); #else #define talloc_move(ctx, pptr) (_TALLOC_TYPEOF(*(pptr)))_talloc_move((ctx),(void *)(pptr)) void *_talloc_move(const void *new_ctx, const void *pptr); #endif /** * @brief Assign a name to a talloc chunk. * * The function is just like talloc_set_name(), but it takes a string constant, * and is much faster. It is extensively used by the "auto naming" macros, such * as talloc_p(). * * This function does not allocate any memory. It just copies the supplied * pointer into the internal representation of the talloc ptr. This means you * must not pass a name pointer to memory that will disappear before the ptr * is freed with talloc_free(). * * @param[in] ptr The talloc chunk to assign a name to. * * @param[in] name Format string for the name. */ void talloc_set_name_const(const void *ptr, const char *name); /** * @brief Create a named talloc chunk. * * The talloc_named() function creates a named talloc pointer. It is * equivalent to: * * @code * ptr = talloc_size(context, size); * talloc_set_name(ptr, fmt, ....); * @endcode * * @param[in] context The talloc context to hang the result off. * * @param[in] size Number of char's that you want to allocate. * * @param[in] fmt Format string for the name. * * @param[in] ... Additional printf-style arguments. * * @return The allocated memory chunk, NULL on error. * * @see talloc_set_name() */ void *talloc_named(const void *context, size_t size, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); /** * @brief Basic routine to allocate a chunk of memory. * * This is equivalent to: * * @code * ptr = talloc_size(context, size); * talloc_set_name_const(ptr, name); * @endcode * * @param[in] context The parent context. * * @param[in] size The number of char's that we want to allocate. * * @param[in] name The name the talloc block has. * * @return The allocated memory chunk, NULL on error. */ void *talloc_named_const(const void *context, size_t size, const char *name); #ifdef DOXYGEN /** * @brief Untyped allocation. * * The function should be used when you don't have a convenient type to pass to * talloc(). Unlike talloc(), it is not type safe (as it returns a void *), so * you are on your own for type checking. * * Best to use talloc() or talloc_array() instead. * * @param[in] ctx The talloc context to hang the result off. * * @param[in] size Number of char's that you want to allocate. * * @return The allocated memory chunk, NULL on error. * * Example: * @code * void *mem = talloc_size(NULL, 100); * @endcode */ void *talloc_size(const void *ctx, size_t size); #else #define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) #endif #ifdef DOXYGEN /** * @brief Allocate into a typed pointer. * * The talloc_ptrtype() macro should be used when you have a pointer and want * to allocate memory to point at with this pointer. When compiling with * gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() and * talloc_get_name() will return the current location in the source file and * not the type. * * @param[in] ctx The talloc context to hang the result off. * * @param[in] type The pointer you want to assign the result to. * * @return The properly casted allocated memory chunk, NULL on * error. * * Example: * @code * unsigned int *a = talloc_ptrtype(NULL, a); * @endcode */ void *talloc_ptrtype(const void *ctx, #type); #else #define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) #endif #ifdef DOXYGEN /** * @brief Allocate a new 0-sized talloc chunk. * * This is a utility macro that creates a new memory context hanging off an * existing context, automatically naming it "talloc_new: __location__" where * __location__ is the source line it is called from. It is particularly * useful for creating a new temporary working context. * * @param[in] ctx The talloc parent context. * * @return A new talloc chunk, NULL on error. */ void *talloc_new(const void *ctx); #else #define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) #endif #ifdef DOXYGEN /** * @brief Allocate a 0-initizialized structure. * * The macro is equivalent to: * * @code * ptr = talloc(ctx, type); * if (ptr) memset(ptr, 0, sizeof(type)); * @endcode * * @param[in] ctx The talloc context to hang the result off. * * @param[in] type The type that we want to allocate. * * @return Pointer to a piece of memory, properly cast to 'type *', * NULL on error. * * Example: * @code * unsigned int *a, *b; * a = talloc_zero(NULL, unsigned int); * b = talloc_zero(a, unsigned int); * @endcode * * @see talloc() * @see talloc_zero_size() * @see talloc_zero_array() */ void *talloc_zero(const void *ctx, #type); /** * @brief Allocate untyped, 0-initialized memory. * * @param[in] ctx The talloc context to hang the result off. * * @param[in] size Number of char's that you want to allocate. * * @return The allocated memory chunk. */ void *talloc_zero_size(const void *ctx, size_t size); #else #define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) #define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) void *_talloc_zero(const void *ctx, size_t size, const char *name); #endif /** * @brief Return the name of a talloc chunk. * * @param[in] ptr The talloc chunk. * * @return The current name for the given talloc pointer. * * @see talloc_set_name() */ const char *talloc_get_name(const void *ptr); /** * @brief Verify that a talloc chunk carries a specified name. * * This function checks if a pointer has the specified name. If it does * then the pointer is returned. * * @param[in] ptr The talloc chunk to check. * * @param[in] name The name to check against. * * @return The pointer if the name matches, NULL if it doesn't. */ void *talloc_check_name(const void *ptr, const char *name); /** * @brief Get the parent chunk of a pointer. * * @param[in] ptr The talloc pointer to inspect. * * @return The talloc parent of ptr, NULL on error. */ void *talloc_parent(const void *ptr); /** * @brief Get a talloc chunk's parent name. * * @param[in] ptr The talloc pointer to inspect. * * @return The name of ptr's parent chunk. */ const char *talloc_parent_name(const void *ptr); /** * @brief Get the total size of a talloc chunk including its children. * * The function returns the total size in bytes used by this pointer and all * child pointers. Mostly useful for debugging. * * Passing NULL is allowed, but it will only give a meaningful result if * talloc_enable_leak_report() or talloc_enable_leak_report_full() has * been called. * * @param[in] ptr The talloc chunk. * * @return The total size. */ size_t talloc_total_size(const void *ptr); /** * @brief Get the number of talloc chunks hanging off a chunk. * * The talloc_total_blocks() function returns the total memory block * count used by this pointer and all child pointers. Mostly useful for * debugging. * * Passing NULL is allowed, but it will only give a meaningful result if * talloc_enable_leak_report() or talloc_enable_leak_report_full() has * been called. * * @param[in] ptr The talloc chunk. * * @return The total size. */ size_t talloc_total_blocks(const void *ptr); #ifdef DOXYGEN /** * @brief Duplicate a memory area into a talloc chunk. * * The function is equivalent to: * * @code * ptr = talloc_size(ctx, size); * if (ptr) memcpy(ptr, p, size); * @endcode * * @param[in] t The talloc context to hang the result off. * * @param[in] p The memory chunk you want to duplicate. * * @param[in] size Number of char's that you want copy. * * @return The allocated memory chunk. * * @see talloc_size() */ void *talloc_memdup(const void *t, const void *p, size_t size); #else #define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); #endif #ifdef DOXYGEN /** * @brief Assign a type to a talloc chunk. * * This macro allows you to force the name of a pointer to be of a particular * type. This can be used in conjunction with talloc_get_type() to do type * checking on void* pointers. * * It is equivalent to this: * * @code * talloc_set_name_const(ptr, #type) * @endcode * * @param[in] ptr The talloc chunk to assign the type to. * * @param[in] type The type to assign. */ void talloc_set_type(const char *ptr, #type); /** * @brief Get a typed pointer out of a talloc pointer. * * This macro allows you to do type checking on talloc pointers. It is * particularly useful for void* private pointers. It is equivalent to * this: * * @code * (type *)talloc_check_name(ptr, #type) * @endcode * * @param[in] ptr The talloc pointer to check. * * @param[in] type The type to check against. * * @return The properly casted pointer given by ptr, NULL on error. */ type *talloc_get_type(const void *ptr, #type); #else #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) #endif #ifdef DOXYGEN /** * @brief Safely turn a void pointer into a typed pointer. * * This macro is used together with talloc(mem_ctx, struct foo). If you had to * assign the talloc chunk pointer to some void pointer variable, * talloc_get_type_abort() is the recommended way to get the convert the void * pointer back to a typed pointer. * * @param[in] ptr The void pointer to convert. * * @param[in] type The type that this chunk contains * * @return The same value as ptr, type-checked and properly cast. */ void *talloc_get_type_abort(const void *ptr, #type); #else #ifdef TALLOC_GET_TYPE_ABORT_NOOP #define talloc_get_type_abort(ptr, type) (type *)(ptr) #else #define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) #endif void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); #endif /** * @brief Find a parent context by name. * * Find a parent memory context of the current context that has the given * name. This can be very useful in complex programs where it may be * difficult to pass all information down to the level you need, but you * know the structure you want is a parent of another context. * * @param[in] ctx The talloc chunk to start from. * * @param[in] name The name of the parent we look for. * * @return The memory context we are looking for, NULL if not * found. */ void *talloc_find_parent_byname(const void *ctx, const char *name); #ifdef DOXYGEN /** * @brief Find a parent context by type. * * Find a parent memory context of the current context that has the given * name. This can be very useful in complex programs where it may be * difficult to pass all information down to the level you need, but you * know the structure you want is a parent of another context. * * Like talloc_find_parent_byname() but takes a type, making it typesafe. * * @param[in] ptr The talloc chunk to start from. * * @param[in] type The type of the parent to look for. * * @return The memory context we are looking for, NULL if not * found. */ void *talloc_find_parent_bytype(const void *ptr, #type); #else #define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) #endif /** * @brief Allocate a talloc pool. * * A talloc pool is a pure optimization for specific situations. In the * release process for Samba 3.2 we found out that we had become considerably * slower than Samba 3.0 was. Profiling showed that malloc(3) was a large CPU * consumer in benchmarks. For Samba 3.2 we have internally converted many * static buffers to dynamically allocated ones, so malloc(3) being beaten * more was no surprise. But it made us slower. * * talloc_pool() is an optimization to call malloc(3) a lot less for the use * pattern Samba has: The SMB protocol is mainly a request/response protocol * where we have to allocate a certain amount of memory per request and free * that after the SMB reply is sent to the client. * * talloc_pool() creates a talloc chunk that you can use as a talloc parent * exactly as you would use any other ::TALLOC_CTX. The difference is that * when you talloc a child of this pool, no malloc(3) is done. Instead, talloc * just increments a pointer inside the talloc_pool. This also works * recursively. If you use the child of the talloc pool as a parent for * grand-children, their memory is also taken from the talloc pool. * * If there is not enough memory in the pool to allocate the new child, * it will create a new talloc chunk as if the parent was a normal talloc * context. * * If you talloc_free() children of a talloc pool, the memory is not given * back to the system. Instead, free(3) is only called if the talloc_pool() * itself is released with talloc_free(). * * The downside of a talloc pool is that if you talloc_move() a child of a * talloc pool to a talloc parent outside the pool, the whole pool memory is * not free(3)'ed until that moved chunk is also talloc_free()ed. * * @param[in] context The talloc context to hang the result off. * * @param[in] size Size of the talloc pool. * * @return The allocated talloc pool, NULL on error. */ void *talloc_pool(const void *context, size_t size); #ifdef DOXYGEN /** * @brief Allocate a talloc object as/with an additional pool. * * This is like talloc_pool(), but's it's more flexible * and allows an object to be a pool for its children. * * @param[in] ctx The talloc context to hang the result off. * * @param[in] type The type that we want to allocate. * * @param[in] num_subobjects The expected number of subobjects, which will * be allocated within the pool. This allocates * space for talloc_chunk headers. * * @param[in] total_subobjects_size The size that all subobjects can use in total. * * * @return The allocated talloc object, NULL on error. */ void *talloc_pooled_object(const void *ctx, #type, unsigned num_subobjects, size_t total_subobjects_size); #else #define talloc_pooled_object(_ctx, _type, \ _num_subobjects, \ _total_subobjects_size) \ (_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \ (_num_subobjects), \ (_total_subobjects_size)) void *_talloc_pooled_object(const void *ctx, size_t type_size, const char *type_name, unsigned num_subobjects, size_t total_subobjects_size); #endif /** * @brief Free a talloc chunk and NULL out the pointer. * * TALLOC_FREE() frees a pointer and sets it to NULL. Use this if you want * immediate feedback (i.e. crash) if you use a pointer after having free'ed * it. * * @param[in] ctx The chunk to be freed. */ #define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0) /* @} ******************************************************************/ /** * \defgroup talloc_ref The talloc reference function. * @ingroup talloc * * This module contains the definitions around talloc references * * @{ */ /** * @brief Increase the reference count of a talloc chunk. * * The talloc_increase_ref_count(ptr) function is exactly equivalent to: * * @code * talloc_reference(NULL, ptr); * @endcode * * You can use either syntax, depending on which you think is clearer in * your code. * * @param[in] ptr The pointer to increase the reference count. * * @return 0 on success, -1 on error. */ int talloc_increase_ref_count(const void *ptr); /** * @brief Get the number of references to a talloc chunk. * * @param[in] ptr The pointer to retrieve the reference count from. * * @return The number of references. */ size_t talloc_reference_count(const void *ptr); #ifdef DOXYGEN /** * @brief Create an additional talloc parent to a pointer. * * The talloc_reference() function makes "context" an additional parent of * ptr. Each additional reference consumes around 48 bytes of memory on intel * x86 platforms. * * If ptr is NULL, then the function is a no-op, and simply returns NULL. * * After creating a reference you can free it in one of the following ways: * * - you can talloc_free() any parent of the original pointer. That * will reduce the number of parents of this pointer by 1, and will * cause this pointer to be freed if it runs out of parents. * * - you can talloc_free() the pointer itself if it has at maximum one * parent. This behaviour has been changed since the release of version * 2.0. Further information in the description of "talloc_free". * * For more control on which parent to remove, see talloc_unlink() * @param[in] ctx The additional parent. * * @param[in] ptr The pointer you want to create an additional parent for. * * @return The original pointer 'ptr', NULL if talloc ran out of * memory in creating the reference. * * @warning You should try to avoid using this interface. It turns a beautiful * talloc-tree into a graph. It is often really hard to debug if you * screw something up by accident. * * Example: * @code * unsigned int *a, *b, *c; * a = talloc(NULL, unsigned int); * b = talloc(NULL, unsigned int); * c = talloc(a, unsigned int); * // b also serves as a parent of c. * talloc_reference(b, c); * @endcode * * @see talloc_unlink() */ void *talloc_reference(const void *ctx, const void *ptr); #else #define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference_loc((ctx),(ptr), __location__) void *_talloc_reference_loc(const void *context, const void *ptr, const char *location); #endif /** * @brief Remove a specific parent from a talloc chunk. * * The function removes a specific parent from ptr. The context passed must * either be a context used in talloc_reference() with this pointer, or must be * a direct parent of ptr. * * You can just use talloc_free() instead of talloc_unlink() if there * is at maximum one parent. This behaviour has been changed since the * release of version 2.0. Further information in the description of * "talloc_free". * * @param[in] context The talloc parent to remove. * * @param[in] ptr The talloc ptr you want to remove the parent from. * * @return 0 on success, -1 on error. * * @note If the parent has already been removed using talloc_free() then * this function will fail and will return -1. Likewise, if ptr is NULL, * then the function will make no modifications and return -1. * * @warning You should try to avoid using this interface. It turns a beautiful * talloc-tree into a graph. It is often really hard to debug if you * screw something up by accident. * * Example: * @code * unsigned int *a, *b, *c; * a = talloc(NULL, unsigned int); * b = talloc(NULL, unsigned int); * c = talloc(a, unsigned int); * // b also serves as a parent of c. * talloc_reference(b, c); * talloc_unlink(b, c); * @endcode */ int talloc_unlink(const void *context, void *ptr); /** * @brief Provide a talloc context that is freed at program exit. * * This is a handy utility function that returns a talloc context * which will be automatically freed on program exit. This can be used * to reduce the noise in memory leak reports. * * Never use this in code that might be used in objects loaded with * dlopen and unloaded with dlclose. talloc_autofree_context() * internally uses atexit(3). Some platforms like modern Linux handles * this fine, but for example FreeBSD does not deal well with dlopen() * and atexit() used simultaneously: dlclose() does not clean up the * list of atexit-handlers, so when the program exits the code that * was registered from within talloc_autofree_context() is gone, the * program crashes at exit. * * @return A talloc context, NULL on error. */ void *talloc_autofree_context(void) _DEPRECATED_; /** * @brief Get the size of a talloc chunk. * * This function lets you know the amount of memory allocated so far by * this context. It does NOT account for subcontext memory. * This can be used to calculate the size of an array. * * @param[in] ctx The talloc chunk. * * @return The size of the talloc chunk. */ size_t talloc_get_size(const void *ctx); /** * @brief Show the parentage of a context. * * @param[in] context The talloc context to look at. * * @param[in] file The output to use, a file, stdout or stderr. */ void talloc_show_parents(const void *context, FILE *file); /** * @brief Check if a context is parent of a talloc chunk. * * This checks if context is referenced in the talloc hierarchy above ptr. * * @param[in] context The assumed talloc context. * * @param[in] ptr The talloc chunk to check. * * @return Return 1 if this is the case, 0 if not. */ int talloc_is_parent(const void *context, const void *ptr); /** * @brief Change the parent context of a talloc pointer. * * The function changes the parent context of a talloc pointer. It is typically * used when the context that the pointer is currently a child of is going to be * freed and you wish to keep the memory for a longer time. * * The difference between talloc_reparent() and talloc_steal() is that * talloc_reparent() can specify which parent you wish to change. This is * useful when a pointer has multiple parents via references. * * @param[in] old_parent * @param[in] new_parent * @param[in] ptr * * @return Return the pointer you passed. It does not have any * failure modes. */ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr); /* @} ******************************************************************/ /** * @defgroup talloc_array The talloc array functions * @ingroup talloc * * Talloc contains some handy helpers for handling Arrays conveniently * * @{ */ #ifdef DOXYGEN /** * @brief Allocate an array. * * The macro is equivalent to: * * @code * (type *)talloc_size(ctx, sizeof(type) * count); * @endcode * * except that it provides integer overflow protection for the multiply, * returning NULL if the multiply overflows. * * @param[in] ctx The talloc context to hang the result off. * * @param[in] type The type that we want to allocate. * * @param[in] count The number of 'type' elements you want to allocate. * * @return The allocated result, properly cast to 'type *', NULL on * error. * * Example: * @code * unsigned int *a, *b; * a = talloc_zero(NULL, unsigned int); * b = talloc_array(a, unsigned int, 100); * @endcode * * @see talloc() * @see talloc_zero_array() */ void *talloc_array(const void *ctx, #type, unsigned count); #else #define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); #endif #ifdef DOXYGEN /** * @brief Allocate an array. * * @param[in] ctx The talloc context to hang the result off. * * @param[in] size The size of an array element. * * @param[in] count The number of elements you want to allocate. * * @return The allocated result, NULL on error. */ void *talloc_array_size(const void *ctx, size_t size, unsigned count); #else #define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) #endif #ifdef DOXYGEN /** * @brief Allocate an array into a typed pointer. * * The macro should be used when you have a pointer to an array and want to * allocate memory of an array to point at with this pointer. When compiling * with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() * and talloc_get_name() will return the current location in the source file * and not the type. * * @param[in] ctx The talloc context to hang the result off. * * @param[in] ptr The pointer you want to assign the result to. * * @param[in] count The number of elements you want to allocate. * * @return The allocated memory chunk, properly casted. NULL on * error. */ void *talloc_array_ptrtype(const void *ctx, const void *ptr, unsigned count); #else #define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) #endif #ifdef DOXYGEN /** * @brief Get the number of elements in a talloc'ed array. * * A talloc chunk carries its own size, so for talloc'ed arrays it is not * necessary to store the number of elements explicitly. * * @param[in] ctx The allocated array. * * @return The number of elements in ctx. */ size_t talloc_array_length(const void *ctx); #else #define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx)) #endif #ifdef DOXYGEN /** * @brief Allocate a zero-initialized array * * @param[in] ctx The talloc context to hang the result off. * * @param[in] type The type that we want to allocate. * * @param[in] count The number of "type" elements you want to allocate. * * @return The allocated result casted to "type *", NULL on error. * * The talloc_zero_array() macro is equivalent to: * * @code * ptr = talloc_array(ctx, type, count); * if (ptr) memset(ptr, 0, sizeof(type) * count); * @endcode */ void *talloc_zero_array(const void *ctx, #type, unsigned count); #else #define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); #endif #ifdef DOXYGEN /** * @brief Change the size of a talloc array. * * The macro changes the size of a talloc pointer. The 'count' argument is the * number of elements of type 'type' that you want the resulting pointer to * hold. * * talloc_realloc() has the following equivalences: * * @code * talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); * talloc_realloc(ctx, NULL, type, N) ==> talloc_array(ctx, type, N); * talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); * @endcode * * The "context" argument is only used if "ptr" is NULL, otherwise it is * ignored. * * @param[in] ctx The parent context used if ptr is NULL. * * @param[in] ptr The chunk to be resized. * * @param[in] type The type of the array element inside ptr. * * @param[in] count The intended number of array elements. * * @return The new array, NULL on error. The call will fail either * due to a lack of memory, or because the pointer has more * than one parent (see talloc_reference()). */ void *talloc_realloc(const void *ctx, void *ptr, #type, size_t count); #else #define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); #endif #ifdef DOXYGEN /** * @brief Untyped realloc to change the size of a talloc array. * * The macro is useful when the type is not known so the typesafe * talloc_realloc() cannot be used. * * @param[in] ctx The parent context used if 'ptr' is NULL. * * @param[in] ptr The chunk to be resized. * * @param[in] size The new chunk size. * * @return The new array, NULL on error. */ void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); #else #define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); #endif /** * @brief Provide a function version of talloc_realloc_size. * * This is a non-macro version of talloc_realloc(), which is useful as * libraries sometimes want a ralloc function pointer. A realloc() * implementation encapsulates the functionality of malloc(), free() and * realloc() in one call, which is why it is useful to be able to pass around * a single function pointer. * * @param[in] context The parent context used if ptr is NULL. * * @param[in] ptr The chunk to be resized. * * @param[in] size The new chunk size. * * @return The new chunk, NULL on error. */ void *talloc_realloc_fn(const void *context, void *ptr, size_t size); /* @} ******************************************************************/ /** * @defgroup talloc_string The talloc string functions. * @ingroup talloc * * talloc string allocation and manipulation functions. * @{ */ /** * @brief Duplicate a string into a talloc chunk. * * This function is equivalent to: * * @code * ptr = talloc_size(ctx, strlen(p)+1); * if (ptr) memcpy(ptr, p, strlen(p)+1); * @endcode * * This functions sets the name of the new pointer to the passed * string. This is equivalent to: * * @code * talloc_set_name_const(ptr, ptr) * @endcode * * @param[in] t The talloc context to hang the result off. * * @param[in] p The string you want to duplicate. * * @return The duplicated string, NULL on error. */ char *talloc_strdup(const void *t, const char *p); /** * @brief Append a string to given string. * * The destination string is reallocated to take * strlen(s) + strlen(a) + 1 characters. * * This functions sets the name of the new pointer to the new * string. This is equivalent to: * * @code * talloc_set_name_const(ptr, ptr) * @endcode * * If s == NULL then new context is created. * * @param[in] s The destination to append to. * * @param[in] a The string you want to append. * * @return The concatenated strings, NULL on error. * * @see talloc_strdup() * @see talloc_strdup_append_buffer() */ char *talloc_strdup_append(char *s, const char *a); /** * @brief Append a string to a given buffer. * * This is a more efficient version of talloc_strdup_append(). It determines the * length of the destination string by the size of the talloc context. * * Use this very carefully as it produces a different result than * talloc_strdup_append() when a zero character is in the middle of the * destination string. * * @code * char *str_a = talloc_strdup(NULL, "hello world"); * char *str_b = talloc_strdup(NULL, "hello world"); * str_a[5] = str_b[5] = '\0' * * char *app = talloc_strdup_append(str_a, ", hello"); * char *buf = talloc_strdup_append_buffer(str_b, ", hello"); * * printf("%s\n", app); // hello, hello (app = "hello, hello") * printf("%s\n", buf); // hello (buf = "hello\0world, hello") * @endcode * * If s == NULL then new context is created. * * @param[in] s The destination buffer to append to. * * @param[in] a The string you want to append. * * @return The concatenated strings, NULL on error. * * @see talloc_strdup() * @see talloc_strdup_append() * @see talloc_array_length() */ char *talloc_strdup_append_buffer(char *s, const char *a); /** * @brief Duplicate a length-limited string into a talloc chunk. * * This function is the talloc equivalent of the C library function strndup(3). * * This functions sets the name of the new pointer to the passed string. This is * equivalent to: * * @code * talloc_set_name_const(ptr, ptr) * @endcode * * @param[in] t The talloc context to hang the result off. * * @param[in] p The string you want to duplicate. * * @param[in] n The maximum string length to duplicate. * * @return The duplicated string, NULL on error. */ char *talloc_strndup(const void *t, const char *p, size_t n); /** * @brief Append at most n characters of a string to given string. * * The destination string is reallocated to take * strlen(s) + strnlen(a, n) + 1 characters. * * This functions sets the name of the new pointer to the new * string. This is equivalent to: * * @code * talloc_set_name_const(ptr, ptr) * @endcode * * If s == NULL then new context is created. * * @param[in] s The destination string to append to. * * @param[in] a The source string you want to append. * * @param[in] n The number of characters you want to append from the * string. * * @return The concatenated strings, NULL on error. * * @see talloc_strndup() * @see talloc_strndup_append_buffer() */ char *talloc_strndup_append(char *s, const char *a, size_t n); /** * @brief Append at most n characters of a string to given buffer * * This is a more efficient version of talloc_strndup_append(). It determines * the length of the destination string by the size of the talloc context. * * Use this very carefully as it produces a different result than * talloc_strndup_append() when a zero character is in the middle of the * destination string. * * @code * char *str_a = talloc_strdup(NULL, "hello world"); * char *str_b = talloc_strdup(NULL, "hello world"); * str_a[5] = str_b[5] = '\0' * * char *app = talloc_strndup_append(str_a, ", hello", 7); * char *buf = talloc_strndup_append_buffer(str_b, ", hello", 7); * * printf("%s\n", app); // hello, hello (app = "hello, hello") * printf("%s\n", buf); // hello (buf = "hello\0world, hello") * @endcode * * If s == NULL then new context is created. * * @param[in] s The destination buffer to append to. * * @param[in] a The source string you want to append. * * @param[in] n The number of characters you want to append from the * string. * * @return The concatenated strings, NULL on error. * * @see talloc_strndup() * @see talloc_strndup_append() * @see talloc_array_length() */ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); /** * @brief Format a string given a va_list. * * This function is the talloc equivalent of the C library function * vasprintf(3). * * This functions sets the name of the new pointer to the new string. This is * equivalent to: * * @code * talloc_set_name_const(ptr, ptr) * @endcode * * @param[in] t The talloc context to hang the result off. * * @param[in] fmt The format string. * * @param[in] ap The parameters used to fill fmt. * * @return The formatted string, NULL on error. */ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); /** * @brief Format a string given a va_list and append it to the given destination * string. * * @param[in] s The destination string to append to. * * @param[in] fmt The format string. * * @param[in] ap The parameters used to fill fmt. * * @return The formatted string, NULL on error. * * @see talloc_vasprintf() */ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); /** * @brief Format a string given a va_list and append it to the given destination * buffer. * * @param[in] s The destination buffer to append to. * * @param[in] fmt The format string. * * @param[in] ap The parameters used to fill fmt. * * @return The formatted string, NULL on error. * * @see talloc_vasprintf() */ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); /** * @brief Format a string. * * This function is the talloc equivalent of the C library function asprintf(3). * * This functions sets the name of the new pointer to the new string. This is * equivalent to: * * @code * talloc_set_name_const(ptr, ptr) * @endcode * * @param[in] t The talloc context to hang the result off. * * @param[in] fmt The format string. * * @param[in] ... The parameters used to fill fmt. * * @return The formatted string, NULL on error. */ char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); /** * @brief Append a formatted string to another string. * * This function appends the given formatted string to the given string. Use * this variant when the string in the current talloc buffer may have been * truncated in length. * * This functions sets the name of the new pointer to the new * string. This is equivalent to: * * @code * talloc_set_name_const(ptr, ptr) * @endcode * * If s == NULL then new context is created. * * @param[in] s The string to append to. * * @param[in] fmt The format string. * * @param[in] ... The parameters used to fill fmt. * * @return The formatted string, NULL on error. */ char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); /** * @brief Append a formatted string to another string. * * This is a more efficient version of talloc_asprintf_append(). It determines * the length of the destination string by the size of the talloc context. * * Use this very carefully as it produces a different result than * talloc_asprintf_append() when a zero character is in the middle of the * destination string. * * @code * char *str_a = talloc_strdup(NULL, "hello world"); * char *str_b = talloc_strdup(NULL, "hello world"); * str_a[5] = str_b[5] = '\0' * * char *app = talloc_asprintf_append(str_a, "%s", ", hello"); * char *buf = talloc_strdup_append_buffer(str_b, "%s", ", hello"); * * printf("%s\n", app); // hello, hello (app = "hello, hello") * printf("%s\n", buf); // hello (buf = "hello\0world, hello") * @endcode * * If s == NULL then new context is created. * * @param[in] s The string to append to * * @param[in] fmt The format string. * * @param[in] ... The parameters used to fill fmt. * * @return The formatted string, NULL on error. * * @see talloc_asprintf() * @see talloc_asprintf_append() */ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); /* @} ******************************************************************/ /** * @defgroup talloc_debug The talloc debugging support functions * @ingroup talloc * * To aid memory debugging, talloc contains routines to inspect the currently * allocated memory hierarchy. * * @{ */ /** * @brief Walk a complete talloc hierarchy. * * This provides a more flexible reports than talloc_report(). It * will recursively call the callback for the entire tree of memory * referenced by the pointer. References in the tree are passed with * is_ref = 1 and the pointer that is referenced. * * You can pass NULL for the pointer, in which case a report is * printed for the top level memory context, but only if * talloc_enable_leak_report() or talloc_enable_leak_report_full() * has been called. * * The recursion is stopped when depth >= max_depth. * max_depth = -1 means only stop at leaf nodes. * * @param[in] ptr The talloc chunk. * * @param[in] depth Internal parameter to control recursion. Call with 0. * * @param[in] max_depth Maximum recursion level. * * @param[in] callback Function to be called on every chunk. * * @param[in] private_data Private pointer passed to callback. */ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *private_data), void *private_data); /** * @brief Print a talloc hierarchy. * * This provides a more flexible reports than talloc_report(). It * will let you specify the depth and max_depth. * * @param[in] ptr The talloc chunk. * * @param[in] depth Internal parameter to control recursion. Call with 0. * * @param[in] max_depth Maximum recursion level. * * @param[in] f The file handle to print to. */ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); /** * @brief Print a summary report of all memory used by ptr. * * This provides a more detailed report than talloc_report(). It will * recursively print the entire tree of memory referenced by the * pointer. References in the tree are shown by giving the name of the * pointer that is referenced. * * You can pass NULL for the pointer, in which case a report is printed * for the top level memory context, but only if * talloc_enable_leak_report() or talloc_enable_leak_report_full() has * been called. * * @param[in] ptr The talloc chunk. * * @param[in] f The file handle to print to. * * Example: * @code * unsigned int *a, *b; * a = talloc(NULL, unsigned int); * b = talloc(a, unsigned int); * fprintf(stderr, "Dumping memory tree for a:\n"); * talloc_report_full(a, stderr); * @endcode * * @see talloc_report() */ void talloc_report_full(const void *ptr, FILE *f); /** * @brief Print a summary report of all memory used by ptr. * * This function prints a summary report of all memory used by ptr. One line of * report is printed for each immediate child of ptr, showing the total memory * and number of blocks used by that child. * * You can pass NULL for the pointer, in which case a report is printed * for the top level memory context, but only if talloc_enable_leak_report() * or talloc_enable_leak_report_full() has been called. * * @param[in] ptr The talloc chunk. * * @param[in] f The file handle to print to. * * Example: * @code * unsigned int *a, *b; * a = talloc(NULL, unsigned int); * b = talloc(a, unsigned int); * fprintf(stderr, "Summary of memory tree for a:\n"); * talloc_report(a, stderr); * @endcode * * @see talloc_report_full() */ void talloc_report(const void *ptr, FILE *f); /** * @brief Enable tracking the use of NULL memory contexts. * * This enables tracking of the NULL memory context without enabling leak * reporting on exit. Useful for when you want to do your own leak * reporting call via talloc_report_null_full(); */ void talloc_enable_null_tracking(void); /** * @brief Enable tracking the use of NULL memory contexts. * * This enables tracking of the NULL memory context without enabling leak * reporting on exit. Useful for when you want to do your own leak * reporting call via talloc_report_null_full(); */ void talloc_enable_null_tracking_no_autofree(void); /** * @brief Disable tracking of the NULL memory context. * * This disables tracking of the NULL memory context. */ void talloc_disable_null_tracking(void); /** * @brief Enable leak report when a program exits. * * This enables calling of talloc_report(NULL, stderr) when the program * exits. In Samba4 this is enabled by using the --leak-report command * line option. * * For it to be useful, this function must be called before any other * talloc function as it establishes a "null context" that acts as the * top of the tree. If you don't call this function first then passing * NULL to talloc_report() or talloc_report_full() won't give you the * full tree printout. * * Here is a typical talloc report: * * @code * talloc report on 'null_context' (total 267 bytes in 15 blocks) * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks * iconv(UTF8,CP850) contains 42 bytes in 2 blocks * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks * iconv(CP850,UTF8) contains 42 bytes in 2 blocks * iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks * iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks * @endcode */ void talloc_enable_leak_report(void); /** * @brief Enable full leak report when a program exits. * * This enables calling of talloc_report_full(NULL, stderr) when the * program exits. In Samba4 this is enabled by using the * --leak-report-full command line option. * * For it to be useful, this function must be called before any other * talloc function as it establishes a "null context" that acts as the * top of the tree. If you don't call this function first then passing * NULL to talloc_report() or talloc_report_full() won't give you the * full tree printout. * * Here is a typical full report: * * @code * full talloc report on 'root' (total 18 bytes in 8 blocks) * p1 contains 18 bytes in 7 blocks (ref 0) * r1 contains 13 bytes in 2 blocks (ref 0) * reference to: p2 * p2 contains 1 bytes in 1 blocks (ref 1) * x3 contains 1 bytes in 1 blocks (ref 0) * x2 contains 1 bytes in 1 blocks (ref 0) * x1 contains 1 bytes in 1 blocks (ref 0) * @endcode */ void talloc_enable_leak_report_full(void); /** * @brief Set a custom "abort" function that is called on serious error. * * The default "abort" function is abort(). * * The "abort" function is called when: * *
    *
  • talloc_get_type_abort() fails
  • *
  • the provided pointer is not a valid talloc context
  • *
  • when the context meta data are invalid
  • *
  • when access after free is detected
  • *
* * Example: * * @code * void my_abort(const char *reason) * { * fprintf(stderr, "talloc abort: %s\n", reason); * abort(); * } * * talloc_set_abort_fn(my_abort); * @endcode * * @param[in] abort_fn The new "abort" function. * * @see talloc_set_log_fn() * @see talloc_get_type() */ void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); /** * @brief Set a logging function. * * @param[in] log_fn The logging function. * * @see talloc_set_log_stderr() * @see talloc_set_abort_fn() */ void talloc_set_log_fn(void (*log_fn)(const char *message)); /** * @brief Set stderr as the output for logs. * * @see talloc_set_log_fn() * @see talloc_set_abort_fn() */ void talloc_set_log_stderr(void); /** * @brief Set a max memory limit for the current context hierarchy * 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 * a stricter memory limit than a parent. * Memory limits are enforced only at memory allocation time. * Stealing a context into a 'limited' hierarchy properly * updates memory usage but does *not* cause failure if the * move causes the new parent to exceed its limits. However * any further allocation on that hierarchy will then fail. * * @warning talloc memlimit functionality is deprecated. Please * consider using cgroup memory limits instead. * * @param[in] ctx The talloc context to set the limit on * @param[in] max_size The (new) max_size */ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_; /* @} ******************************************************************/ #if TALLOC_DEPRECATED #define talloc_zero_p(ctx, type) talloc_zero(ctx, type) #define talloc_p(ctx, type) talloc(ctx, type) #define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) #define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) #define talloc_destroy(ctx) talloc_free(ctx) #define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) #endif #ifndef TALLOC_MAX_DEPTH #define TALLOC_MAX_DEPTH 10000 #endif #ifdef __cplusplus } /* end of extern "C" */ #endif #endif ldb-2.0.8/lib/talloc/talloc.pc.in0000660000000000000000000000043712406075657016471 0ustar rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: talloc Description: A hierarchical pool based memory system with destructors Version: @TALLOC_VERSION@ Libs: @LIB_RPATH@ -L${libdir} -ltalloc Cflags: -I${includedir} URL: http://talloc.samba.org/ ldb-2.0.8/lib/talloc/talloc_guide.txt0000660000000000000000000007272013573675413017464 0ustar rootroot00000000000000Using talloc in Samba4 ====================== .. contents:: Andrew Tridgell August 2009 The most current version of this document is available at http://samba.org/ftp/unpacked/talloc/talloc_guide.txt If you are used to the "old" talloc from Samba3 before 3.0.20 then please read this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the Samba4 talloc has been ported back to Samba3, so this guide applies to both. The new talloc is a hierarchical, reference counted memory pool system with destructors. Quite a mouthful really, but not too bad once you get used to it. Perhaps the biggest change from Samba3 is that there is no distinction between a "talloc context" and a "talloc pointer". Any pointer returned from talloc() is itself a valid talloc context. This means you can do this:: struct foo *X = talloc(mem_ctx, struct foo); X->name = talloc_strdup(X, "foo"); and the pointer X->name would be a "child" of the talloc context "X" which is itself a child of "mem_ctx". So if you do talloc_free(mem_ctx) then it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if you do talloc_free(X->name) then just the name element of X is destroyed. If you think about this, then what this effectively gives you is an n-ary tree, where you can free any part of the tree with talloc_free(). If you find this confusing, then I suggest you run the testsuite to watch talloc in action. You may also like to add your own tests to testsuite.c to clarify how some particular situation is handled. Performance ----------- All the additional features of talloc() over malloc() do come at a price. We have a simple performance test in Samba4 that measures talloc() versus malloc() performance, and it seems that talloc() is about 4% slower than malloc() on my x86 Debian Linux box. For Samba, the great reduction in code complexity that we get by using talloc makes this worthwhile, especially as the total overhead of talloc/malloc in Samba is already quite small. talloc API ---------- The following is a complete guide to the talloc API. Read it all at least twice. Multi-threading --------------- talloc itself does not deal with threads. It is thread-safe (assuming the underlying "malloc" is), as long as each thread uses different memory contexts. If two threads use the same context then they need to synchronize in order to be safe. In particular: - when using talloc_enable_leak_report(), giving directly NULL as a parent context implicitly refers to a hidden "null context" global variable, so this should not be used in a multi-threaded environment without proper synchronization. In threaded code turn off null tracking using talloc_disable_null_tracking(). ; - the context returned by talloc_autofree_context() is also global so shouldn't be used by several threads simultaneously without synchronization. talloc and shared objects ------------------------- talloc can be used in shared objects. Special care needs to be taken to never use talloc_autofree_context() in code that might be loaded with dlopen() and unloaded with dlclose(), as talloc_autofree_context() internally uses atexit(3). Some platforms like modern Linux handles this fine, but for example FreeBSD does not deal well with dlopen() and atexit() used simultaneously: dlclose() does not clean up the list of atexit-handlers, so when the program exits the code that was registered from within talloc_autofree_context() is gone, the program crashes at exit. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (type *)talloc(const void *context, type); The talloc() macro is the core of the talloc library. It takes a memory context and a type, and returns a pointer to a new area of memory of the given type. The returned pointer is itself a talloc context, so you can use it as the context argument to more calls to talloc if you wish. The returned pointer is a "child" of the supplied context. This means that if you talloc_free() the context then the new child disappears as well. Alternatively you can free just the child. The context argument to talloc() can be NULL, in which case a new top level context is created. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_size(const void *context, size_t size); The function talloc_size() should be used when you don't have a convenient type to pass to talloc(). Unlike talloc(), it is not type safe (as it returns a void *), so you are on your own for type checking. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); The talloc_ptrtype() macro should be used when you have a pointer and want to allocate memory to point at with this pointer. When compiling with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() and talloc_get_name() will return the current location in the source file. and not the type. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- int talloc_free(void *ptr); The talloc_free() function frees a piece of talloc memory, and all its children. You can call talloc_free() on any pointer returned by talloc(). The return value of talloc_free() indicates success or failure, with 0 returned for success and -1 for failure. A possible failure condition is if the pointer had a destructor attached to it and the destructor returned -1. See talloc_set_destructor() for details on destructors. Likewise, if "ptr" is NULL, then the function will make no modifications and returns -1. From version 2.0 and onwards, as a special case, talloc_free() is refused on pointers that have more than one parent associated, as talloc would have no way of knowing which parent should be removed. This is different from older versions in the sense that always the reference to the most recently established parent has been destroyed. Hence to free a pointer that has more than one parent please use talloc_unlink(). To help you find problems in your code caused by this behaviour, if you do try and free a pointer with more than one parent then the talloc logging function will be called to give output like this: ERROR: talloc_free with references at some_dir/source/foo.c:123 reference at some_dir/source/other.c:325 reference at some_dir/source/third.c:121 Please see the documentation for talloc_set_log_fn() and talloc_set_log_stderr() for more information on talloc logging functions. talloc_free() operates recursively on its children. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_free_children(void *ptr); The talloc_free_children() walks along the list of all children of a talloc context and talloc_free()s only the children, not the context itself. A NULL argument is handled as no-op. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_reference(const void *context, const void *ptr); The talloc_reference() function makes "context" an additional parent of "ptr". The return value of talloc_reference() is always the original pointer "ptr", unless talloc ran out of memory in creating the reference in which case it will return NULL (each additional reference consumes around 48 bytes of memory on intel x86 platforms). If "ptr" is NULL, then the function is a no-op, and simply returns NULL. After creating a reference you can free it in one of the following ways: - you can talloc_free() any parent of the original pointer. That will reduce the number of parents of this pointer by 1, and will cause this pointer to be freed if it runs out of parents. - you can talloc_free() the pointer itself if it has at maximum one parent. This behaviour has been changed since the release of version 2.0. Further information in the description of "talloc_free". For more control on which parent to remove, see talloc_unlink() =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- int talloc_unlink(const void *context, void *ptr); The talloc_unlink() function removes a specific parent from ptr. The context passed must either be a context used in talloc_reference() with this pointer, or must be a direct parent of ptr. Note that if the parent has already been removed using talloc_free() then this function will fail and will return -1. Likewise, if "ptr" is NULL, then the function will make no modifications and return -1. You can just use talloc_free() instead of talloc_unlink() if there is at maximum one parent. This behaviour has been changed since the release of version 2.0. Further information in the description of "talloc_free". =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); The function talloc_set_destructor() sets the "destructor" for the pointer "ptr". A destructor is a function that is called when the memory used by a pointer is about to be released. The destructor receives the pointer as an argument, and should return 0 for success and -1 for failure. The destructor can do anything it wants to, including freeing other pieces of memory. A common use for destructors is to clean up operating system resources (such as open file descriptors) contained in the structure the destructor is placed on. You can only place one destructor on a pointer. If you need more than one destructor then you can create a zero-length child of the pointer and place an additional destructor on that. To remove a destructor call talloc_set_destructor() with NULL for the destructor. If your destructor attempts to talloc_free() the pointer that it is the destructor for then talloc_free() will return -1 and the free will be ignored. This would be a pointless operation anyway, as the destructor is only called when the memory is just about to go away. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- int talloc_increase_ref_count(const void *ptr); The talloc_increase_ref_count(ptr) function is exactly equivalent to: talloc_reference(NULL, ptr); You can use either syntax, depending on which you think is clearer in your code. It returns 0 on success and -1 on failure. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- size_t talloc_reference_count(const void *ptr); Return the number of references to the pointer. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_set_name(const void *ptr, const char *fmt, ...); Each talloc pointer has a "name". The name is used principally for debugging purposes, although it is also possible to set and get the name on a pointer in as a way of "marking" pointers in your code. The main use for names on pointer is for "talloc reports". See talloc_report() and talloc_report_full() for details. Also see talloc_enable_leak_report() and talloc_enable_leak_report_full(). The talloc_set_name() function allocates memory as a child of the pointer. It is logically equivalent to: talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); Note that multiple calls to talloc_set_name() will allocate more memory without releasing the name. All of the memory is released when the ptr is freed using talloc_free(). =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_set_name_const(const void *ptr, const char *name); The function talloc_set_name_const() is just like talloc_set_name(), but it takes a string constant, and is much faster. It is extensively used by the "auto naming" macros, such as talloc_p(). This function does not allocate any memory. It just copies the supplied pointer into the internal representation of the talloc ptr. This means you must not pass a name pointer to memory that will disappear before the ptr is freed with talloc_free(). =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_named(const void *context, size_t size, const char *fmt, ...); The talloc_named() function creates a named talloc pointer. It is equivalent to: ptr = talloc_size(context, size); talloc_set_name(ptr, fmt, ....); =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_named_const(const void *context, size_t size, const char *name); This is equivalent to:: ptr = talloc_size(context, size); talloc_set_name_const(ptr, name); =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- const char *talloc_get_name(const void *ptr); This returns the current name for the given talloc pointer. See talloc_set_name() for details. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_init(const char *fmt, ...); This function creates a zero length named talloc context as a top level context. It is equivalent to:: talloc_named(NULL, 0, fmt, ...); =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_new(void *ctx); This is a utility macro that creates a new memory context hanging off an exiting context, automatically naming it "talloc_new: __location__" where __location__ is the source line it is called from. It is particularly useful for creating a new temporary working context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (type *)talloc_realloc(const void *context, void *ptr, type, count); The talloc_realloc() macro changes the size of a talloc pointer. The "count" argument is the number of elements of type "type" that you want the resulting pointer to hold. talloc_realloc() has the following equivalences:: talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); The "context" argument is only used if "ptr" is NULL, otherwise it is ignored. talloc_realloc() returns the new pointer, or NULL on failure. The call will fail either due to a lack of memory, or because the pointer has more than one parent (see talloc_reference()). =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_realloc_size(const void *context, void *ptr, size_t size); the talloc_realloc_size() function is useful when the type is not known so the typesafe talloc_realloc() cannot be used. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_steal(const void *new_ctx, const void *ptr); The talloc_steal() function changes the parent context of a talloc pointer. It is typically used when the context that the pointer is currently a child of is going to be freed and you wish to keep the memory for a longer time. The talloc_steal() function returns the pointer that you pass it. It does not have any failure modes. NOTE: It is possible to produce loops in the parent/child relationship if you are not careful with talloc_steal(). No guarantees are provided as to your sanity or the safety of your data if you do this. talloc_steal (new_ctx, NULL) will return NULL with no sideeffects. Note that if you try and call talloc_steal() on a pointer that has more than one parent then the result is ambiguous. Talloc will choose to remove the parent that is currently indicated by talloc_parent() and replace it with the chosen parent. You will also get a message like this via the talloc logging functions: WARNING: talloc_steal with references at some_dir/source/foo.c:123 reference at some_dir/source/other.c:325 reference at some_dir/source/third.c:121 To unambiguously change the parent of a pointer please see the function talloc_reparent(). See the talloc_set_log_fn() documentation for more information on talloc logging. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr); The talloc_reparent() function changes the parent context of a talloc pointer. It is typically used when the context that the pointer is currently a child of is going to be freed and you wish to keep the memory for a longer time. The talloc_reparent() function returns the pointer that you pass it. It does not have any failure modes. The difference between talloc_reparent() and talloc_steal() is that talloc_reparent() can specify which parent you wish to change. This is useful when a pointer has multiple parents via references. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_parent(const void *ptr); The talloc_parent() function returns the current talloc parent. This is usually the pointer under which this memory was originally created, but it may have changed due to a talloc_steal() or talloc_reparent() =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- size_t talloc_total_size(const void *ptr); The talloc_total_size() function returns the total size in bytes used by this pointer and all child pointers. Mostly useful for debugging. Passing NULL is allowed, but it will only give a meaningful result if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- size_t talloc_total_blocks(const void *ptr); The talloc_total_blocks() function returns the total memory block count used by this pointer and all child pointers. Mostly useful for debugging. Passing NULL is allowed, but it will only give a meaningful result if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv), void *priv); This provides a more flexible reports than talloc_report(). It will recursively call the callback for the entire tree of memory referenced by the pointer. References in the tree are passed with is_ref = 1 and the pointer that is referenced. You can pass NULL for the pointer, in which case a report is printed for the top level memory context, but only if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. The recursion is stopped when depth >= max_depth. max_depth = -1 means only stop at leaf nodes. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); This provides a more flexible reports than talloc_report(). It will let you specify the depth and max_depth. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_report(const void *ptr, FILE *f); The talloc_report() function prints a summary report of all memory used by ptr. One line of report is printed for each immediate child of ptr, showing the total memory and number of blocks used by that child. You can pass NULL for the pointer, in which case a report is printed for the top level memory context, but only if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_report_full(const void *ptr, FILE *f); This provides a more detailed report than talloc_report(). It will recursively print the entire tree of memory referenced by the pointer. References in the tree are shown by giving the name of the pointer that is referenced. You can pass NULL for the pointer, in which case a report is printed for the top level memory context, but only if talloc_enable_leak_report() or talloc_enable_leak_report_full() has been called. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_enable_leak_report(void); This enables calling of talloc_report(NULL, stderr) when the program exits. In Samba4 this is enabled by using the --leak-report command line option. For it to be useful, this function must be called before any other talloc function as it establishes a "null context" that acts as the top of the tree. If you don't call this function first then passing NULL to talloc_report() or talloc_report_full() won't give you the full tree printout. Here is a typical talloc report: talloc report on 'null_context' (total 267 bytes in 15 blocks) libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks iconv(UTF8,CP850) contains 42 bytes in 2 blocks libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks iconv(CP850,UTF8) contains 42 bytes in 2 blocks iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_enable_leak_report_full(void); This enables calling of talloc_report_full(NULL, stderr) when the program exits. In Samba4 this is enabled by using the --leak-report-full command line option. For it to be useful, this function must be called before any other talloc function as it establishes a "null context" that acts as the top of the tree. If you don't call this function first then passing NULL to talloc_report() or talloc_report_full() won't give you the full tree printout. Here is a typical full report: full talloc report on 'root' (total 18 bytes in 8 blocks) p1 contains 18 bytes in 7 blocks (ref 0) r1 contains 13 bytes in 2 blocks (ref 0) reference to: p2 p2 contains 1 bytes in 1 blocks (ref 1) x3 contains 1 bytes in 1 blocks (ref 0) x2 contains 1 bytes in 1 blocks (ref 0) x1 contains 1 bytes in 1 blocks (ref 0) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_enable_null_tracking(void); This enables tracking of the NULL memory context without enabling leak reporting on exit. Useful for when you want to do your own leak reporting call via talloc_report_null_full(); =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_disable_null_tracking(void); This disables tracking of the NULL memory context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (type *)talloc_zero(const void *ctx, type); The talloc_zero() macro is equivalent to:: ptr = talloc(ctx, type); if (ptr) memset(ptr, 0, sizeof(type)); =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_zero_size(const void *ctx, size_t size) The talloc_zero_size() function is useful when you don't have a known type =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_memdup(const void *ctx, const void *p, size_t size); The talloc_memdup() function is equivalent to:: ptr = talloc_size(ctx, size); if (ptr) memcpy(ptr, p, size); =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_strdup(const void *ctx, const char *p); The talloc_strdup() function is equivalent to:: ptr = talloc_size(ctx, strlen(p)+1); if (ptr) memcpy(ptr, p, strlen(p)+1); This functions sets the name of the new pointer to the passed string. This is equivalent to:: talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_strndup(const void *t, const char *p, size_t n); The talloc_strndup() function is the talloc equivalent of the C library function strndup() This functions sets the name of the new pointer to the passed string. This is equivalent to: talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_append_string(const void *t, char *orig, const char *append); The talloc_append_string() function appends the given formatted string to the given string. This function sets the name of the new pointer to the new string. This is equivalent to:: talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); The talloc_vasprintf() function is the talloc equivalent of the C library function vasprintf() This functions sets the name of the new pointer to the new string. This is equivalent to:: talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_asprintf(const void *t, const char *fmt, ...); The talloc_asprintf() function is the talloc equivalent of the C library function asprintf() This functions sets the name of the new pointer to the new string. This is equivalent to:: talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_asprintf_append(char *s, const char *fmt, ...); The talloc_asprintf_append() function appends the given formatted string to the given string. Use this variant when the string in the current talloc buffer may have been truncated in length. This functions sets the name of the new pointer to the new string. This is equivalent to:: talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); The talloc_asprintf_append() function appends the given formatted string to the end of the currently allocated talloc buffer. Use this variant when the string in the current talloc buffer has not been changed. This functions sets the name of the new pointer to the new string. This is equivalent to:: talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ((type *)talloc_array(const void *ctx, type, unsigned int count); The talloc_array() macro is equivalent to:: (type *)talloc_size(ctx, sizeof(type) * count); except that it provides integer overflow protection for the multiply, returning NULL if the multiply overflows. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_array_size(const void *ctx, size_t size, unsigned int count); The talloc_array_size() function is useful when the type is not known. It operates in the same way as talloc_array(), but takes a size instead of a type. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); The talloc_ptrtype() macro should be used when you have a pointer to an array and want to allocate memory of an array to point at with this pointer. When compiling with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() and talloc_get_name() will return the current location in the source file. and not the type. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size); This is a non-macro version of talloc_realloc(), which is useful as libraries sometimes want a ralloc function pointer. A realloc() implementation encapsulates the functionality of malloc(), free() and realloc() in one call, which is why it is useful to be able to pass around a single function pointer. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_autofree_context(void); This is a handy utility function that returns a talloc context which will be automatically freed on program exit. This can be used to reduce the noise in memory leak reports. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_check_name(const void *ptr, const char *name); This function checks if a pointer has the specified name. If it does then the pointer is returned. It it doesn't then NULL is returned. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (type *)talloc_get_type(const void *ptr, type); This macro allows you to do type checking on talloc pointers. It is particularly useful for void* private pointers. It is equivalent to this:: (type *)talloc_check_name(ptr, #type) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- talloc_set_type(const void *ptr, type); This macro allows you to force the name of a pointer to be of a particular type. This can be used in conjunction with talloc_get_type() to do type checking on void* pointers. It is equivalent to this:: talloc_set_name_const(ptr, #type) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- talloc_get_size(const void *ctx); This function lets you know the amount of memory allocated so far by this context. It does NOT account for subcontext memory. This can be used to calculate the size of an array. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void *talloc_find_parent_byname(const void *ctx, const char *name); Find a parent memory context of the current context that has the given name. This can be very useful in complex programs where it may be difficult to pass all information down to the level you need, but you know the structure you want is a parent of another context. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (type *)talloc_find_parent_bytype(ctx, type); Like talloc_find_parent_byname() but takes a type, making it typesafe. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_set_log_fn(void (*log_fn)(const char *message)); This function sets a logging function that talloc will use for warnings and errors. By default talloc will not print any warnings or errors. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void talloc_set_log_stderr(void) This sets the talloc log function to write log messages to stderr. ldb-2.0.8/lib/talloc/talloc_testsuite.h0000660000000000000000000000025612406075657020021 0ustar rootroot00000000000000#ifndef __LIB_TALLOC_TALLOC_TESTSUITE_H__ #define __LIB_TALLOC_TALLOC_TESTSUITE_H__ struct torture_context; bool torture_local_talloc(struct torture_context *tctx); #endif ldb-2.0.8/lib/talloc/test_magic_differs.sh0000770000000000000000000000055112667552643020442 0ustar rootroot00000000000000#!/bin/sh # This test ensures that two different talloc processes do not use the same # magic value to lessen the opportunity for transferrable attacks. echo "test: magic differs" helper=$1 m1=$($helper) m2=$($helper) if [ $m1 -eq $m2 ]; then echo "failure: magic remained the same between executions ($m1 vs $m2)" exit 1 fi echo "success: magic differs" ldb-2.0.8/lib/talloc/test_magic_differs_helper.c0000660000000000000000000000052112617125140021563 0ustar rootroot00000000000000#include #include "talloc.h" /* * This program is called by a testing shell script in order to ensure that * if the library is loaded into different processes it uses different magic * values in order to thwart security attacks. */ int main(int argc, char *argv[]) { printf("%i\n", talloc_test_get_magic()); return 0; } ldb-2.0.8/lib/talloc/test_pytalloc.c0000660000000000000000000001505613573675413017321 0ustar rootroot00000000000000/* Samba Unix SMB/CIFS implementation. C utilities for the pytalloc test suite. Provides the "_test_pytalloc" Python module. NOTE: Please read talloc_guide.txt for full documentation Copyright (C) Petr Viktorin 2015 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include #include #include static PyObject *testpytalloc_new(PyTypeObject *mod, PyObject *Py_UNUSED(ignored)) { char *obj = talloc_strdup(NULL, "This is a test string");; return pytalloc_steal(pytalloc_GetObjectType(), obj); } static PyObject *testpytalloc_get_object_type(PyObject *mod, PyObject *Py_UNUSED(ignored)) { PyObject *type = (PyObject *)pytalloc_GetObjectType(); Py_INCREF(type); return type; } static PyObject *testpytalloc_base_new(PyTypeObject *mod, PyObject *Py_UNUSED(ignored)) { char *obj = talloc_strdup(NULL, "This is a test string for a BaseObject");; return pytalloc_steal(pytalloc_GetBaseObjectType(), obj); } static PyObject *testpytalloc_base_get_object_type(PyObject *mod, PyObject *Py_UNUSED(ignored)) { PyObject *type = (PyObject *)pytalloc_GetBaseObjectType(); Py_INCREF(type); return type; } static PyObject *testpytalloc_reference(PyObject *mod, PyObject *args) { PyObject *source = NULL; void *ptr; if (!PyArg_ParseTuple(args, "O!", pytalloc_GetObjectType(), &source)) return NULL; ptr = pytalloc_get_ptr(source); return pytalloc_reference_ex(pytalloc_GetObjectType(), ptr, ptr); } static PyObject *testpytalloc_base_reference(PyObject *mod, PyObject *args) { PyObject *source = NULL; void *mem_ctx; if (!PyArg_ParseTuple(args, "O!", pytalloc_GetBaseObjectType(), &source)) { return NULL; } mem_ctx = pytalloc_get_mem_ctx(source); return pytalloc_reference_ex(pytalloc_GetBaseObjectType(), mem_ctx, mem_ctx); } static PyMethodDef test_talloc_methods[] = { { "new", (PyCFunction)testpytalloc_new, METH_NOARGS, "create a talloc Object with a testing string"}, { "get_object_type", (PyCFunction)testpytalloc_get_object_type, METH_NOARGS, "call pytalloc_GetObjectType"}, { "base_new", (PyCFunction)testpytalloc_base_new, METH_NOARGS, "create a talloc BaseObject with a testing string"}, { "base_get_object_type", (PyCFunction)testpytalloc_base_get_object_type, METH_NOARGS, "call pytalloc_GetBaseObjectType"}, { "reference", (PyCFunction)testpytalloc_reference, METH_VARARGS, "call pytalloc_reference_ex"}, { "base_reference", (PyCFunction)testpytalloc_base_reference, METH_VARARGS, "call pytalloc_reference_ex"}, { NULL } }; static PyTypeObject DObject_Type; static int dobject_destructor(void *ptr) { PyObject *destructor_func = *talloc_get_type(ptr, PyObject*); PyObject *ret; ret = PyObject_CallObject(destructor_func, NULL); Py_DECREF(destructor_func); if (ret == NULL) { PyErr_Print(); } else { Py_DECREF(ret); } return 0; } static PyObject *dobject_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *destructor_func = NULL; PyObject **obj; if (!PyArg_ParseTuple(args, "O", &destructor_func)) return NULL; Py_INCREF(destructor_func); obj = talloc(NULL, PyObject*); *obj = destructor_func; talloc_set_destructor((void*)obj, dobject_destructor); return pytalloc_steal(&DObject_Type, obj); } static PyTypeObject DObject_Type = { .tp_name = "_test_pytalloc.DObject", .tp_basicsize = sizeof(pytalloc_Object), .tp_methods = NULL, .tp_new = dobject_new, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = "test talloc object that calls a function when underlying data is freed\n", }; static PyTypeObject DBaseObject_Type; static int d_base_object_destructor(void *ptr) { PyObject *destructor_func = *talloc_get_type(ptr, PyObject*); PyObject *ret; ret = PyObject_CallObject(destructor_func, NULL); Py_DECREF(destructor_func); if (ret == NULL) { PyErr_Print(); } else { Py_DECREF(ret); } return 0; } static PyObject *d_base_object_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *destructor_func = NULL; PyObject **obj; if (!PyArg_ParseTuple(args, "O", &destructor_func)) return NULL; Py_INCREF(destructor_func); obj = talloc(NULL, PyObject*); *obj = destructor_func; talloc_set_destructor((void*)obj, d_base_object_destructor); return pytalloc_steal(&DBaseObject_Type, obj); } static PyTypeObject DBaseObject_Type = { .tp_name = "_test_pytalloc.DBaseObject", .tp_methods = NULL, .tp_new = d_base_object_new, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = "test talloc object that calls a function when underlying data is freed\n", }; #define MODULE_DOC PyDoc_STR("Test utility module for pytalloc") #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, .m_name = "_test_pytalloc", .m_doc = PyDoc_STR("Test utility module for pytalloc"), .m_size = -1, .m_methods = test_talloc_methods, }; #endif static PyObject *module_init(void); static PyObject *module_init(void) { PyObject *m; DObject_Type.tp_base = pytalloc_GetObjectType(); if (PyType_Ready(&DObject_Type) < 0) { return NULL; } DBaseObject_Type.tp_basicsize = pytalloc_BaseObject_size(); DBaseObject_Type.tp_base = pytalloc_GetBaseObjectType(); if (PyType_Ready(&DBaseObject_Type) < 0) { return NULL; } #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); #else m = Py_InitModule3("_test_pytalloc", test_talloc_methods, MODULE_DOC); #endif if (m == NULL) { return NULL; } Py_INCREF(&DObject_Type); Py_INCREF(DObject_Type.tp_base); PyModule_AddObject(m, "DObject", (PyObject *)&DObject_Type); Py_INCREF(&DBaseObject_Type); Py_INCREF(DBaseObject_Type.tp_base); PyModule_AddObject(m, "DBaseObject", (PyObject *)&DBaseObject_Type); return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit__test_pytalloc(void); PyMODINIT_FUNC PyInit__test_pytalloc(void) { return module_init(); } #else void init_test_pytalloc(void); void init_test_pytalloc(void) { module_init(); } #endif ldb-2.0.8/lib/talloc/test_pytalloc.py0000660000000000000000000001377213573675413017532 0ustar rootroot00000000000000#!/usr/bin/env python3 # Simple tests for the talloc python bindings. # Copyright (C) 2015 Petr Viktorin import unittest import subprocess import sys import gc import talloc import _test_pytalloc def dummy_func(): pass class TallocTests(unittest.TestCase): def test_report_full(self): # report_full is hardcoded to print to stdout, so use a subprocess process = subprocess.Popen([ sys.executable, '-c', """if True: import talloc, _test_pytalloc obj = _test_pytalloc.new() talloc.report_full(obj) """ ], stdout=subprocess.PIPE) output, stderr = process.communicate() output = str(output) self.assertTrue("full talloc report on 'talloc.Object" in output) self.assertTrue("This is a test string" in output) def test_totalblocks(self): obj = _test_pytalloc.new() # Two blocks: the string, and the name self.assertEqual(talloc.total_blocks(obj), 2) def test_repr(self): obj = _test_pytalloc.new() prefix = '= obj1) self.assertFalse(obj1 > obj1) def test_compare_different(self): # object comparison is consistent obj1, obj2 = sorted([ _test_pytalloc.new(), _test_pytalloc.new()]) self.assertFalse(obj1 == obj2) self.assertTrue(obj1 != obj2) self.assertTrue(obj1 <= obj2) self.assertTrue(obj1 < obj2) self.assertFalse(obj1 >= obj2) self.assertFalse(obj1 > obj2) def test_compare_different_types(self): # object comparison falls back to comparing types if sys.version_info >= (3, 0): # In Python 3, types are unorderable -- nothing to test return if talloc.Object < _test_pytalloc.DObject: obj1 = _test_pytalloc.new() obj2 = _test_pytalloc.DObject(dummy_func) else: obj2 = _test_pytalloc.new() obj1 = _test_pytalloc.DObject(dummy_func) self.assertFalse(obj1 == obj2) self.assertTrue(obj1 != obj2) self.assertTrue(obj1 <= obj2) self.assertTrue(obj1 < obj2) self.assertFalse(obj1 >= obj2) self.assertFalse(obj1 > obj2) class TallocBaseComparisonTests(unittest.TestCase): def test_compare_same(self): obj1 = _test_pytalloc.base_new() self.assertTrue(obj1 == obj1) self.assertFalse(obj1 != obj1) self.assertTrue(obj1 <= obj1) self.assertFalse(obj1 < obj1) self.assertTrue(obj1 >= obj1) self.assertFalse(obj1 > obj1) def test_compare_different(self): # object comparison is consistent obj1, obj2 = sorted([ _test_pytalloc.base_new(), _test_pytalloc.base_new()]) self.assertFalse(obj1 == obj2) self.assertTrue(obj1 != obj2) self.assertTrue(obj1 <= obj2) self.assertTrue(obj1 < obj2) self.assertFalse(obj1 >= obj2) self.assertFalse(obj1 > obj2) def test_compare_different_types(self): # object comparison falls back to comparing types if sys.version_info >= (3, 0): # In Python 3, types are unorderable -- nothing to test return if talloc.BaseObject < _test_pytalloc.DBaseObject: obj1 = _test_pytalloc.base_new() obj2 = _test_pytalloc.DBaseObject(dummy_func) else: obj2 = _test_pytalloc.base_new() obj1 = _test_pytalloc.DBaseObject(dummy_func) self.assertFalse(obj1 == obj2) self.assertTrue(obj1 != obj2) self.assertTrue(obj1 <= obj2) self.assertTrue(obj1 < obj2) self.assertFalse(obj1 >= obj2) self.assertFalse(obj1 > obj2) class TallocUtilTests(unittest.TestCase): def test_get_type(self): self.assertTrue(talloc.Object is _test_pytalloc.get_object_type()) def test_reference(self): # Check correct lifetime of the talloc'd data with multiple references lst = [] obj = _test_pytalloc.DObject(lambda: lst.append('dead')) ref = _test_pytalloc.reference(obj) del obj gc.collect() self.assertEqual(lst, []) del ref gc.collect() self.assertEqual(lst, ['dead']) def test_get_base_type(self): self.assertTrue(talloc.BaseObject is _test_pytalloc.base_get_object_type()) def test_base_reference(self): # Check correct lifetime of the talloc'd data with multiple references lst = [] obj = _test_pytalloc.DBaseObject(lambda: lst.append('dead')) ref = _test_pytalloc.base_reference(obj) del obj gc.collect() self.assertEqual(lst, []) del ref gc.collect() self.assertEqual(lst, ['dead']) if __name__ == '__main__': unittest.TestProgram() ldb-2.0.8/lib/talloc/testsuite.c0000660000000000000000000014732713573675413016473 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. local testing of talloc routines. Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include "replace.h" #include "system/time.h" #include #ifdef HAVE_PTHREAD #include #endif #include #include #ifdef NDEBUG #undef NDEBUG #endif #include #include "talloc_testsuite.h" static struct timeval private_timeval_current(void) { struct timeval tv; gettimeofday(&tv, NULL); return tv; } static double private_timeval_elapsed(struct timeval *tv) { struct timeval tv2 = private_timeval_current(); return (tv2.tv_sec - tv->tv_sec) + (tv2.tv_usec - tv->tv_usec)*1.0e-6; } #define torture_assert(test, expr, str) if (!(expr)) { \ printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \ test, __location__, #expr, str); \ return false; \ } #define torture_assert_str_equal(test, arg1, arg2, desc) \ if (arg1 == NULL && arg2 == NULL) { /* OK, both NULL == equal */ \ } else if (arg1 == NULL || arg2 == NULL) { \ return false; \ } else if (strcmp(arg1, arg2)) { \ printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \ test, __location__, arg1, arg2, desc); \ return false; \ } #define CHECK_SIZE(test, ptr, tsize) do { \ if (talloc_total_size(ptr) != (tsize)) { \ printf("failed: %s [\n%s: wrong '%s' tree size: got %u expected %u\n]\n", \ test, __location__, #ptr, \ (unsigned)talloc_total_size(ptr), \ (unsigned)tsize); \ talloc_report_full(ptr, stdout); \ return false; \ } \ } while (0) #define CHECK_BLOCKS(test, ptr, tblocks) do { \ if (talloc_total_blocks(ptr) != (tblocks)) { \ printf("failed: %s [\n%s: wrong '%s' tree blocks: got %u expected %u\n]\n", \ test, __location__, #ptr, \ (unsigned)talloc_total_blocks(ptr), \ (unsigned)tblocks); \ talloc_report_full(ptr, stdout); \ return false; \ } \ } while (0) #define CHECK_PARENT(test, ptr, parent) do { \ if (talloc_parent(ptr) != (parent)) { \ printf("failed: %s [\n%s: '%s' has wrong parent: got %p expected %p\n]\n", \ test, __location__, #ptr, \ talloc_parent(ptr), \ (parent)); \ talloc_report_full(ptr, stdout); \ talloc_report_full(parent, stdout); \ talloc_report_full(NULL, stdout); \ return false; \ } \ } while (0) static unsigned int test_abort_count; #if 0 static void test_abort_fn(const char *reason) { printf("# test_abort_fn(%s)\n", reason); test_abort_count++; } static void test_abort_start(void) { test_abort_count = 0; talloc_set_abort_fn(test_abort_fn); } #endif static void test_abort_stop(void) { test_abort_count = 0; talloc_set_abort_fn(NULL); } static void test_log_stdout(const char *message) { fprintf(stdout, "%s", message); } /* test references */ static bool test_ref1(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref1\n# SINGLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); p2 = talloc_named_const(p1, 1, "p2"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 2, "x2"); talloc_named_const(p1, 3, "x3"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", p1, 5); CHECK_BLOCKS("ref1", p2, 1); CHECK_BLOCKS("ref1", ref, 1); CHECK_BLOCKS("ref1", r1, 2); fprintf(stderr, "Freeing p2\n"); talloc_unlink(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", p1, 5); CHECK_BLOCKS("ref1", p2, 1); CHECK_BLOCKS("ref1", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", r1, 1); fprintf(stderr, "Freeing r1\n"); talloc_free(r1); talloc_report_full(NULL, stderr); fprintf(stderr, "Testing NULL\n"); if (talloc_reference(root, NULL)) { return false; } CHECK_BLOCKS("ref1", root, 1); CHECK_SIZE("ref1", root, 0); talloc_free(root); printf("success: ref1\n"); return true; } /* test references */ static bool test_ref2(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref2\n# DOUBLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 5); CHECK_BLOCKS("ref2", p2, 1); CHECK_BLOCKS("ref2", r1, 2); fprintf(stderr, "Freeing ref\n"); talloc_unlink(r1, ref); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 5); CHECK_BLOCKS("ref2", p2, 1); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 4); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing r1\n"); talloc_free(r1); talloc_report_full(root, stderr); CHECK_SIZE("ref2", root, 0); talloc_free(root); printf("success: ref2\n"); return true; } /* test references */ static bool test_ref3(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref3\n# PARENT REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); p2 = talloc_named_const(root, 1, "p2"); r1 = talloc_named_const(p1, 1, "r1"); ref = talloc_reference(p2, r1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref3", p1, 2); CHECK_BLOCKS("ref3", p2, 2); CHECK_BLOCKS("ref3", r1, 1); CHECK_BLOCKS("ref3", ref, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref3", p2, 2); CHECK_BLOCKS("ref3", r1, 1); fprintf(stderr, "Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stderr); CHECK_SIZE("ref3", root, 0); talloc_free(root); printf("success: ref3\n"); return true; } /* test references */ static bool test_ref4(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref4\n# REFERRER REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref4", p1, 5); CHECK_BLOCKS("ref4", p2, 1); CHECK_BLOCKS("ref4", ref, 1); CHECK_BLOCKS("ref4", r1, 2); fprintf(stderr, "Freeing r1\n"); talloc_free(r1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref4", p1, 5); CHECK_BLOCKS("ref4", p2, 1); fprintf(stderr, "Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref4", p1, 4); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_SIZE("ref4", root, 0); talloc_free(root); printf("success: ref4\n"); return true; } /* test references */ static bool test_unlink1(void) { void *root, *p1, *p2, *ref, *r1; printf("test: unlink\n# UNLINK\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(p1, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("unlink", p1, 7); CHECK_BLOCKS("unlink", p2, 1); CHECK_BLOCKS("unlink", ref, 1); CHECK_BLOCKS("unlink", r1, 2); fprintf(stderr, "Unreferencing r1\n"); talloc_unlink(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("unlink", p1, 6); CHECK_BLOCKS("unlink", p2, 1); CHECK_BLOCKS("unlink", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_SIZE("unlink", root, 0); talloc_free(root); printf("success: unlink\n"); return true; } static int fail_destructor(void *ptr) { return -1; } /* miscellaneous tests to try to get a higher test coverage percentage */ static bool test_misc(void) { void *root, *p1; char *p2; double *d; const char *name; printf("test: misc\n# MISCELLANEOUS\n"); root = talloc_new(NULL); p1 = talloc_size(root, 0x7fffffff); torture_assert("misc", !p1, "failed: large talloc allowed\n"); p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); p2 = talloc_strdup(p1, "foo"); torture_assert("misc", talloc_unlink(root, p2) == -1, "failed: talloc_unlink() of non-reference context should return -1\n"); torture_assert("misc", talloc_unlink(p1, p2) == 0, "failed: talloc_unlink() of parent should succeed\n"); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); name = talloc_set_name(p1, "my name is %s", "foo"); torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", "failed: wrong name after talloc_set_name(my name is foo)"); torture_assert_str_equal("misc", talloc_get_name(p1), name, "failed: wrong name after talloc_set_name(my name is foo)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_set_name_const(p1, NULL); torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", "failed: wrong name after talloc_set_name(NULL)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); torture_assert("misc", talloc_free(NULL) == -1, "talloc_free(NULL) should give -1\n"); talloc_set_destructor(p1, fail_destructor); torture_assert("misc", talloc_free(p1) == -1, "Failed destructor should cause talloc_free to fail\n"); talloc_set_destructor(p1, NULL); talloc_report(root, stderr); p2 = (char *)talloc_zero_size(p1, 20); torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); talloc_free(p2); torture_assert("misc", talloc_strdup(root, NULL) == NULL, "failed: strdup on NULL should give NULL\n"); p2 = talloc_strndup(p1, "foo", 2); torture_assert("misc", strcmp("fo", p2) == 0, "strndup doesn't work\n"); p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); torture_assert("misc", strcmp("food", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); torture_assert("misc", strcmp("hello world", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); talloc_free(p2); d = talloc_array(p1, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); d = talloc_realloc(p1, d, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); talloc_free(p1); CHECK_BLOCKS("misc", root, 1); p1 = talloc_named(root, 100, "%d bytes", 100); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(root, p1); p1 = talloc_init("%d bytes", 200); p2 = talloc_asprintf(p1, "my test '%s'", "string"); torture_assert_str_equal("misc", p2, "my test 'string'", "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); CHECK_BLOCKS("misc", p1, 3); CHECK_SIZE("misc", p2, 17); CHECK_BLOCKS("misc", root, 1); talloc_unlink(NULL, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(p1, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(p1, p2); talloc_unlink(root, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(NULL, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p2); talloc_unlink(root, p1); /* Test that talloc_unlink is a no-op */ torture_assert("misc", talloc_unlink(root, NULL) == -1, "failed: talloc_unlink(root, NULL) == -1\n"); talloc_report(root, stderr); talloc_report(NULL, stderr); CHECK_SIZE("misc", root, 0); talloc_free(root); CHECK_SIZE("misc", NULL, 0); talloc_enable_null_tracking_no_autofree(); talloc_enable_leak_report(); talloc_enable_leak_report_full(); printf("success: misc\n"); return true; } /* test realloc */ static bool test_realloc(void) { void *root, *p1, *p2; printf("test: realloc\n# REALLOC\n"); root = talloc_new(NULL); p1 = talloc_size(root, 10); CHECK_SIZE("realloc", p1, 10); p1 = talloc_realloc_size(NULL, p1, 20); CHECK_SIZE("realloc", p1, 20); talloc_new(p1); p2 = talloc_realloc_size(p1, NULL, 30); talloc_new(p1); p2 = talloc_realloc_size(p1, p2, 40); CHECK_SIZE("realloc", p2, 40); CHECK_SIZE("realloc", root, 60); CHECK_BLOCKS("realloc", p1, 4); p1 = talloc_realloc_size(NULL, p1, 20); CHECK_SIZE("realloc", p1, 60); talloc_increase_ref_count(p2); torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL, "failed: talloc_realloc() on a referenced pointer should fail\n"); CHECK_BLOCKS("realloc", p1, 4); talloc_realloc_size(NULL, p2, 0); talloc_realloc_size(NULL, p2, 0); CHECK_BLOCKS("realloc", p1, 4); talloc_realloc_size(p1, p2, 0); CHECK_BLOCKS("realloc", p1, 3); torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL, "failed: oversize talloc should fail\n"); talloc_realloc_size(NULL, p1, 0); CHECK_BLOCKS("realloc", root, 4); talloc_realloc_size(root, p1, 0); CHECK_BLOCKS("realloc", root, 1); CHECK_SIZE("realloc", root, 0); talloc_free(root); printf("success: realloc\n"); return true; } /* test realloc with a child */ static bool test_realloc_child(void) { void *root; struct el2 { const char *name; } *el2, *el2_2, *el2_3, **el_list_save; struct el1 { int count; struct el2 **list, **list2, **list3; } *el1; printf("test: REALLOC WITH CHILD\n"); root = talloc_new(NULL); el1 = talloc(root, struct el1); el1->list = talloc(el1, struct el2 *); el1->list[0] = talloc(el1->list, struct el2); el1->list[0]->name = talloc_strdup(el1->list[0], "testing"); el1->list2 = talloc(el1, struct el2 *); el1->list2[0] = talloc(el1->list2, struct el2); el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2"); el1->list3 = talloc(el1, struct el2 *); el1->list3[0] = talloc(el1->list3, struct el2); el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2"); el2 = talloc(el1->list, struct el2); CHECK_PARENT("el2", el2, el1->list); el2_2 = talloc(el1->list2, struct el2); CHECK_PARENT("el2", el2_2, el1->list2); el2_3 = talloc(el1->list3, struct el2); CHECK_PARENT("el2", el2_3, el1->list3); el_list_save = el1->list; el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); if (el1->list == el_list_save) { printf("failure: talloc_realloc didn't move pointer"); return false; } CHECK_PARENT("el1_after_realloc", el1->list, el1); el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200); CHECK_PARENT("el1_after_realloc", el1->list2, el1); el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300); CHECK_PARENT("el1_after_realloc", el1->list3, el1); CHECK_PARENT("el2", el2, el1->list); CHECK_PARENT("el2", el2_2, el1->list2); CHECK_PARENT("el2", el2_3, el1->list3); /* Finally check realloc with multiple children */ el1 = talloc_realloc(root, el1, struct el1, 100); CHECK_PARENT("el1->list", el1->list, el1); CHECK_PARENT("el1->list2", el1->list2, el1); CHECK_PARENT("el1->list3", el1->list3, el1); talloc_free(root); printf("success: REALLOC WITH CHILD\n"); return true; } /* test type checking */ static bool test_type(void) { void *root; struct el1 { int count; }; struct el2 { int count; }; struct el1 *el1; printf("test: type\n# talloc type checking\n"); root = talloc_new(NULL); el1 = talloc(root, struct el1); el1->count = 1; torture_assert("type", talloc_get_type(el1, struct el1) == el1, "type check failed on el1\n"); torture_assert("type", talloc_get_type(el1, struct el2) == NULL, "type check failed on el1 with el2\n"); talloc_set_type(el1, struct el2); torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1, "type set failed on el1 with el2\n"); talloc_free(root); printf("success: type\n"); return true; } /* test steal */ static bool test_steal(void) { void *root, *p1, *p2; printf("test: steal\n# STEAL\n"); root = talloc_new(NULL); p1 = talloc_array(root, char, 10); CHECK_SIZE("steal", p1, 10); p2 = talloc_realloc(root, NULL, char, 20); CHECK_SIZE("steal", p1, 10); CHECK_SIZE("steal", root, 30); torture_assert("steal", talloc_steal(p1, NULL) == NULL, "failed: stealing NULL should give NULL\n"); torture_assert("steal", talloc_steal(p1, p1) == p1, "failed: stealing to ourselves is a nop\n"); CHECK_BLOCKS("steal", root, 3); CHECK_SIZE("steal", root, 30); talloc_steal(NULL, p1); talloc_steal(NULL, p2); CHECK_BLOCKS("steal", root, 1); CHECK_SIZE("steal", root, 0); talloc_free(p1); talloc_steal(root, p2); CHECK_BLOCKS("steal", root, 2); CHECK_SIZE("steal", root, 20); talloc_free(p2); CHECK_BLOCKS("steal", root, 1); CHECK_SIZE("steal", root, 0); talloc_free(root); p1 = talloc_size(NULL, 3); talloc_report_full(NULL, stderr); CHECK_SIZE("steal", NULL, 3); talloc_free(p1); printf("success: steal\n"); return true; } /* test move */ static bool test_move(void) { void *root; struct t_move { char *p; int *x; } *t1, *t2; printf("test: move\n# MOVE\n"); root = talloc_new(NULL); t1 = talloc(root, struct t_move); t2 = talloc(root, struct t_move); t1->p = talloc_strdup(t1, "foo"); t1->x = talloc(t1, int); *t1->x = 42; t2->p = talloc_move(t2, &t1->p); t2->x = talloc_move(t2, &t1->x); torture_assert("move", t1->p == NULL && t1->x == NULL && strcmp(t2->p, "foo") == 0 && *t2->x == 42, "talloc move failed"); talloc_free(root); printf("success: move\n"); return true; } /* test talloc_realloc_fn */ static bool test_realloc_fn(void) { void *root, *p1; printf("test: realloc_fn\n# talloc_realloc_fn\n"); root = talloc_new(NULL); p1 = talloc_realloc_fn(root, NULL, 10); CHECK_BLOCKS("realloc_fn", root, 2); CHECK_SIZE("realloc_fn", root, 10); p1 = talloc_realloc_fn(root, p1, 20); CHECK_BLOCKS("realloc_fn", root, 2); CHECK_SIZE("realloc_fn", root, 20); p1 = talloc_realloc_fn(root, p1, 0); CHECK_BLOCKS("realloc_fn", root, 1); CHECK_SIZE("realloc_fn", root, 0); talloc_free(root); printf("success: realloc_fn\n"); return true; } static bool test_unref_reparent(void) { void *root, *p1, *p2, *c1; printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "orig parent"); p2 = talloc_named_const(root, 1, "parent by reference"); c1 = talloc_named_const(p1, 1, "child"); talloc_reference(p2, c1); CHECK_PARENT("unref_reparent", c1, p1); talloc_free(p1); CHECK_PARENT("unref_reparent", c1, p2); talloc_unlink(p2, c1); CHECK_SIZE("unref_reparent", root, 1); talloc_free(p2); talloc_free(root); printf("success: unref_reparent\n"); return true; } /* measure the speed of talloc versus malloc */ static bool test_speed(void) { void *ctx = talloc_new(NULL); unsigned count; const int loop = 1000; int i; struct timeval tv; printf("test: speed\n# TALLOC VS MALLOC SPEED\n"); tv = private_timeval_current(); count = 0; do { void *p1, *p2, *p3; for (i=0;ireq2 = talloc_strdup(req1, "req2"); talloc_set_destructor(req1->req2, test_loop_destructor); req1->req3 = talloc_strdup(req1, "req3"); (void)talloc_reference(req1->req3, req1); talloc_report_full(top, stderr); talloc_free(parent); talloc_report_full(top, stderr); talloc_report_full(NULL, stderr); talloc_free(top); torture_assert("loop", loop_destructor_count == 1, "FAILED TO FIRE LOOP DESTRUCTOR\n"); loop_destructor_count = 0; printf("success: loop\n"); return true; } static int realloc_parent_destructor_count; static int test_realloc_parent_destructor(char *ptr) { realloc_parent_destructor_count++; return 0; } static bool test_realloc_on_destructor_parent(void) { void *top = talloc_new(NULL); char *parent; char *a, *b, *C, *D; realloc_parent_destructor_count = 0; printf("test: free_for_exit\n# TALLOC FREE FOR EXIT\n"); parent = talloc_strdup(top, "parent"); a = talloc_strdup(parent, "a"); b = talloc_strdup(a, "b"); C = talloc_strdup(a, "C"); D = talloc_strdup(b, "D"); talloc_set_destructor(D, test_realloc_parent_destructor); /* Capitalised ones have destructors. * * parent --> a -> b -> D * -> c */ a = talloc_realloc(parent, a, char, 2048); torture_assert("check talloc_realloc", a != NULL, "talloc_realloc failed"); talloc_set_destructor(C, test_realloc_parent_destructor); /* * parent --> a[2048] -> b -> D * -> C * */ talloc_free(parent); torture_assert("check destructor realloc_parent_destructor", realloc_parent_destructor_count == 2, "FAILED TO FIRE free_for_exit_destructor\n"); printf("success: free_for_exit\n"); return true; } static int fail_destructor_str(char *ptr) { return -1; } static bool test_free_parent_deny_child(void) { void *top = talloc_new(NULL); char *level1; char *level2; char *level3; printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n"); level1 = talloc_strdup(top, "level1"); level2 = talloc_strdup(level1, "level2"); level3 = talloc_strdup(level2, "level3"); talloc_set_destructor(level3, fail_destructor_str); talloc_free(level1); talloc_set_destructor(level3, NULL); CHECK_PARENT("free_parent_deny_child", level3, top); talloc_free(top); printf("success: free_parent_deny_child\n"); return true; } struct new_parent { void *new_parent; char val[20]; }; static int reparenting_destructor(struct new_parent *np) { talloc_set_destructor(np, NULL); (void)talloc_move(np->new_parent, &np); return -1; } static bool test_free_parent_reparent_child(void) { void *top = talloc_new(NULL); char *level1; char *alternate_level1; char *level2; struct new_parent *level3; printf("test: free_parent_reparent_child\n# " "TALLOC FREE PARENT REPARENT CHILD\n"); level1 = talloc_strdup(top, "level1"); alternate_level1 = talloc_strdup(top, "alternate_level1"); level2 = talloc_strdup(level1, "level2"); level3 = talloc(level2, struct new_parent); level3->new_parent = alternate_level1; memset(level3->val, 'x', sizeof(level3->val)); talloc_set_destructor(level3, reparenting_destructor); talloc_free(level1); CHECK_PARENT("free_parent_reparent_child", level3, alternate_level1); talloc_free(top); printf("success: free_parent_reparent_child\n"); return true; } static bool test_free_parent_reparent_child_in_pool(void) { void *top = talloc_new(NULL); char *level1; char *alternate_level1; char *level2; void *pool; struct new_parent *level3; printf("test: free_parent_reparent_child_in_pool\n# " "TALLOC FREE PARENT REPARENT CHILD IN POOL\n"); pool = talloc_pool(top, 1024); level1 = talloc_strdup(pool, "level1"); alternate_level1 = talloc_strdup(top, "alternate_level1"); level2 = talloc_strdup(level1, "level2"); level3 = talloc(level2, struct new_parent); level3->new_parent = alternate_level1; memset(level3->val, 'x', sizeof(level3->val)); talloc_set_destructor(level3, reparenting_destructor); talloc_free(level1); talloc_set_destructor(level3, NULL); CHECK_PARENT("free_parent_reparent_child_in_pool", level3, alternate_level1); /* Even freeing alternate_level1 should leave pool alone. */ talloc_free(alternate_level1); talloc_free(top); printf("success: free_parent_reparent_child_in_pool\n"); return true; } static bool test_talloc_ptrtype(void) { void *top = talloc_new(NULL); struct struct1 { int foo; int bar; } *s1, *s2, **s3, ***s4; const char *location1; const char *location2; const char *location3; const char *location4; printf("test: ptrtype\n# TALLOC PTRTYPE\n"); s1 = talloc_ptrtype(top, s1);location1 = __location__; if (talloc_get_size(s1) != sizeof(struct struct1)) { printf("failure: ptrtype [\n" "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n" "]\n", (unsigned long)talloc_get_size(s1), (unsigned long)sizeof(struct struct1)); return false; } if (strcmp(location1, talloc_get_name(s1)) != 0) { printf("failure: ptrtype [\n" "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", talloc_get_name(s1), location1); return false; } s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__; if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() allocated the wrong size " "%lu (should be %lu)\n]\n", (unsigned long)talloc_get_size(s2), (unsigned long)(sizeof(struct struct1)*10)); return false; } if (strcmp(location2, talloc_get_name(s2)) != 0) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", talloc_get_name(s2), location2); return false; } s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__; if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() allocated the wrong size " "%lu (should be %lu)\n]\n", (unsigned long)talloc_get_size(s3), (unsigned long)(sizeof(struct struct1 *)*10)); return false; } torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3), "talloc_array_ptrtype() sets the wrong name"); s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() allocated the wrong size " "%lu (should be %lu)\n]\n", (unsigned long)talloc_get_size(s4), (unsigned long)(sizeof(struct struct1 **)*10)); return false; } torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4), "talloc_array_ptrtype() sets the wrong name"); talloc_free(top); printf("success: ptrtype\n"); return true; } static int _test_talloc_free_in_destructor(void **ptr) { talloc_free(*ptr); return 0; } static bool test_talloc_free_in_destructor(void) { void *level0; void *level1; void *level2; void *level3; void *level4; void **level5; printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n"); level0 = talloc_new(NULL); level1 = talloc_new(level0); level2 = talloc_new(level1); level3 = talloc_new(level2); level4 = talloc_new(level3); level5 = talloc(level4, void *); *level5 = level3; (void)talloc_reference(level0, level3); (void)talloc_reference(level3, level3); (void)talloc_reference(level5, level3); talloc_set_destructor(level5, _test_talloc_free_in_destructor); talloc_free(level1); talloc_free(level0); printf("success: free_in_destructor\n"); return true; } static bool test_autofree(void) { #if _SAMBA_BUILD_ < 4 /* autofree test would kill smbtorture */ void *p; printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n"); p = talloc_autofree_context(); talloc_free(p); p = talloc_autofree_context(); talloc_free(p); printf("success: autofree\n"); #endif return true; } static bool test_pool(void) { void *pool; void *p1, *p2, *p3, *p4; void *p2_2; pool = talloc_pool(NULL, 1024); p1 = talloc_size(pool, 80); memset(p1, 0x11, talloc_get_size(p1)); p2 = talloc_size(pool, 20); memset(p2, 0x11, talloc_get_size(p2)); p3 = talloc_size(p1, 50); memset(p3, 0x11, talloc_get_size(p3)); p4 = talloc_size(p3, 1000); memset(p4, 0x11, talloc_get_size(p4)); #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ p2_2 = talloc_realloc_size(pool, p2, 20+1); torture_assert("pool realloc 20+1", p2_2 == p2, "failed: pointer changed"); memset(p2, 0x11, talloc_get_size(p2)); p2_2 = talloc_realloc_size(pool, p2, 20-1); torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); memset(p2, 0x11, talloc_get_size(p2)); p2_2 = talloc_realloc_size(pool, p2, 20-1); torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); memset(p2, 0x11, talloc_get_size(p2)); talloc_free(p3); /* this should reclaim the memory of p4 and p3 */ p2_2 = talloc_realloc_size(pool, p2, 400); torture_assert("pool realloc 400", p2_2 == p2, "failed: pointer changed"); memset(p2, 0x11, talloc_get_size(p2)); talloc_free(p1); /* this should reclaim the memory of p1 */ p2_2 = talloc_realloc_size(pool, p2, 800); torture_assert("pool realloc 800", p2_2 == p1, "failed: pointer not changed"); p2 = p2_2; memset(p2, 0x11, talloc_get_size(p2)); /* this should do a malloc */ p2_2 = talloc_realloc_size(pool, p2, 1800); torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed"); p2 = p2_2; memset(p2, 0x11, talloc_get_size(p2)); /* this should reclaim the memory from the pool */ p3 = talloc_size(pool, 80); torture_assert("pool alloc 80", p3 == p1, "failed: pointer changed"); memset(p3, 0x11, talloc_get_size(p3)); talloc_free(p2); talloc_free(p3); p1 = talloc_size(pool, 80); memset(p1, 0x11, talloc_get_size(p1)); p2 = talloc_size(pool, 20); memset(p2, 0x11, talloc_get_size(p2)); talloc_free(p1); p2_2 = talloc_realloc_size(pool, p2, 20-1); torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); memset(p2, 0x11, talloc_get_size(p2)); p2_2 = talloc_realloc_size(pool, p2, 20-1); torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); memset(p2, 0x11, talloc_get_size(p2)); /* this should do a malloc */ p2_2 = talloc_realloc_size(pool, p2, 1800); torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed"); p2 = p2_2; memset(p2, 0x11, talloc_get_size(p2)); /* this should reclaim the memory from the pool */ p3 = talloc_size(pool, 800); torture_assert("pool alloc 800", p3 == p1, "failed: pointer changed"); memset(p3, 0x11, talloc_get_size(p3)); #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ talloc_free(pool); return true; } static bool test_pool_steal(void) { void *root; void *pool; void *p1, *p2; void *p1_2, *p2_2; size_t hdr; size_t ofs1, ofs2; root = talloc_new(NULL); pool = talloc_pool(root, 1024); p1 = talloc_size(pool, 4 * 16); torture_assert("pool allocate 4 * 16", p1 != NULL, "failed "); memset(p1, 0x11, talloc_get_size(p1)); p2 = talloc_size(pool, 4 * 16); torture_assert("pool allocate 4 * 16", p2 > p1, "failed: !(p2 > p1) "); memset(p2, 0x11, talloc_get_size(p2)); ofs1 = PTR_DIFF(p2, p1); hdr = ofs1 - talloc_get_size(p1); talloc_steal(root, p1); talloc_steal(root, p2); talloc_free(pool); p1_2 = p1; #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ p1_2 = talloc_realloc_size(root, p1, 5 * 16); torture_assert("pool realloc 5 * 16", p1_2 > p2, "failed: pointer not changed"); memset(p1_2, 0x11, talloc_get_size(p1_2)); ofs1 = PTR_DIFF(p1_2, p2); ofs2 = talloc_get_size(p2) + hdr; torture_assert("pool realloc ", ofs1 == ofs2, "failed: pointer offset unexpected"); p2_2 = talloc_realloc_size(root, p2, 3 * 16); torture_assert("pool realloc 5 * 16", p2_2 == p2, "failed: pointer changed"); memset(p2_2, 0x11, talloc_get_size(p2_2)); #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ talloc_free(p1_2); p2_2 = p2; #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ /* now we should reclaim the full pool */ p2_2 = talloc_realloc_size(root, p2, 8 * 16); torture_assert("pool realloc 8 * 16", p2_2 == p1, "failed: pointer not expected"); p2 = p2_2; memset(p2_2, 0x11, talloc_get_size(p2_2)); /* now we malloc and free the full pool space */ p2_2 = talloc_realloc_size(root, p2, 2 * 1024); torture_assert("pool realloc 2 * 1024", p2_2 != p1, "failed: pointer not expected"); memset(p2_2, 0x11, talloc_get_size(p2_2)); #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ talloc_free(p2_2); talloc_free(root); return true; } static bool test_pool_nest(void) { void *p1, *p2, *p3; void *e = talloc_new(NULL); p1 = talloc_pool(NULL, 1024); torture_assert("talloc_pool", p1 != NULL, "failed"); p2 = talloc_pool(p1, 500); torture_assert("talloc_pool", p2 != NULL, "failed"); p3 = talloc_size(p2, 10); talloc_steal(e, p3); talloc_free(p2); talloc_free(p3); talloc_free(p1); return true; } struct pooled { char *s1; char *s2; char *s3; }; static bool test_pooled_object(void) { struct pooled *p; const char *s1 = "hello"; const char *s2 = "world"; const char *s3 = ""; p = talloc_pooled_object(NULL, struct pooled, 3, strlen(s1)+strlen(s2)+strlen(s3)+3); if (talloc_get_size(p) != sizeof(struct pooled)) { return false; } p->s1 = talloc_strdup(p, s1); TALLOC_FREE(p->s1); p->s1 = talloc_strdup(p, s2); TALLOC_FREE(p->s1); p->s1 = talloc_strdup(p, s1); p->s2 = talloc_strdup(p, s2); p->s3 = talloc_strdup(p, s3); TALLOC_FREE(p); return true; } static bool test_free_ref_null_context(void) { void *p1, *p2, *p3; int ret; talloc_disable_null_tracking(); p1 = talloc_new(NULL); p2 = talloc_new(NULL); p3 = talloc_reference(p2, p1); torture_assert("reference", p3 == p1, "failed: reference on null"); ret = talloc_free(p1); torture_assert("ref free with null parent", ret == 0, "failed: free with null parent"); talloc_free(p2); talloc_enable_null_tracking_no_autofree(); p1 = talloc_new(NULL); p2 = talloc_new(NULL); p3 = talloc_reference(p2, p1); torture_assert("reference", p3 == p1, "failed: reference on null"); ret = talloc_free(p1); torture_assert("ref free with null tracked parent", ret == 0, "failed: free with null parent"); talloc_free(p2); return true; } static bool test_rusty(void) { void *root; const char *p1; talloc_enable_null_tracking(); root = talloc_new(NULL); p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_report_full(root, stdout); talloc_free(root); CHECK_BLOCKS("null_context", NULL, 2); return true; } static bool test_free_children(void) { void *root; char *p1, *p2; const char *name, *name2; talloc_enable_null_tracking(); root = talloc_new(NULL); p1 = talloc_strdup(root, "foo1"); p2 = talloc_strdup(p1, "foo2"); (void)p2; talloc_set_name(p1, "%s", "testname"); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); if (strcmp(talloc_get_name(p1), "testname") != 0) { return false; } talloc_set_name(p1, "%s", "testname"); name = talloc_get_name(p1); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); torture_assert("name", name == talloc_get_name(p1), "name ptr changed"); torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 2); /* note that this does not free the old child name */ talloc_set_name_const(p1, "testname2"); name2 = talloc_get_name(p1); /* but this does */ talloc_free_children(p1); (void)name2; torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 1); talloc_report_full(root, stdout); talloc_free(root); return true; } static bool test_memlimit(void) { void *root; char *l1, *l2, *l3, *l4, *l5, *t; char *pool; int i; printf("test: memlimit\n# MEMORY LIMITS\n"); printf("==== talloc_new(NULL)\n"); root = talloc_new(NULL); talloc_report_full(root, stdout); printf("==== talloc_size(root, 2048)\n"); l1 = talloc_size(root, 2048); torture_assert("memlimit", l1 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_free(l1)\n"); talloc_free(l1); talloc_report_full(root, stdout); printf("==== talloc_strdup(root, level 1)\n"); l1 = talloc_strdup(root, "level 1"); torture_assert("memlimit", l1 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_set_memlimit(l1, 2048)\n"); torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0, "failed: setting memlimit should never fail\n"); talloc_report_full(root, stdout); printf("==== talloc_size(root, 2048)\n"); l2 = talloc_size(l1, 2048); torture_assert("memlimit", l2 == NULL, "failed: alloc should fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_strdup(l1, level 2)\n"); l2 = talloc_strdup(l1, "level 2"); torture_assert("memlimit", l2 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_free(l2)\n"); talloc_free(l2); talloc_report_full(root, stdout); printf("==== talloc_size(NULL, 2048)\n"); l2 = talloc_size(NULL, 2048); talloc_report_full(root, stdout); printf("==== talloc_steal(l1, l2)\n"); talloc_steal(l1, l2); talloc_report_full(root, stdout); printf("==== talloc_strdup(l2, level 3)\n"); l3 = talloc_strdup(l2, "level 3"); torture_assert("memlimit", l3 == NULL, "failed: alloc should fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_free(l2)\n"); talloc_free(l2); talloc_report_full(root, stdout); printf("==== talloc_strdup(NULL, level 2)\n"); l2 = talloc_strdup(NULL, "level 2"); talloc_steal(l1, l2); talloc_report_full(root, stdout); printf("==== talloc_strdup(l2, level 3)\n"); l3 = talloc_strdup(l2, "level 3"); torture_assert("memlimit", l3 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_set_memlimit(l3, 1024)\n"); torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0, "failed: setting memlimit should never fail\n"); talloc_report_full(root, stdout); printf("==== talloc_strdup(l3, level 4)\n"); l4 = talloc_strdup(l3, "level 4"); torture_assert("memlimit", l4 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_set_memlimit(l4, 512)\n"); torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, "failed: setting memlimit should never fail\n"); talloc_report_full(root, stdout); printf("==== talloc_strdup(l4, level 5)\n"); l5 = talloc_strdup(l4, "level 5"); torture_assert("memlimit", l5 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_realloc(NULL, l5, char, 600)\n"); t = talloc_realloc(NULL, l5, char, 600); torture_assert("memlimit", t == NULL, "failed: alloc should fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_realloc(NULL, l5, char, 5)\n"); l5 = talloc_realloc(NULL, l5, char, 5); torture_assert("memlimit", l5 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_strdup(l3, level 4)\n"); l4 = talloc_strdup(l3, "level 4"); torture_assert("memlimit", l4 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== talloc_set_memlimit(l4, 512)\n"); torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, "failed: setting memlimit should never fail\n"); talloc_report_full(root, stdout); printf("==== talloc_strdup(l4, level 5)\n"); l5 = talloc_strdup(l4, "level 5"); torture_assert("memlimit", l5 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); printf("==== Make new temp context and steal l5\n"); t = talloc_new(root); talloc_steal(t, l5); talloc_report_full(root, stdout); printf("==== talloc_size(t, 2048)\n"); l1 = talloc_size(t, 2048); torture_assert("memlimit", l1 != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_report_full(root, stdout); talloc_free(root); /* Test memlimits with pools. */ pool = talloc_pool(NULL, 10*1024); torture_assert("memlimit", pool != NULL, "failed: alloc should not fail due to memory limit\n"); talloc_set_memlimit(pool, 10*1024); for (i = 0; i < 9; i++) { l1 = talloc_size(pool, 1024); torture_assert("memlimit", l1 != NULL, "failed: alloc should not fail due to memory limit\n"); } /* The next alloc should fail. */ l2 = talloc_size(pool, 1024); torture_assert("memlimit", l2 == NULL, "failed: alloc should fail due to memory limit\n"); /* Moving one of the children shouldn't change the limit, as it's still inside the pool. */ root = talloc_new(NULL); talloc_steal(root, l1); l2 = talloc_size(pool, 1024); torture_assert("memlimit", l2 == NULL, "failed: alloc should fail due to memory limit\n"); talloc_free(pool); talloc_free(root); printf("success: memlimit\n"); return true; } #ifdef HAVE_PTHREAD #define NUM_THREADS 100 /* Sync variables. */ static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; static void *intermediate_ptr; /* Subthread. */ static void *thread_fn(void *arg) { int ret; const char *ctx_name = (const char *)arg; void *sub_ctx = NULL; /* * Do stuff that creates a new talloc hierarchy in * this thread. */ void *top_ctx = talloc_named_const(NULL, 0, "top"); if (top_ctx == NULL) { return NULL; } sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); if (sub_ctx == NULL) { return NULL; } /* * Now transfer a pointer from our hierarchy * onto the intermediate ptr. */ ret = pthread_mutex_lock(&mtx); if (ret != 0) { talloc_free(top_ctx); return NULL; } /* Wait for intermediate_ptr to be free. */ while (intermediate_ptr != NULL) { ret = pthread_cond_wait(&condvar, &mtx); if (ret != 0) { talloc_free(top_ctx); ret = pthread_mutex_unlock(&mtx); assert(ret == 0); return NULL; } } /* and move our memory onto it from our toplevel hierarchy. */ intermediate_ptr = talloc_move(NULL, &sub_ctx); /* Tell the main thread it's ready for pickup. */ pthread_cond_broadcast(&condvar); ret = pthread_mutex_unlock(&mtx); assert(ret == 0); talloc_free(top_ctx); return NULL; } /* Main thread. */ static bool test_pthread_talloc_passing(void) { int i; int ret; char str_array[NUM_THREADS][20]; pthread_t thread_id; void *mem_ctx; /* * Important ! Null tracking breaks threaded talloc. * It *must* be turned off. */ talloc_disable_null_tracking(); printf("test: pthread_talloc_passing\n# PTHREAD TALLOC PASSING\n"); /* Main thread toplevel context. */ mem_ctx = talloc_named_const(NULL, 0, "toplevel"); if (mem_ctx == NULL) { printf("failed to create toplevel context\n"); return false; } /* * Spin off NUM_THREADS threads. * They will use their own toplevel contexts. */ for (i = 0; i < NUM_THREADS; i++) { ret = snprintf(str_array[i], 20, "thread:%d", i); if (ret < 0) { printf("snprintf %d failed\n", i); return false; } ret = pthread_create(&thread_id, NULL, thread_fn, str_array[i]); if (ret != 0) { printf("failed to create thread %d (%d)\n", i, ret); return false; } } printf("Created %d threads\n", NUM_THREADS); /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */ for (i = 0; i < NUM_THREADS; i++) { ret = pthread_mutex_lock(&mtx); if (ret != 0) { printf("pthread_mutex_lock %d failed (%d)\n", i, ret); talloc_free(mem_ctx); return false; } /* Wait for intermediate_ptr to have our data. */ while (intermediate_ptr == NULL) { ret = pthread_cond_wait(&condvar, &mtx); if (ret != 0) { printf("pthread_cond_wait %d failed (%d)\n", i, ret); talloc_free(mem_ctx); ret = pthread_mutex_unlock(&mtx); assert(ret == 0); } } /* and move it onto our toplevel hierarchy. */ (void)talloc_move(mem_ctx, &intermediate_ptr); /* Tell the sub-threads we're ready for another. */ pthread_cond_broadcast(&condvar); ret = pthread_mutex_unlock(&mtx); assert(ret == 0); } CHECK_SIZE("pthread_talloc_passing", mem_ctx, NUM_THREADS * 100); #if 1 /* Dump the hierarchy. */ talloc_report(mem_ctx, stdout); #endif talloc_free(mem_ctx); printf("success: pthread_talloc_passing\n"); return true; } #endif static void test_magic_protection_abort(const char *reason) { /* exit with errcode 42 to communicate successful test to the parent process */ if (strcmp(reason, "Bad talloc magic value - unknown value") == 0) { _exit(42); } else { printf("talloc aborted for an unexpected reason\n"); } } static int test_magic_protection_destructor(int *ptr) { _exit(404); /* Not 42 */ } static bool test_magic_protection(void) { void *pool = talloc_pool(NULL, 1024); int *p1, *p2; pid_t pid; int exit_status; printf("test: magic_protection\n"); p1 = talloc(pool, int); p2 = talloc(pool, int); /* To avoid complaints from the compiler assign values to the p1 & p2. */ *p1 = 6; *p2 = 9; pid = fork(); if (pid == 0) { talloc_set_abort_fn(test_magic_protection_abort); talloc_set_destructor(p2, test_magic_protection_destructor); /* * Simulate a security attack * by triggering a buffer overflow in memset to overwrite the * constructor in the next pool chunk. * * Real attacks would attempt to set a real destructor. */ memset(p1, '\0', 32); /* Then the attack takes effect when the memory's freed. */ talloc_free(pool); /* Never reached. Make compilers happy */ return true; } while (wait(&exit_status) != pid); if (!WIFEXITED(exit_status)) { printf("Child exited through unexpected abnormal means\n"); return false; } if (WEXITSTATUS(exit_status) != 42) { printf("Child exited with wrong exit status\n"); return false; } if (WIFSIGNALED(exit_status)) { printf("Child recieved unexpected signal\n"); return false; } printf("success: magic_protection\n"); return true; } static void test_magic_free_protection_abort(const char *reason) { /* exit with errcode 42 to communicate successful test to the parent process */ if (strcmp(reason, "Bad talloc magic value - access after free") == 0) { _exit(42); } /* not 42 */ _exit(404); } static bool test_magic_free_protection(void) { void *pool = talloc_pool(NULL, 1024); int *p1, *p2, *p3; pid_t pid; int exit_status; printf("test: magic_free_protection\n"); p1 = talloc(pool, int); p2 = talloc(pool, int); /* To avoid complaints from the compiler assign values to the p1 & p2. */ *p1 = 6; *p2 = 9; p3 = talloc_realloc(pool, p2, int, 2048); torture_assert("pool realloc 2048", p3 != p2, "failed: pointer not changed"); /* * Now access the memory in the pool after the realloc(). It * should be marked as free, so use of the old pointer should * trigger the abort function */ pid = fork(); if (pid == 0) { talloc_set_abort_fn(test_magic_free_protection_abort); talloc_get_name(p2); /* Never reached. Make compilers happy */ return true; } while (wait(&exit_status) != pid); if (!WIFEXITED(exit_status)) { printf("Child exited through unexpected abnormal means\n"); return false; } if (WEXITSTATUS(exit_status) != 42) { printf("Child exited with wrong exit status\n"); return false; } if (WIFSIGNALED(exit_status)) { printf("Child recieved unexpected signal\n"); return false; } talloc_free(pool); printf("success: magic_free_protection\n"); return true; } static void test_reset(void) { talloc_set_log_fn(test_log_stdout); test_abort_stop(); talloc_disable_null_tracking(); talloc_enable_null_tracking_no_autofree(); } bool torture_local_talloc(struct torture_context *tctx) { bool ret = true; setlinebuf(stdout); test_reset(); ret &= test_pooled_object(); test_reset(); ret &= test_pool_nest(); test_reset(); ret &= test_ref1(); test_reset(); ret &= test_ref2(); test_reset(); ret &= test_ref3(); test_reset(); ret &= test_ref4(); test_reset(); ret &= test_unlink1(); test_reset(); ret &= test_misc(); test_reset(); ret &= test_realloc(); test_reset(); ret &= test_realloc_child(); test_reset(); ret &= test_steal(); test_reset(); ret &= test_move(); test_reset(); ret &= test_unref_reparent(); test_reset(); ret &= test_realloc_fn(); test_reset(); ret &= test_type(); test_reset(); ret &= test_lifeless(); test_reset(); ret &= test_loop(); test_reset(); ret &= test_free_parent_deny_child(); test_reset(); ret &= test_realloc_on_destructor_parent(); test_reset(); ret &= test_free_parent_reparent_child(); test_reset(); ret &= test_free_parent_reparent_child_in_pool(); test_reset(); ret &= test_talloc_ptrtype(); test_reset(); ret &= test_talloc_free_in_destructor(); test_reset(); ret &= test_pool(); test_reset(); ret &= test_pool_steal(); test_reset(); ret &= test_free_ref_null_context(); test_reset(); ret &= test_rusty(); test_reset(); ret &= test_free_children(); test_reset(); ret &= test_memlimit(); #ifdef HAVE_PTHREAD test_reset(); ret &= test_pthread_talloc_passing(); #endif if (ret) { test_reset(); ret &= test_speed(); } test_reset(); ret &= test_autofree(); test_reset(); ret &= test_magic_protection(); test_reset(); ret &= test_magic_free_protection(); test_reset(); talloc_disable_null_tracking(); return ret; } ldb-2.0.8/lib/talloc/testsuite_main.c0000660000000000000000000000207112406075657017457 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. local testing of talloc routines. Copyright (C) Andrew Tridgell 2004 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include "replace.h" #include "talloc_testsuite.h" int main(void) { bool ret = torture_local_talloc(NULL); if (!ret) return -1; return 0; } ldb-2.0.8/lib/talloc/web/index.html0000660000000000000000000000313012406075657017025 0ustar rootroot00000000000000 talloc

talloc

talloc is a hierarchical pool based memory allocator with destructors. It is the core memory allocator used in Samba, and has made a huge difference in many aspects of Samba4 development.

To get started with talloc, I would recommend you read the talloc guide.

Download

You can download the latest releases of talloc from the talloc directory on the samba public source archive.

Discussion and bug reports

talloc does not currently have its own mailing list or bug tracking system. For now, please use the samba-technical mailing list, and the Samba bugzilla bug tracking system.

Development

You can download the latest code either via git or rsync.

To fetch via git see the following guide:
Using Git for Samba Development
Once you have cloned the tree switch to the master branch and cd into the lib/talloc directory.

To fetch via rsync use this command:
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/talloc .

Andrew Tridgell
talloc AT tridgell.net
ldb-2.0.8/lib/talloc/wscript0000660000000000000000000001556613573675413015713 0ustar rootroot00000000000000#!/usr/bin/env python APPNAME = 'talloc' VERSION = '2.2.0' import os import sys # find the buildtools directory top = '.' while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: top = top + '/..' sys.path.insert(0, top + '/buildtools/wafsamba') out = 'bin' import wafsamba from wafsamba import samba_dist, samba_utils from waflib import Logs, Options, Context # setup what directories to put in a tarball samba_dist.DIST_DIRS("""lib/talloc:. lib/replace:lib/replace buildtools:buildtools third_party/waf:third_party/waf""") def options(opt): opt.BUILTIN_DEFAULT('replace') opt.PRIVATE_EXTENSION_DEFAULT('talloc', noextension='talloc') opt.RECURSE('lib/replace') if opt.IN_LAUNCH_DIR(): opt.add_option('--enable-talloc-compat1', help=("Build talloc 1.x.x compat library [False]"), action="store_true", dest='TALLOC_COMPAT1', default=False) def configure(conf): conf.RECURSE('lib/replace') conf.env.standalone_talloc = conf.IN_LAUNCH_DIR() conf.define('TALLOC_BUILD_VERSION_MAJOR', int(VERSION.split('.')[0])) conf.define('TALLOC_BUILD_VERSION_MINOR', int(VERSION.split('.')[1])) conf.define('TALLOC_BUILD_VERSION_RELEASE', int(VERSION.split('.')[2])) conf.env.TALLOC_COMPAT1 = False if conf.env.standalone_talloc: conf.env.TALLOC_COMPAT1 = Options.options.TALLOC_COMPAT1 conf.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' conf.env.TALLOC_VERSION = VERSION conf.CHECK_XSLTPROC_MANPAGES() conf.CHECK_HEADERS('sys/auxv.h') conf.CHECK_FUNCS('getauxval') conf.SAMBA_CONFIG_H() conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() conf.SAMBA_CHECK_PYTHON() conf.SAMBA_CHECK_PYTHON_HEADERS() if not conf.env.standalone_talloc: if conf.CHECK_BUNDLED_SYSTEM_PKG('talloc', minversion=VERSION, implied_deps='replace'): conf.define('USING_SYSTEM_TALLOC', 1) if conf.env.disable_python: using_system_pytalloc_util = False else: using_system_pytalloc_util = True name = 'pytalloc-util' + conf.all_envs['default']['PYTHON_SO_ABI_FLAG'] if not conf.CHECK_BUNDLED_SYSTEM_PKG(name, minversion=VERSION, implied_deps='talloc replace'): using_system_pytalloc_util = False if using_system_pytalloc_util: conf.define('USING_SYSTEM_PYTALLOC_UTIL', 1) def build(bld): bld.RECURSE('lib/replace') if bld.env.standalone_talloc: private_library = False # should we also install the symlink to libtalloc1.so here? bld.SAMBA_LIBRARY('talloc-compat1-%s' % (VERSION), 'compat/talloc_compat1.c', public_deps='talloc', soname='libtalloc.so.1', pc_files=[], public_headers=[], enabled=bld.env.TALLOC_COMPAT1) testsuite_deps = 'talloc' if bld.CONFIG_SET('HAVE_PTHREAD'): testsuite_deps += ' pthread' bld.SAMBA_BINARY('talloc_testsuite', 'testsuite_main.c testsuite.c', testsuite_deps, install=False) bld.SAMBA_BINARY('talloc_test_magic_differs_helper', 'test_magic_differs_helper.c', 'talloc', install=False) else: private_library = True if not bld.CONFIG_SET('USING_SYSTEM_TALLOC'): bld.SAMBA_LIBRARY('talloc', 'talloc.c', deps='replace', abi_directory='ABI', abi_match='talloc* _talloc*', hide_symbols=True, vnum=VERSION, public_headers=('' if private_library else 'talloc.h'), pc_files='talloc.pc', public_headers_install=not private_library, private_library=private_library, manpages='man/talloc.3') if not bld.CONFIG_SET('USING_SYSTEM_PYTALLOC_UTIL'): name = bld.pyembed_libname('pytalloc-util') bld.SAMBA_LIBRARY(name, source='pytalloc_util.c', public_deps='talloc', pyembed=True, vnum=VERSION, hide_symbols=True, abi_directory='ABI', abi_match='pytalloc_* _pytalloc_*', private_library=private_library, public_headers=('' if private_library else 'pytalloc.h'), pc_files='pytalloc-util.pc', enabled=bld.PYTHON_BUILD_IS_ENABLED() ) bld.SAMBA_PYTHON('pytalloc', 'pytalloc.c', deps='talloc ' + name, enabled=bld.PYTHON_BUILD_IS_ENABLED(), realname='talloc.so') bld.SAMBA_PYTHON('test_pytalloc', 'test_pytalloc.c', deps=name, enabled=bld.PYTHON_BUILD_IS_ENABLED(), realname='_test_pytalloc.so', install=False) def testonly(ctx): '''run talloc testsuite''' import samba_utils samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') cmd = os.path.join(Context.g_module.out, 'talloc_testsuite') ret = samba_utils.RUN_COMMAND(cmd) print("testsuite returned %d" % ret) magic_helper_cmd = os.path.join(Context.g_module.out, 'talloc_test_magic_differs_helper') magic_cmd = os.path.join(Context.g_module.top, 'lib', 'talloc', 'test_magic_differs.sh') if not os.path.exists(magic_cmd): magic_cmd = os.path.join(Context.g_module.top, 'test_magic_differs.sh') magic_ret = samba_utils.RUN_COMMAND(magic_cmd + " " + magic_helper_cmd) print("magic differs test returned %d" % magic_ret) pyret = samba_utils.RUN_PYTHON_TESTS(['test_pytalloc.py']) print("python testsuite returned %d" % pyret) sys.exit(ret or magic_ret or pyret) # WAF doesn't build the unit tests for this, maybe because they don't link with talloc? # This forces it def test(ctx): Options.commands.append('build') Options.commands.append('testonly') def dist(): '''makes a tarball for distribution''' samba_dist.dist() def reconfigure(ctx): '''reconfigure if config scripts have changed''' samba_utils.reconfigure(ctx) def pydoctor(ctx): '''build python apidocs''' cmd='PYTHONPATH=bin/python pydoctor --project-name=talloc --project-url=http://talloc.samba.org/ --make-html --docformat=restructuredtext --introspect-c-modules --add-module bin/python/talloc.*' print("Running: %s" % cmd) os.system(cmd) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs0000660000000000000000000001254512406075657016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t) tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *) tdb_allrecord_lock: int (struct tdb_context *, int, enum tdb_lock_flags, bool) tdb_allrecord_unlock: int (struct tdb_context *, int, bool) tdb_allrecord_upgrade: int (struct tdb_context *) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_brlock: int (struct tdb_context *, int, tdb_off_t, size_t, enum tdb_lock_flags) tdb_brunlock: int (struct tdb_context *, int, tdb_off_t, size_t) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_convert: void *(void *, uint32_t) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_expand: int (struct tdb_context *, tdb_off_t) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_have_extra_locks: bool (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_io_init: void (struct tdb_context *) tdb_lock: int (struct tdb_context *, int, int) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lock_record: int (struct tdb_context *, tdb_off_t) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_mmap: void (struct tdb_context *) tdb_munmap: int (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_needs_recovery: bool (struct tdb_context *) tdb_nest_lock: int (struct tdb_context *, uint32_t, int, enum tdb_lock_flags) tdb_nest_unlock: int (struct tdb_context *, uint32_t, int, bool) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *) tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *) tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_release_transaction_locks: void (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_lock: int (struct tdb_context *, int, enum tdb_lock_flags) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_recover: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_unlock: int (struct tdb_context *, int) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlock_record: int (struct tdb_context *, tdb_off_t) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) tdb_write_lock_record: int (struct tdb_context *, tdb_off_t) tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs0000660000000000000000000000672112406075657016327 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs0000660000000000000000000000704612406075657016331 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs0000660000000000000000000000704612406075657016332 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs0000660000000000000000000000704612406075657016333 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs0000660000000000000000000000623012406075657016243 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs0000660000000000000000000000623012406075657016244 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs0000660000000000000000000000623012406075657016245 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs0000660000000000000000000000630412406075657016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs0000660000000000000000000000630412406075657016251 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs0000660000000000000000000000630412406075657016252 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs0000660000000000000000000000630412406075657016253 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs0000660000000000000000000000635612406075657016263 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs0000660000000000000000000000713012406075657016242 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs0000660000000000000000000000713012406075657016243 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs0000660000000000000000000000723212746330636016324 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs0000660000000000000000000000734712761221116016321 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs0000660000000000000000000000734713017565171016331 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs0000660000000000000000000000734713100601766016324 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs0000660000000000000000000000743313126252766016333 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs0000660000000000000000000000743313444661620016330 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs0000660000000000000000000000743313444661620016331 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs0000660000000000000000000000771313573675413016343 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs0000660000000000000000000000771313573675413016344 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs0000660000000000000000000000713012436323671016237 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs0000660000000000000000000000713012437274221016235 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs0000660000000000000000000000713012445751350016240 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs0000660000000000000000000000723212520121120016220 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs0000660000000000000000000000723212536700353016243 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs0000660000000000000000000000723212553526406016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs0000660000000000000000000000723212617125445016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs0000660000000000000000000000723212702766507016256 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs0000660000000000000000000000771313573675413016254 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs0000660000000000000000000000771313573675413016255 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs0000660000000000000000000000771313573675413016256 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/Makefile0000660000000000000000000000166413573675413015222 0ustar rootroot00000000000000# simple makefile wrapper to run waf WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` WAF_BINARY=$(PYTHON) $(WAF_BIN) WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) all: $(WAF) build install: $(WAF) install uninstall: $(WAF) uninstall test: FORCE $(WAF) test $(TEST_OPTIONS) testenv: $(WAF) test --testenv $(TEST_OPTIONS) quicktest: $(WAF) test --quick $(TEST_OPTIONS) dist: touch .tmplock WAFLOCK=.tmplock $(WAF) dist distcheck: touch .tmplock WAFLOCK=.tmplock $(WAF) distcheck clean: $(WAF) clean distclean: $(WAF) distclean reconfigure: configure $(WAF) reconfigure show_waf_options: $(WAF) --help # some compatibility make targets everything: all testsuite: all check: test torture: all # this should do an install as well, once install is finished installcheck: test etags: $(WAF) etags ctags: $(WAF) ctags pydoctor: $(WAF) pydoctor bin/%:: FORCE $(WAF) --targets=`basename $@` FORCE: ldb-2.0.8/lib/tdb/_tdb_text.py0000660000000000000000000000642113573675413016104 0ustar rootroot00000000000000# Text wrapper for tdb bindings # # Copyright (C) 2015 Petr Viktorin # Published under the GNU LGPLv3 or later import sys import tdb class TdbTextWrapper(object): """Text interface for a TDB file""" def __init__(self, tdb): self._tdb = tdb @property def raw(self): return self._tdb def get(self, key): key = key.encode('utf-8') result = self._tdb.get(key) if result is not None: return result.decode('utf-8') def append(self, key, value): key = key.encode('utf-8') value = value.encode('utf-8') self._tdb.append(key, value) def firstkey(self): result = self._tdb.firstkey() if result: return result.decode('utf-8') def nextkey(self, key): key = key.encode('utf-8') result = self._tdb.nextkey(key) if result is not None: return result.decode('utf-8') def delete(self, key): key = key.encode('utf-8') self._tdb.delete(key) def store(self, key, value): key = key.encode('utf-8') value = value.encode('utf-8') self._tdb.store(key, value) def __iter__(self): for key in iter(self._tdb): yield key.decode('utf-8') def __getitem__(self, key): key = key.encode('utf-8') result = self._tdb[key] return result.decode('utf-8') def __contains__(self, key): key = key.encode('utf-8') return key in self._tdb def __repr__(self): return '' % self._tdb def __setitem__(self, key, value): key = key.encode('utf-8') value = value.encode('utf-8') self._tdb[key] = value def __delitem__(self, key): key = key.encode('utf-8') del self._tdb[key] if sys.version_info > (3, 0): keys = __iter__ else: iterkeys = __iter__ has_key = __contains__ ## Add wrappers for functions and getters that don't deal with text def _add_wrapper(name): orig = getattr(tdb.Tdb, name) def wrapper(self, *args, **kwargs): return orig(self._tdb, *args, **kwargs) wrapper.__name__ = orig.__name__ wrapper.__doc__ = orig.__doc__ setattr(TdbTextWrapper, name, wrapper) for name in ("transaction_cancel", "transaction_commit", "transaction_prepare_commit", "transaction_start", "reopen", "lock_all", "unlock_all", "read_lock_all", "read_unlock_all", "close", "add_flags", "remove_flags", "clear", "repack", "enable_seqnum", "increment_seqnum_nonblock", ): _add_wrapper(name) def _add_getter(name): orig = getattr(tdb.Tdb, name) doc = orig.__doc__ def getter(self): return getattr(self._tdb, name) def setter(self, value): return setattr(self._tdb, name, value) setattr(TdbTextWrapper, name, property(getter, setter, doc=doc)) for name in ("hash_size", "map_size", "freelist_size", "flags", "max_dead", "filename", "seqnum", "text", ): _add_getter(name) ldb-2.0.8/lib/tdb/common/check.c0000660000000000000000000003150013573675413016263 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Rusty Russell 2009 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* Since we opened it, these shouldn't fail unless it's recent corruption. */ static bool tdb_check_header(struct tdb_context *tdb, tdb_off_t *recovery) { struct tdb_header hdr; uint32_t h1, h2; if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) return false; if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) goto corrupt; CONVERT(hdr); if (hdr.version != TDB_VERSION) goto corrupt; if (hdr.rwlocks != 0 && hdr.rwlocks != TDB_FEATURE_FLAG_MAGIC && hdr.rwlocks != TDB_HASH_RWLOCK_MAGIC) goto corrupt; tdb_header_hash(tdb, &h1, &h2); if (hdr.magic1_hash && hdr.magic2_hash && (hdr.magic1_hash != h1 || hdr.magic2_hash != h2)) goto corrupt; if (hdr.hash_size == 0) goto corrupt; if (hdr.hash_size != tdb->hash_size) goto corrupt; if (hdr.recovery_start != 0 && hdr.recovery_start < TDB_DATA_START(tdb->hash_size)) goto corrupt; *recovery = hdr.recovery_start; return true; corrupt: tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Header is corrupt\n")); return false; } /* Generic record header check. */ static bool tdb_check_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec) { tdb_off_t tailer; /* Check rec->next: 0 or points to record offset, aligned. */ if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)){ TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too small next %u\n", off, rec->next)); goto corrupt; } if (rec->next + sizeof(*rec) < rec->next) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too large next %u\n", off, rec->next)); goto corrupt; } if ((rec->next % TDB_ALIGNMENT) != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u misaligned next %u\n", off, rec->next)); goto corrupt; } if (tdb_oob(tdb, rec->next, sizeof(*rec), 0)) goto corrupt; /* Check rec_len: similar to rec->next, implies next record. */ if ((rec->rec_len % TDB_ALIGNMENT) != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u misaligned length %u\n", off, rec->rec_len)); goto corrupt; } /* Must fit tailer. */ if (rec->rec_len < sizeof(tailer)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too short length %u\n", off, rec->rec_len)); goto corrupt; } /* OOB allows "right at the end" access, so this works for last rec. */ if (tdb_oob(tdb, off, sizeof(*rec)+rec->rec_len, 0)) goto corrupt; /* Check tailer. */ if (tdb_ofs_read(tdb, off+sizeof(*rec)+rec->rec_len-sizeof(tailer), &tailer) == -1) goto corrupt; if (tailer != sizeof(*rec) + rec->rec_len) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u invalid tailer\n", off)); goto corrupt; } return true; corrupt: tdb->ecode = TDB_ERR_CORRUPT; return false; } /* Grab some bytes: may copy if can't use mmap. Caller has already done bounds check. */ static TDB_DATA get_bytes(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) { TDB_DATA d; d.dsize = len; if (tdb->transaction == NULL && tdb->map_ptr != NULL) d.dptr = (unsigned char *)tdb->map_ptr + off; else d.dptr = tdb_alloc_read(tdb, off, d.dsize); return d; } /* Frees data if we're not able to simply use mmap. */ static void put_bytes(struct tdb_context *tdb, TDB_DATA d) { if (tdb->transaction == NULL && tdb->map_ptr != NULL) return; free(d.dptr); } /* We use the excellent Jenkins lookup3 hash; this is based on hash_word2. * See: http://burtleburtle.net/bob/c/lookup3.c */ #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) static void hash(uint32_t key, uint32_t *pc, uint32_t *pb) { uint32_t a,b,c; /* Set up the internal state */ a = b = c = 0xdeadbeef + *pc; c += *pb; a += key; c ^= b; c -= rot(b,14); a ^= c; a -= rot(c,11); b ^= a; b -= rot(a,25); c ^= b; c -= rot(b,16); a ^= c; a -= rot(c,4); b ^= a; b -= rot(a,14); c ^= b; c -= rot(b,24); *pc=c; *pb=b; } /* We want to check that all free records are in the free list (only once), and all free list entries are free records. Similarly for each hash chain of used records. Doing that naively (without walking hash chains, since we want to be linear) means keeping a list of records which have been seen in each hash chain, and another of records pointed to (ie. next pointers from records and the initial hash chain heads). These two lists should be equal. This will take 8 bytes per record, and require sorting at the end. So instead, we record each offset in a bitmap such a way that recording it twice will cancel out. Since each offset should appear exactly twice, the bitmap should be zero at the end. The approach was inspired by Bloom Filters (see Wikipedia). For each value, we flip K bits in a bitmap of size N. The number of distinct arrangements is: N! / (K! * (N-K)!) Of course, not all arrangements are actually distinct, but testing shows this formula to be close enough. So, if K == 8 and N == 256, the probability of two things flipping the same bits is 1 in 409,663,695,276,000. Given that ldb uses a hash size of 10000, using 32 bytes per hash chain (320k) seems reasonable. */ #define NUM_HASHES 8 #define BITMAP_BITS 256 static void bit_flip(unsigned char bits[], unsigned int idx) { bits[idx / CHAR_BIT] ^= (1 << (idx % CHAR_BIT)); } /* We record offsets in a bitmap for the particular chain it should be in. */ static void record_offset(unsigned char bits[], tdb_off_t off) { uint32_t h1 = off, h2 = 0; unsigned int i; /* We get two good hash values out of jhash2, so we use both. Then * we keep going to produce further hash values. */ for (i = 0; i < NUM_HASHES / 2; i++) { hash(off, &h1, &h2); bit_flip(bits, h1 % BITMAP_BITS); bit_flip(bits, h2 % BITMAP_BITS); h2++; } } /* Check that an in-use record is valid. */ static bool tdb_check_used_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec, unsigned char **hashes, int (*check)(TDB_DATA, TDB_DATA, void *), 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) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too short for contents\n", off)); return false; } key = get_bytes(tdb, off + sizeof(*rec), rec->key_len); if (!key.dptr) return false; if (tdb->hash_fn(&key) != rec->full_hash) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u has incorrect hash\n", off)); goto fail_put_key; } /* Mark this offset as a known value for this hash bucket. */ record_offset(hashes[BUCKET(rec->full_hash)+1], off); /* And similarly if the next pointer is valid. */ if (rec->next) record_offset(hashes[BUCKET(rec->full_hash)+1], rec->next); /* If they supply a check function and this record isn't dead, get data and feed it. */ if (check && rec->magic != TDB_DEAD_MAGIC) { data = get_bytes(tdb, off + sizeof(*rec) + rec->key_len, rec->data_len); if (!data.dptr) goto fail_put_key; if (check(key, data, private_data) == -1) goto fail_put_data; put_bytes(tdb, data); } put_bytes(tdb, key); return true; fail_put_data: put_bytes(tdb, data); fail_put_key: put_bytes(tdb, key); return false; } /* Check that an unused record is valid. */ static bool tdb_check_free_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec, unsigned char **hashes) { if (!tdb_check_record(tdb, off, rec)) return false; /* Mark this offset as a known value for the free list. */ record_offset(hashes[0], off); /* And similarly if the next pointer is valid. */ if (rec->next) record_offset(hashes[0], rec->next); return true; } /* Slow, but should be very rare. */ size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off) { size_t len; for (len = 0; off + len < tdb->map_size; len++) { char c; if (tdb->methods->tdb_read(tdb, off, &c, 1, 0)) return 0; if (c != 0 && c != 0x42) break; } return len; } _PUBLIC_ int tdb_check(struct tdb_context *tdb, int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { unsigned int h; unsigned char **hashes; tdb_off_t off, recovery_start; struct tdb_record rec; bool found_recovery = false; tdb_len_t dead; bool locked; /* Read-only databases use no locking at all: it's best-effort. * We may have a write lock already, so skip that case too. */ if (tdb->read_only || tdb->allrecord_lock.count != 0) { locked = false; } else { if (tdb_lockall_read(tdb) == -1) return -1; locked = true; } /* Make sure we know true size of the underlying file. */ tdb_oob(tdb, tdb->map_size, 1, 1); /* Header must be OK: also gets us the recovery ptr, if any. */ if (!tdb_check_header(tdb, &recovery_start)) goto unlock; /* We should have the whole header, too. */ if (tdb->map_size < TDB_DATA_START(tdb->hash_size)) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "File too short for hashes\n")); goto unlock; } /* One big malloc: pointers then bit arrays. */ hashes = (unsigned char **)calloc( 1, sizeof(hashes[0]) * (1+tdb->hash_size) + BITMAP_BITS / CHAR_BIT * (1+tdb->hash_size)); if (!hashes) { tdb->ecode = TDB_ERR_OOM; goto unlock; } /* Initialize pointers */ hashes[0] = (unsigned char *)(&hashes[1+tdb->hash_size]); for (h = 1; h < 1+tdb->hash_size; h++) hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT; /* Freelist and hash headers are all in a row: read them. */ for (h = 0; h < 1+tdb->hash_size; h++) { if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), &off) == -1) goto free; if (off) record_offset(hashes[h], off); } /* For each record, read it in and check it's ok. */ for (off = TDB_DATA_START(tdb->hash_size); off < tdb->map_size; off += sizeof(rec) + rec.rec_len) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == -1) goto free; switch (rec.magic) { case TDB_MAGIC: case TDB_DEAD_MAGIC: if (!tdb_check_used_record(tdb, off, &rec, hashes, check, private_data)) goto free; break; case TDB_FREE_MAGIC: if (!tdb_check_free_record(tdb, off, &rec, hashes)) goto free; break; /* If we crash after ftruncate, we can get zeroes or fill. */ case TDB_RECOVERY_INVALID_MAGIC: case 0x42424242: if (recovery_start == off) { found_recovery = true; break; } dead = tdb_dead_space(tdb, off); if (dead < sizeof(rec)) goto corrupt; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Dead space at %u-%u (of %u)\n", off, off + dead, tdb->map_size)); rec.rec_len = dead - sizeof(rec); break; case TDB_RECOVERY_MAGIC: if (recovery_start != off) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Unexpected recovery record at offset %u\n", off)); goto free; } found_recovery = true; break; default: ; corrupt: tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Bad magic 0x%x at offset %u\n", rec.magic, off)); goto free; } } /* Now, hashes should all be empty: each record exists and is referred * to by one other. */ for (h = 0; h < 1+tdb->hash_size; h++) { unsigned int i; for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) { if (hashes[h][i] != 0) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Hashes do not match records\n")); goto free; } } } /* We must have found recovery area if there was one. */ if (recovery_start != 0 && !found_recovery) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Expected a recovery area at %u\n", recovery_start)); goto free; } free(hashes); if (locked) { tdb_unlockall_read(tdb); } return 0; free: free(hashes); unlock: if (locked) { tdb_unlockall_read(tdb); } return -1; } ldb-2.0.8/lib/tdb/common/dump.c0000660000000000000000000000755213573675413016165 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash, tdb_off_t offset) { struct tdb_record rec; tdb_off_t tailer_ofs, tailer; if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { printf("ERROR: failed to read record at %u\n", offset); return 0; } printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%u " "key_len=%u data_len=%u full_hash=0x%08x magic=0x%08x\n", hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t); if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) { printf("ERROR: failed to read tailer at %u\n", tailer_ofs); return rec.next; } if (tailer != rec.rec_len + sizeof(rec)) { printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec))); } return rec.next; } static int tdb_dump_chain(struct tdb_context *tdb, int i) { struct tdb_chainwalk_ctx chainwalk; tdb_off_t rec_ptr, top; if (i == -1) { top = FREELIST_TOP; } else { top = TDB_HASH_TOP(i); } if (tdb_lock(tdb, i, F_WRLCK) != 0) return -1; if (tdb_ofs_read(tdb, top, &rec_ptr) == -1) return tdb_unlock(tdb, i, F_WRLCK); tdb_chainwalk_init(&chainwalk, rec_ptr); if (rec_ptr) printf("hash=%d\n", i); while (rec_ptr) { bool ok; rec_ptr = tdb_dump_record(tdb, i, rec_ptr); ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { printf("circular hash chain %d\n", i); break; } } return tdb_unlock(tdb, i, F_WRLCK); } _PUBLIC_ void tdb_dump_all(struct tdb_context *tdb) { uint32_t i; for (i=0;ihash_size;i++) { tdb_dump_chain(tdb, i); } printf("freelist:\n"); tdb_dump_chain(tdb, -1); } _PUBLIC_ int tdb_printfreelist(struct tdb_context *tdb) { int ret; long total_free = 0; tdb_off_t offset, rec_ptr; struct tdb_record rec; if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) return ret; offset = FREELIST_TOP; /* read in the freelist top */ if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) { tdb_unlock(tdb, -1, F_WRLCK); return 0; } printf("freelist top=[0x%08x]\n", rec_ptr ); while (rec_ptr) { if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { tdb_unlock(tdb, -1, F_WRLCK); return -1; } if (rec.magic != TDB_FREE_MAGIC) { printf("bad magic 0x%08x in free list\n", rec.magic); tdb_unlock(tdb, -1, F_WRLCK); return -1; } printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%u)] (end = 0x%08x)\n", rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); total_free += rec.rec_len; /* move to the next record */ rec_ptr = rec.next; } printf("total rec_len = [0x%08lx (%lu)]\n", total_free, total_free); return tdb_unlock(tdb, -1, F_WRLCK); } ldb-2.0.8/lib/tdb/common/error.c0000660000000000000000000000360512406075657016342 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" _PUBLIC_ enum TDB_ERROR tdb_error(struct tdb_context *tdb) { return tdb->ecode; } static struct tdb_errname { enum TDB_ERROR ecode; const char *estring; } emap[] = { {TDB_SUCCESS, "Success"}, {TDB_ERR_CORRUPT, "Corrupt database"}, {TDB_ERR_IO, "IO Error"}, {TDB_ERR_LOCK, "Locking error"}, {TDB_ERR_OOM, "Out of memory"}, {TDB_ERR_EXISTS, "Record exists"}, {TDB_ERR_NOLOCK, "Lock exists on other keys"}, {TDB_ERR_EINVAL, "Invalid parameter"}, {TDB_ERR_NOEXIST, "Record does not exist"}, {TDB_ERR_RDONLY, "write not permitted"} }; /* Error string for the last tdb error */ _PUBLIC_ const char *tdb_errorstr(struct tdb_context *tdb) { uint32_t i; for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) if (tdb->ecode == emap[i].ecode) return emap[i].estring; return "Invalid error code"; } ldb-2.0.8/lib/tdb/common/freelist.c0000660000000000000000000004257113573675413017035 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* read a freelist record and check for simple errors */ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec) { if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) return -1; if (rec->magic == TDB_MAGIC) { /* this happens when a app is showdown while deleting a record - we should not completely fail when this happens */ TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%u - fixing\n", rec->magic, off)); rec->magic = TDB_FREE_MAGIC; if (tdb_rec_write(tdb, off, rec) == -1) return -1; } if (rec->magic != TDB_FREE_MAGIC) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%u\n", rec->magic, off)); return -1; } if (tdb_oob(tdb, rec->next, sizeof(*rec), 0) != 0) return -1; return 0; } /* update a record tailer (must hold allocation lock) */ static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, const struct tdb_record *rec) { tdb_off_t totalsize; /* Offset of tailer from record header */ totalsize = sizeof(*rec) + rec->rec_len; return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t), &totalsize); } /** * Read the record directly on the left. * Fail if there is no record on the left. */ static int read_record_on_left(struct tdb_context *tdb, tdb_off_t rec_ptr, tdb_off_t *left_p, struct tdb_record *left_r) { tdb_off_t left_ptr; tdb_off_t left_size; struct tdb_record left_rec; int ret; left_ptr = rec_ptr - sizeof(tdb_off_t); if (left_ptr <= TDB_DATA_START(tdb->hash_size)) { /* no record on the left */ return -1; } /* Read in tailer and jump back to header */ ret = tdb_ofs_read(tdb, left_ptr, &left_size); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left_ptr)); return -1; } /* it could be uninitialised data */ if (left_size == 0 || left_size == TDB_PAD_U32) { return -1; } if (left_size > rec_ptr) { return -1; } left_ptr = rec_ptr - left_size; if (left_ptr < TDB_DATA_START(tdb->hash_size)) { return -1; } /* Now read in the left record */ ret = tdb->methods->tdb_read(tdb, left_ptr, &left_rec, sizeof(left_rec), DOCONV()); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left_ptr, left_size)); return -1; } *left_p = left_ptr; *left_r = left_rec; return 0; } /** * Merge new freelist record with the direct left neighbour. * This assumes that left_rec represents the record * directly to the left of right_rec and that this is * a freelist record. */ static int merge_with_left_record(struct tdb_context *tdb, tdb_off_t left_ptr, struct tdb_record *left_rec, struct tdb_record *right_rec) { int ret; left_rec->rec_len += sizeof(*right_rec) + right_rec->rec_len; ret = tdb_rec_write(tdb, left_ptr, left_rec); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "merge_with_left_record: update_left failed at %u\n", left_ptr)); return -1; } ret = update_tailer(tdb, left_ptr, left_rec); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "merge_with_left_record: update_tailer failed at %u\n", left_ptr)); return -1; } return 0; } /** * Check whether the record left of a given freelist record is * also a freelist record, and if so, merge the two records. * * Return code: * -1 upon error * 0 if left was not a free record * 1 if left was free and successfully merged. * * The current record is handed in with pointer and fully read record. * * The left record pointer and struct can be retrieved as result * in lp and lr; */ static int check_merge_with_left_record(struct tdb_context *tdb, tdb_off_t rec_ptr, struct tdb_record *rec, tdb_off_t *lp, struct tdb_record *lr) { tdb_off_t left_ptr; struct tdb_record left_rec; int ret; ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); if (ret != 0) { return 0; } if (left_rec.magic != TDB_FREE_MAGIC) { return 0; } /* It's free - expand to include it. */ ret = merge_with_left_record(tdb, left_ptr, &left_rec, rec); if (ret != 0) { return -1; } if (lp != NULL) { *lp = left_ptr; } if (lr != NULL) { *lr = left_rec; } return 1; } /** * Check whether the record left of a given freelist record is * also a freelist record, and if so, merge the two records. * * Return code: * -1 upon error * 0 if left was not a free record * 1 if left was free and successfully merged. * * In this variant, the input record is specified just as the pointer * and is read from the database if needed. * * next_ptr will contain the original record's next pointer after * successful merging (which will be lost after merging), so that * the caller can update the last pointer. */ static int check_merge_ptr_with_left_record(struct tdb_context *tdb, tdb_off_t rec_ptr, tdb_off_t *next_ptr) { tdb_off_t left_ptr; struct tdb_record rec, left_rec; int ret; ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); if (ret != 0) { return 0; } if (left_rec.magic != TDB_FREE_MAGIC) { return 0; } /* It's free - expand to include it. */ ret = tdb->methods->tdb_read(tdb, rec_ptr, &rec, sizeof(rec), DOCONV()); if (ret != 0) { return -1; } ret = merge_with_left_record(tdb, left_ptr, &left_rec, &rec); if (ret != 0) { return -1; } if (next_ptr != NULL) { *next_ptr = rec.next; } return 1; } /** * Add an element into the freelist. * * We merge the new record into the left record if it is also a * free record, but not with the right one. This makes the * operation O(1) instead of O(n): merging with the right record * requires a traverse of the freelist to find the previous * record in the free list. * * This prevents db traverses from being O(n^2) after a lot of deletes. */ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) { int ret; /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; /* set an initial tailer, so if we fail we don't leave a bogus record */ if (update_tailer(tdb, offset, rec) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n")); goto fail; } ret = check_merge_with_left_record(tdb, offset, rec, NULL, NULL); if (ret == -1) { goto fail; } if (ret == 1) { /* merged */ goto done; } /* Nothing to merge, prepend to free list */ rec->magic = TDB_FREE_MAGIC; if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || tdb_rec_write(tdb, offset, rec) == -1 || tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%u\n", offset)); goto fail; } done: /* And we're done. */ tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: tdb_unlock(tdb, -1, F_WRLCK); return -1; } /* the core of tdb_allocate - called when we have decided which free list entry to use Note that we try to allocate by grabbing data from the end of an existing record, not the beginning. This is so the left merge in a free is more likely to be able to free up the record without fragmentation */ static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, tdb_len_t length, tdb_off_t rec_ptr, struct tdb_record *rec, tdb_off_t last_ptr) { #define MIN_REC_SIZE (sizeof(struct tdb_record) + sizeof(tdb_off_t) + 8) if (rec->rec_len < length + MIN_REC_SIZE) { /* we have to grab the whole record */ /* unlink it from the previous record */ if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { return 0; } /* mark it not free */ rec->magic = TDB_MAGIC; if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { return 0; } return rec_ptr; } /* we're going to just shorten the existing record */ rec->rec_len -= (length + sizeof(*rec)); if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { return 0; } if (update_tailer(tdb, rec_ptr, rec) == -1) { return 0; } /* and setup the new record */ rec_ptr += sizeof(*rec) + rec->rec_len; memset(rec, '\0', sizeof(*rec)); rec->rec_len = length; rec->magic = TDB_MAGIC; if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { return 0; } if (update_tailer(tdb, rec_ptr, rec) == -1) { return 0; } return rec_ptr; } /* allocate some space from the free list. The offset returned points to a unconnected tdb_record within the database with room for at least length bytes of total data 0 is returned if the space could not be allocated */ static tdb_off_t tdb_allocate_from_freelist( struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec) { tdb_off_t rec_ptr, last_ptr, newrec_ptr; struct tdb_chainwalk_ctx chainwalk; bool modified; struct { tdb_off_t rec_ptr, last_ptr; tdb_len_t rec_len; } bestfit; float multiplier = 1.0; bool merge_created_candidate; /* over-allocate to reduce fragmentation */ length *= 1.25; /* Extra bytes required for tailer */ length += sizeof(tdb_off_t); length = TDB_ALIGN(length, TDB_ALIGNMENT); again: merge_created_candidate = false; last_ptr = FREELIST_TOP; /* read in the freelist top */ if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) return 0; modified = false; tdb_chainwalk_init(&chainwalk, rec_ptr); bestfit.rec_ptr = 0; bestfit.last_ptr = 0; bestfit.rec_len = 0; /* this is a best fit allocation strategy. Originally we used a first fit strategy, but it suffered from massive fragmentation issues when faced with a slowly increasing record size. */ while (rec_ptr) { int ret; tdb_off_t left_ptr; struct tdb_record left_rec; if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { return 0; } ret = check_merge_with_left_record(tdb, rec_ptr, rec, &left_ptr, &left_rec); if (ret == -1) { return 0; } if (ret == 1) { /* merged */ rec_ptr = rec->next; ret = tdb_ofs_write(tdb, last_ptr, &rec->next); if (ret == -1) { return 0; } /* * We have merged the current record into the left * neighbour. So our traverse of the freelist will * skip it and consider the next record in the chain. * * But the enlarged left neighbour may be a candidate. * If it is, we can not directly use it, though. * The only thing we can do and have to do here is to * update the current best fit size in the chain if the * current best fit is the left record. (By that we may * worsen the best fit we already had, bit this is not a * problem.) * * If the current best fit is not the left record, * all we can do is remember the fact that a merge * created a new candidate so that we can trigger * a second walk of the freelist if at the end of * the first walk we have not found any fit. * This way we can avoid expanding the database. */ if (bestfit.rec_ptr == left_ptr) { bestfit.rec_len = left_rec.rec_len; } if (left_rec.rec_len > length) { merge_created_candidate = true; } modified = true; continue; } if (rec->rec_len >= length) { if (bestfit.rec_ptr == 0 || rec->rec_len < bestfit.rec_len) { bestfit.rec_len = rec->rec_len; bestfit.rec_ptr = rec_ptr; bestfit.last_ptr = last_ptr; } } /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; if (!modified) { bool ok; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return 0; } } /* if we've found a record that is big enough, then stop searching if its also not too big. The definition of 'too big' changes as we scan through */ if (bestfit.rec_len > 0 && bestfit.rec_len < length * multiplier) { break; } /* this multiplier means we only extremely rarely search more than 50 or so records. At 50 records we accept records up to 11 times larger than what we want */ multiplier *= 1.05; } if (bestfit.rec_ptr != 0) { if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { return 0; } newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, rec, bestfit.last_ptr); return newrec_ptr; } if (merge_created_candidate) { goto again; } /* we didn't find enough space. See if we can expand the database and if we can then try again */ if (tdb_expand(tdb, length + sizeof(*rec)) == 0) goto again; return 0; } static bool tdb_alloc_dead( struct tdb_context *tdb, int hash, tdb_len_t length, tdb_off_t *rec_ptr, struct tdb_record *rec) { tdb_off_t last_ptr; *rec_ptr = tdb_find_dead(tdb, hash, rec, length, &last_ptr); if (*rec_ptr == 0) { return false; } /* * Unlink the record from the hash chain, it's about to be moved into * another one. */ return (tdb_ofs_write(tdb, last_ptr, &rec->next) == 0); } static void tdb_purge_dead(struct tdb_context *tdb, uint32_t hash) { int max_dead_records = tdb->max_dead_records; tdb->max_dead_records = 0; tdb_trim_dead(tdb, hash); tdb->max_dead_records = max_dead_records; } /* * Chain "hash" is assumed to be locked */ tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, struct tdb_record *rec) { tdb_off_t ret; uint32_t i; if (tdb->max_dead_records == 0) { /* * No dead records to expect anywhere. Do the blocking * freelist lock without trying to steal from others */ goto blocking_freelist_allocate; } /* * The following loop tries to get the freelist lock nonblocking. If * it gets the lock, allocate from there. If the freelist is busy, * instead of waiting we try to steal dead records from other hash * chains. * * Be aware that we do nonblocking locks on the other hash chains as * well and fail gracefully. This way we avoid deadlocks (we block two * hash chains, something which is pretty bad normally) */ for (i=0; ihash_size; i++) { int list; list = BUCKET(hash+i); if (tdb_lock_nonblock(tdb, list, F_WRLCK) == 0) { bool got_dead; got_dead = tdb_alloc_dead(tdb, list, length, &ret, rec); tdb_unlock(tdb, list, F_WRLCK); if (got_dead) { return ret; } } if (tdb_lock_nonblock(tdb, -1, F_WRLCK) == 0) { /* * Under the freelist lock take the chance to give * back our dead records. */ tdb_purge_dead(tdb, hash); ret = tdb_allocate_from_freelist(tdb, length, rec); tdb_unlock(tdb, -1, F_WRLCK); return ret; } } blocking_freelist_allocate: if (tdb_lock(tdb, -1, F_WRLCK) == -1) { return 0; } /* * Dead records can happen even if max_dead_records==0, they * are older than the max_dead_records concept: They happen if * tdb_delete happens concurrently with a traverse. */ tdb_purge_dead(tdb, hash); ret = tdb_allocate_from_freelist(tdb, length, rec); tdb_unlock(tdb, -1, F_WRLCK); return ret; } /** * Merge adjacent records in the freelist. */ static int tdb_freelist_merge_adjacent(struct tdb_context *tdb, int *count_records, int *count_merged) { tdb_off_t cur, next; int count = 0; int merged = 0; int ret; ret = tdb_lock(tdb, -1, F_RDLCK); if (ret == -1) { return -1; } cur = FREELIST_TOP; while (tdb_ofs_read(tdb, cur, &next) == 0 && next != 0) { tdb_off_t next2; count++; ret = check_merge_ptr_with_left_record(tdb, next, &next2); if (ret == -1) { goto done; } if (ret == 1) { /* * merged: * now let cur->next point to next2 instead of next */ ret = tdb_ofs_write(tdb, cur, &next2); if (ret != 0) { goto done; } next = next2; merged++; } cur = next; } if (count_records != NULL) { *count_records = count; } if (count_merged != NULL) { *count_merged = merged; } ret = 0; done: tdb_unlock(tdb, -1, F_RDLCK); return ret; } /** * return the size of the freelist - no merging done */ static int tdb_freelist_size_no_merge(struct tdb_context *tdb) { tdb_off_t ptr; int count=0; if (tdb_lock(tdb, -1, F_RDLCK) == -1) { return -1; } ptr = FREELIST_TOP; while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { count++; } tdb_unlock(tdb, -1, F_RDLCK); return count; } /** * return the size of the freelist - used to decide if we should repack * * As a side effect, adjacent records are merged unless the * database is read-only, in order to reduce the fragmentation * without repacking. */ _PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) { int count = 0; if (tdb->read_only) { count = tdb_freelist_size_no_merge(tdb); } else { int ret; ret = tdb_freelist_merge_adjacent(tdb, &count, NULL); if (ret != 0) { return -1; } } return count; } ldb-2.0.8/lib/tdb/common/freelistcheck.c0000660000000000000000000000517013573675413020025 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. trivial database library Copyright (C) Jeremy Allison 2006 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* Check the freelist is good and contains no loops. Very memory intensive - only do this as a consistency checker. Heh heh - uses an in memory tdb as the storage for the "seen" record list. For some reason this strikes me as extremely clever as I don't have to write another tree data structure implementation :-). */ static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) { TDB_DATA key; key.dptr = (unsigned char *)&rec_ptr; key.dsize = sizeof(rec_ptr); return tdb_store(mem_tdb, key, tdb_null, TDB_INSERT); } _PUBLIC_ int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) { struct tdb_context *mem_tdb = NULL; struct tdb_record rec; tdb_off_t rec_ptr, last_ptr; int ret = -1; *pnum_entries = 0; mem_tdb = tdb_open("flval", tdb->hash_size, TDB_INTERNAL, O_RDWR, 0600); if (!mem_tdb) { return -1; } if (tdb_lock(tdb, -1, F_WRLCK) == -1) { tdb_close(mem_tdb); return 0; } last_ptr = FREELIST_TOP; /* Store the FREELIST_TOP record. */ if (seen_insert(mem_tdb, last_ptr) == -1) { tdb->ecode = TDB_ERR_CORRUPT; ret = -1; goto fail; } /* read in the freelist top */ if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) { goto fail; } while (rec_ptr) { /* If we can't store this record (we've seen it before) then the free list has a loop and must be corrupt. */ if (seen_insert(mem_tdb, rec_ptr)) { tdb->ecode = TDB_ERR_CORRUPT; ret = -1; goto fail; } if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) { goto fail; } /* move to the next record */ rec_ptr = rec.next; *pnum_entries += 1; } ret = 0; fail: tdb_close(mem_tdb); tdb_unlock(tdb, -1, F_WRLCK); return ret; } ldb-2.0.8/lib/tdb/common/hash.c0000660000000000000000000003051113444661620016122 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Rusty Russell 2010 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* This is based on the hash algorithm from gdbm */ unsigned int tdb_old_hash(TDB_DATA *key) { uint32_t value; /* Used to compute the hash value. */ uint32_t i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) value = (value + (key->dptr[i] << (i*5 % 24))); return (1103515243 * value + 12345); } #ifndef WORDS_BIGENDIAN # define HASH_LITTLE_ENDIAN 1 # define HASH_BIG_ENDIAN 0 #else # define HASH_LITTLE_ENDIAN 0 # define HASH_BIG_ENDIAN 1 #endif /* ------------------------------------------------------------------------------- lookup3.c, by Bob Jenkins, May 2006, Public Domain. These are functions for producing 32-bit hashes for hash table lookup. hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and 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 hashlittle(). hashlittle() and hashbig() hash byte arrays. hashlittle() is is faster than hashbig() on little-endian machines. Intel and AMD are little-endian machines. On second thought, you probably want hashlittle2(), which is identical to hashlittle() except it returns two 32-bit hashes for the price of one. You could implement hashbig2() 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; mix(a,b,c); a += i4; b += i5; c += i6; mix(a,b,c); a += i7; final(a,b,c); then use c as the hash value. If you have a variable length array of 4-byte integers to hash, use hash_word(). If you have a byte array (like a character string), use hashlittle(). If you have several byte arrays, or a mix of things, see the comments above hashlittle(). 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. */ #define hashsize(n) ((uint32_t)1<<(n)) #define hashmask(n) (hashsize(n)-1) #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) /* ------------------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. This is reversible, so any information in (a,b,c) before mix() is still in (a,b,c) after mix(). If four pairs of (a,b,c) inputs are run through mix(), or through 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^=rot(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 mix(a,b,c) \ { \ a -= c; a ^= rot(c, 4); c += b; \ b -= a; b ^= rot(a, 6); a += c; \ c -= b; c ^= rot(b, 8); b += a; \ a -= c; a ^= rot(c,16); c += b; \ b -= a; b ^= rot(a,19); a += c; \ c -= b; c ^= rot(b, 4); b += a; \ } /* ------------------------------------------------------------------------------- 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 final(a,b,c) \ { \ c ^= b; c -= rot(b,14); \ a ^= c; a -= rot(c,11); \ b ^= a; b -= rot(a,25); \ c ^= b; c -= rot(b,16); \ a ^= c; a -= rot(c,4); \ b ^= a; b -= rot(a,14); \ c ^= b; c -= rot(b,24); \ } /* ------------------------------------------------------------------------------- hashlittle() -- hash a variable-length key into a 32-bit value k : the key (the unaligned variable-length array of bytes) length : the length of the key, counting by bytes val2 : IN: can be any 4-byte value OUT: second 32 bit hash. 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. Note that the return value is better mixed than val2, so use that first. 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 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; 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 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 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 1 : a+=k8[0]; break; case 0 : return c; } } 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 (length > 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); mix(a,b,c); length -= 12; k += 6; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; switch(length) { 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; 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 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 6 : b+=k[2]; a+=k[0]+(((uint32_t)k[1])<<16); break; 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 2 : a+=k[0]; break; case 1 : a+=k8[0]; break; case 0 : return c; /* zero length requires no mixing */ } } 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 (length > 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; mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) { 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 1 : a+=k[0]; break; case 0 : return c; } } final(a,b,c); return c; } _PUBLIC_ unsigned int tdb_jenkins_hash(TDB_DATA *key) { return hashlittle(key->dptr, key->dsize); } ldb-2.0.8/lib/tdb/common/io.c0000660000000000000000000004517113573675413015626 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* * We prepend the mutex area, so fixup offsets. See mutex.c for details. * tdb->hdr_ofs is 0 or header.mutex_size. * * Note: that we only have the 4GB limit of tdb_off_t for * tdb->map_size. The file size on disk can be 4GB + tdb->hdr_ofs! */ static bool tdb_adjust_offset(struct tdb_context *tdb, off_t *off) { off_t tmp = tdb->hdr_ofs + *off; if ((tmp < tdb->hdr_ofs) || (tmp < *off)) { errno = EIO; return false; } *off = tmp; return true; } static ssize_t tdb_pwrite(struct tdb_context *tdb, const void *buf, size_t count, off_t offset) { ssize_t ret; if (!tdb_adjust_offset(tdb, &offset)) { return -1; } do { ret = pwrite(tdb->fd, buf, count, offset); } while ((ret == -1) && (errno == EINTR)); return ret; } static ssize_t tdb_pread(struct tdb_context *tdb, void *buf, size_t count, off_t offset) { ssize_t ret; if (!tdb_adjust_offset(tdb, &offset)) { return -1; } do { ret = pread(tdb->fd, buf, count, offset); } while ((ret == -1) && (errno == EINTR)); return ret; } static int tdb_ftruncate(struct tdb_context *tdb, off_t length) { ssize_t ret; if (!tdb_adjust_offset(tdb, &length)) { return -1; } do { ret = ftruncate(tdb->fd, length); } while ((ret == -1) && (errno == EINTR)); return ret; } #ifdef HAVE_POSIX_FALLOCATE static int tdb_posix_fallocate(struct tdb_context *tdb, off_t offset, off_t len) { ssize_t ret; if (!tdb_adjust_offset(tdb, &offset)) { return -1; } do { ret = posix_fallocate(tdb->fd, offset, len); } while ((ret == -1) && (errno == EINTR)); return ret; } #endif static int tdb_fstat(struct tdb_context *tdb, struct stat *buf) { int ret; ret = fstat(tdb->fd, buf); if (ret == -1) { return -1; } if (buf->st_size < tdb->hdr_ofs) { errno = EIO; return -1; } buf->st_size -= tdb->hdr_ofs; return ret; } /* check for an out of bounds access - if it is out of bounds then see if the database has been expanded by someone else and expand if necessary */ static int tdb_notrans_oob( struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { struct stat st; if (len + off < len) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob off %u len %u wrap\n", off, len)); } return -1; } /* * This duplicates functionality from tdb_oob(). Don't remove: * we still have direct callers of tdb->methods->tdb_oob() * inside transaction.c. */ if (off + len <= tdb->map_size) return 0; if (tdb->flags & TDB_INTERNAL) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond internal malloc size %u\n", (int)(off + len), (int)tdb->map_size)); } return -1; } if (tdb_fstat(tdb, &st) == -1) { tdb->ecode = TDB_ERR_IO; return -1; } /* Beware >4G files! */ if ((tdb_off_t)st.st_size != st.st_size) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_oob len %llu too large!\n", (long long)st.st_size)); return -1; } /* Unmap, update size, remap. We do this unconditionally, to handle * the unusual case where the db is truncated. * * This can happen to a child using tdb_reopen_all(true) on a * TDB_CLEAR_IF_FIRST tdb whose parent crashes: the next * opener will truncate the database. */ if (tdb_munmap(tdb) == -1) { tdb->ecode = TDB_ERR_IO; return -1; } tdb->map_size = st.st_size; if (tdb_mmap(tdb) != 0) { return -1; } if (st.st_size < (size_t)off + len) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond eof at %u\n", (int)(off + len), (int)st.st_size)); } return -1; } return 0; } /* write a lump of data at a specified offset */ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { if (len == 0) { return 0; } if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } if (tdb_oob(tdb, off, len, 0) != 0) return -1; if (tdb->map_ptr) { memcpy(off + (char *)tdb->map_ptr, buf, len); } else { #ifdef HAVE_INCOHERENT_MMAP tdb->ecode = TDB_ERR_IO; return -1; #else ssize_t written; written = tdb_pwrite(tdb, buf, len, off); if ((written != (ssize_t)len) && (written != -1)) { /* try once more */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only " "%zi of %u bytes at %u, trying once more\n", written, len, off)); written = tdb_pwrite(tdb, (const char *)buf+written, len-written, off+written); } if (written == -1) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %u " "len=%u (%s)\n", off, len, strerror(errno))); return -1; } else if (written != (ssize_t)len) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to " "write %u bytes at %u in two attempts\n", len, off)); return -1; } #endif } return 0; } /* Endian conversion: we only ever deal with 4 byte quantities */ void *tdb_convert(void *buf, uint32_t size) { uint32_t i, *p = (uint32_t *)buf; for (i = 0; i < size / 4; i++) p[i] = TDB_BYTEREV(p[i]); return buf; } /* read a lump of data at a specified offset, maybe convert */ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { if (tdb_oob(tdb, off, len, 0) != 0) { return -1; } if (tdb->map_ptr) { memcpy(buf, off + (char *)tdb->map_ptr, len); } else { #ifdef HAVE_INCOHERENT_MMAP tdb->ecode = TDB_ERR_IO; return -1; #else ssize_t ret; ret = tdb_pread(tdb, buf, len, off); if (ret != (ssize_t)len) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %u " "len=%u ret=%zi (%s) map_size=%u\n", off, len, ret, strerror(errno), tdb->map_size)); return -1; } #endif } if (cv) { tdb_convert(buf, len); } return 0; } /* do an unlocked scan of the hash table heads to find the next non-zero head. The value will then be confirmed with the lock held */ static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) { uint32_t h = *chain; if (tdb->map_ptr) { for (;h < tdb->hash_size;h++) { if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { break; } } } else { uint32_t off=0; for (;h < tdb->hash_size;h++) { if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { break; } } } (*chain) = h; } int tdb_munmap(struct tdb_context *tdb) { if (tdb->flags & TDB_INTERNAL) return 0; #ifdef HAVE_MMAP if (tdb->map_ptr) { int ret; ret = munmap(tdb->map_ptr, tdb->map_size); if (ret != 0) return ret; } #endif tdb->map_ptr = NULL; return 0; } /* If mmap isn't coherent, *everyone* must always mmap. */ static bool should_mmap(const struct tdb_context *tdb) { #ifdef HAVE_INCOHERENT_MMAP return true; #else return !(tdb->flags & TDB_NOMMAP); #endif } int tdb_mmap(struct tdb_context *tdb) { if (tdb->flags & TDB_INTERNAL) return 0; #ifdef HAVE_MMAP if (should_mmap(tdb)) { tdb->map_ptr = mmap(NULL, tdb->map_size, PROT_READ|(tdb->read_only? 0:PROT_WRITE), MAP_SHARED|MAP_FILE, tdb->fd, tdb->hdr_ofs); /* * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! */ if (tdb->map_ptr == MAP_FAILED) { tdb->map_ptr = NULL; TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %u (%s)\n", tdb->map_size, strerror(errno))); #ifdef HAVE_INCOHERENT_MMAP tdb->ecode = TDB_ERR_IO; return -1; #endif } } else { tdb->map_ptr = NULL; } #else tdb->map_ptr = NULL; #endif return 0; } /* expand a file. we prefer to use ftruncate, as that is what posix says to use for mmap expansion */ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { char buf[8192]; tdb_off_t new_size; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } if (!tdb_add_off_t(size, addition, &new_size)) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " "overflow detected current size[%u] addition[%u]!\n", (unsigned)size, (unsigned)addition)); errno = ENOSPC; return -1; } #ifdef HAVE_POSIX_FALLOCATE ret = tdb_posix_fallocate(tdb, size, addition); if (ret == 0) { return 0; } if (ret == ENOSPC) { /* * The Linux glibc (at least as of 2.24) fallback if * the file system does not support fallocate does not * reset the file size back to where it was. Also, to * me it is unclear from the posix spec of * posix_fallocate whether this is allowed or * not. Better be safe than sorry and "goto fail" but * "return -1" here, leaving the EOF pointer too * large. */ goto fail; } /* * Retry the "old" way. Possibly unnecessary, but looking at * our configure script there seem to be weird failure modes * for posix_fallocate. See commit 3264a98ff16de, which * probably refers to * https://sourceware.org/bugzilla/show_bug.cgi?id=1083. */ #endif ret = tdb_ftruncate(tdb, new_size); if (ret == -1) { char b = 0; ssize_t written = tdb_pwrite(tdb, &b, 1, new_size - 1); if (written == 0) { /* try once more, potentially revealing errno */ written = tdb_pwrite(tdb, &b, 1, new_size - 1); } if (written == 0) { /* again - give up, guessing errno */ errno = ENOSPC; } if (written != 1) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %u failed (%s)\n", (unsigned)new_size, strerror(errno))); return -1; } } /* now fill the file with something. This ensures that the file isn't sparse, which would be very bad if we ran out of disk. This must be done with write, not via mmap */ memset(buf, TDB_PAD_BYTE, sizeof(buf)); while (addition) { size_t n = addition>sizeof(buf)?sizeof(buf):addition; ssize_t written = tdb_pwrite(tdb, buf, n, size); if (written == 0) { /* prevent infinite loops: try _once_ more */ written = tdb_pwrite(tdb, buf, n, size); } if (written == 0) { /* give up, trying to provide a useful errno */ tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " "returned 0 twice: giving up!\n")); errno = ENOSPC; goto fail; } if (written == -1) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of " "%u bytes failed (%s)\n", (int)n, strerror(errno))); goto fail; } if (written != n) { TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote " "only %zu of %zi bytes - retrying\n", written, n)); } addition -= written; size += written; } return 0; fail: { int err = errno; /* * We're holding the freelist lock or are inside a * transaction. Cutting the file is safe, the space we * tried to allocate can't have been used anywhere in * the meantime. */ ret = tdb_ftruncate(tdb, size); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: " "retruncate to %ju failed\n", (uintmax_t)size)); } errno = err; } return -1; } /* You need 'size', this tells you how much you should expand by. */ tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size) { tdb_off_t new_size, top_size, increment; tdb_off_t max_size = UINT32_MAX - map_size; if (size > max_size) { /* * We can't round up anymore, just give back * what we're asked for. * * The caller has to take care of the ENOSPC handling. */ return size; } /* limit size in order to avoid using up huge amounts of memory for * in memory tdbs if an oddball huge record creeps in */ if (size > 100 * 1024) { increment = size * 2; } else { increment = size * 100; } if (increment < size) { goto overflow; } if (!tdb_add_off_t(map_size, increment, &top_size)) { goto overflow; } /* always make room for at least top_size more records, and at least 25% more space. if the DB is smaller than 100MiB, otherwise grow it by 10% only. */ if (map_size > 100 * 1024 * 1024) { new_size = map_size * 1.10; } else { new_size = map_size * 1.25; } if (new_size < map_size) { goto overflow; } /* Round the database up to a multiple of the page size */ new_size = MAX(top_size, new_size); if (new_size + page_size < new_size) { /* There's a "+" in TDB_ALIGN that might overflow... */ goto overflow; } return TDB_ALIGN(new_size, page_size) - map_size; overflow: /* * Somewhere in between we went over 4GB. Make one big jump to * exactly 4GB database size. */ return max_size; } /* expand the database at least size bytes by expanding the underlying file and doing the mmap again if necessary */ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) { struct tdb_record rec; tdb_off_t offset; tdb_off_t new_size; if (tdb_lock(tdb, -1, F_WRLCK) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); return -1; } /* must know about any previous expansions by another process */ tdb_oob(tdb, tdb->map_size, 1, 1); /* * Note: that we don't care about tdb->hdr_ofs != 0 here * * The 4GB limitation is just related to tdb->map_size * and the offset calculation in the records. * * The file on disk can be up to 4GB + tdb->hdr_ofs */ size = tdb_expand_adjust(tdb->map_size, size, tdb->page_size); if (!tdb_add_off_t(tdb->map_size, size, &new_size)) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_expand " "overflow detected current map_size[%u] size[%u]!\n", (unsigned)tdb->map_size, (unsigned)size)); goto fail; } /* form a new freelist record */ offset = tdb->map_size; memset(&rec,'\0',sizeof(rec)); rec.rec_len = size - sizeof(rec); if (tdb->flags & TDB_INTERNAL) { char *new_map_ptr; new_map_ptr = (char *)realloc(tdb->map_ptr, new_size); if (!new_map_ptr) { tdb->ecode = TDB_ERR_OOM; goto fail; } tdb->map_ptr = new_map_ptr; tdb->map_size = new_size; } else { int ret; /* * expand the file itself */ ret = tdb->methods->tdb_expand_file(tdb, tdb->map_size, size); if (ret != 0) { goto fail; } /* Explicitly remap: if we're in a transaction, this won't * happen automatically! */ tdb_munmap(tdb); tdb->map_size = new_size; if (tdb_mmap(tdb) != 0) { goto fail; } } /* link it into the free list */ if (tdb_free(tdb, offset, &rec) == -1) goto fail; tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: tdb_unlock(tdb, -1, F_WRLCK); return -1; } int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { int ret = tdb->methods->tdb_oob(tdb, off, len, probe); return ret; } /* read/write a tdb_off_t */ int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) { return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); } int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) { tdb_off_t off = *d; return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); } /* read a lump of data, allocating the space for it */ unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len) { unsigned char *buf; /* some systems don't like zero length malloc */ if (!(buf = (unsigned char *)malloc(len ? len : 1))) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%u (%s)\n", len, strerror(errno))); return NULL; } if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) { SAFE_FREE(buf); return NULL; } return buf; } /* Give a piece of tdb data to a parser */ int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, tdb_off_t offset, tdb_len_t len, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { TDB_DATA data; int result; data.dsize = len; if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { /* * Optimize by avoiding the malloc/memcpy/free, point the * parser directly at the mmap area. */ if (tdb_oob(tdb, offset, len, 0) != 0) { return -1; } data.dptr = offset + (unsigned char *)tdb->map_ptr; return parser(key, data, private_data); } if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) { return -1; } result = parser(key, data, private_data); free(data.dptr); return result; } /* 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)) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_CORRUPT; 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_oob(tdb, offset, rec->key_len, 1); if (ret == -1) { return -1; } ret = tdb_oob(tdb, offset, rec->data_len, 1); if (ret == -1) { return -1; } ret = tdb_oob(tdb, offset, rec->rec_len, 1); if (ret == -1) { return -1; } return tdb_oob(tdb, rec->next, sizeof(*rec), 0); } int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) { struct tdb_record r = *rec; return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); } static const struct tdb_methods io_methods = { tdb_read, tdb_write, tdb_next_hash_chain, tdb_notrans_oob, tdb_expand_file, }; /* initialise the default methods table */ void tdb_io_init(struct tdb_context *tdb) { tdb->methods = &io_methods; } ldb-2.0.8/lib/tdb/common/lock.c0000660000000000000000000006173313573675413016151 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" _PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) { tdb->interrupt_sig_ptr = ptr; } static int fcntl_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, bool waitflag) { struct flock fl; int cmd; #ifdef USE_TDB_MUTEX_LOCKING { int ret; if (tdb_mutex_lock(tdb, rw, off, len, waitflag, &ret)) { return ret; } } #endif fl.l_type = rw; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; cmd = waitflag ? F_SETLKW : F_SETLK; return fcntl(tdb->fd, cmd, &fl); } static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len) { struct flock fl; #if 0 /* Check they matched up locks and unlocks correctly. */ char line[80]; FILE *locks; bool found = false; locks = fopen("/proc/locks", "r"); while (fgets(line, 80, locks)) { char *p; int type, start, l; /* eg. 1: FLOCK ADVISORY WRITE 2440 08:01:2180826 0 EOF */ p = strchr(line, ':') + 1; if (strncmp(p, " POSIX ADVISORY ", strlen(" POSIX ADVISORY "))) continue; p += strlen(" FLOCK ADVISORY "); if (strncmp(p, "READ ", strlen("READ ")) == 0) type = F_RDLCK; else if (strncmp(p, "WRITE ", strlen("WRITE ")) == 0) type = F_WRLCK; else abort(); p += 6; if (atoi(p) != getpid()) continue; p = strchr(strchr(p, ' ') + 1, ' ') + 1; start = atoi(p); p = strchr(p, ' ') + 1; if (strncmp(p, "EOF", 3) == 0) l = 0; else l = atoi(p) - start + 1; if (off == start) { if (len != l) { fprintf(stderr, "Len %u should be %u: %s", (int)len, l, line); abort(); } if (type != rw) { fprintf(stderr, "Type %s wrong: %s", rw == F_RDLCK ? "READ" : "WRITE", line); abort(); } found = true; break; } } if (!found) { fprintf(stderr, "Unlock on %u@%u not found!\n", (int)off, (int)len); abort(); } fclose(locks); #endif #ifdef USE_TDB_MUTEX_LOCKING { int ret; if (tdb_mutex_unlock(tdb, rw, off, len, &ret)) { return ret; } } #endif fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; return fcntl(tdb->fd, F_SETLKW, &fl); } /* * Calculate the lock offset for a list * * list -1 is the freelist, otherwise a hash chain. * * Note that we consistently (but without real reason) lock hash chains at an * offset that is 4 bytes below the real offset of the corresponding list head * in the db. * * This is the memory layout of the hashchain array: * * FREELIST_TOP + 0 = freelist * FREELIST_TOP + 4 = hashtable list 0 * FREELIST_TOP + 8 = hashtable list 1 * ... * * Otoh lock_offset computes: * * freelist = FREELIST_TOP - 4 * list 0 = FREELIST_TOP + 0 * list 1 = FREELIST_TOP + 4 * ... * * Unfortunately we can't change this calculation in order to align the locking * offset with the memory layout, as that would make the locking incompatible * between different tdb versions. */ static tdb_off_t lock_offset(int list) { return FREELIST_TOP + 4*list; } /* a byte range locking function - return 0 on success this functions locks/unlocks "len" byte at the specified offset. On error, errno is also set so that errors are passed back properly through tdb_open(). note that a len of zero means lock to end of file */ int tdb_brlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len, enum tdb_lock_flags flags) { int ret; if (tdb->flags & TDB_NOLOCK) { return 0; } if (flags & TDB_LOCK_MARK_ONLY) { return 0; } if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { tdb->ecode = TDB_ERR_RDONLY; return -1; } do { ret = fcntl_lock(tdb, rw_type, offset, len, flags & TDB_LOCK_WAIT); /* Check for a sigalarm break. */ if (ret == -1 && errno == EINTR && tdb->interrupt_sig_ptr && *tdb->interrupt_sig_ptr) { break; } } while (ret == -1 && errno == EINTR); if (ret == -1) { tdb->ecode = TDB_ERR_LOCK; /* Generic lock error. errno set by fcntl. * EAGAIN is an expected return from non-blocking * locks. */ if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) { TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %u rw_type=%d flags=%d len=%zu\n", tdb->fd, offset, rw_type, flags, len)); } return -1; } return 0; } int tdb_brunlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len) { int ret; if (tdb->flags & TDB_NOLOCK) { return 0; } do { ret = fcntl_unlock(tdb, rw_type, offset, len); } while (ret == -1 && errno == EINTR); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %u rw_type=%u len=%zu\n", tdb->fd, offset, rw_type, len)); } return ret; } /* * Do a tdb_brlock in a loop. Some OSes (such as solaris) have too * conservative deadlock detection and claim a deadlock when progress can be * made. For those OSes we may loop for a while. */ static int tdb_brlock_retry(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len, enum tdb_lock_flags flags) { int count = 1000; while (count--) { struct timeval tv; int ret; ret = tdb_brlock(tdb, rw_type, offset, len, flags); if (ret == 0) { return 0; } if (errno != EDEADLK) { break; } /* sleep for as short a time as we can - more portable than usleep() */ tv.tv_sec = 0; tv.tv_usec = 1; select(0, NULL, NULL, NULL, &tv); } return -1; } /* upgrade a read lock to a write lock. */ int tdb_allrecord_upgrade(struct tdb_context *tdb) { int ret; if (tdb->allrecord_lock.count != 1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_allrecord_upgrade failed: count %u too high\n", tdb->allrecord_lock.count)); tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.off != 1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_allrecord_upgrade failed: already upgraded?\n")); tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb_have_mutexes(tdb)) { ret = tdb_mutex_allrecord_upgrade(tdb); if (ret == -1) { goto fail; } ret = tdb_brlock_retry(tdb, F_WRLCK, lock_offset(tdb->hash_size), 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE); if (ret == -1) { tdb_mutex_allrecord_downgrade(tdb); } } else { ret = tdb_brlock_retry(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE); } if (ret == 0) { tdb->allrecord_lock.ltype = F_WRLCK; tdb->allrecord_lock.off = 0; return 0; } fail: TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_allrecord_upgrade failed\n")); return -1; } static struct tdb_lock_type *find_nestlock(struct tdb_context *tdb, tdb_off_t offset) { int i; for (i=0; inum_lockrecs; i++) { if (tdb->lockrecs[i].off == offset) { return &tdb->lockrecs[i]; } } return NULL; } /* lock an offset in the database. */ int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, enum tdb_lock_flags flags) { struct tdb_lock_type *new_lck; if (offset >= lock_offset(tdb->hash_size)) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid offset %u for ltype=%d\n", offset, ltype)); return -1; } if (tdb->flags & TDB_NOLOCK) return 0; new_lck = find_nestlock(tdb, offset); if (new_lck) { if ((new_lck->ltype == F_RDLCK) && (ltype == F_WRLCK)) { if (!tdb_have_mutexes(tdb)) { int ret; /* * Upgrade the underlying fcntl * lock. Mutexes don't do readlocks, * so this only applies to fcntl * locking. */ ret = tdb_brlock(tdb, ltype, offset, 1, flags); if (ret != 0) { return ret; } } new_lck->ltype = F_WRLCK; } /* * Just increment the in-memory struct, posix locks * don't stack. */ new_lck->count++; return 0; } if (tdb->num_lockrecs == tdb->lockrecs_array_length) { new_lck = (struct tdb_lock_type *)realloc( tdb->lockrecs, sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); if (new_lck == NULL) { errno = ENOMEM; return -1; } tdb->lockrecs_array_length = tdb->num_lockrecs+1; tdb->lockrecs = new_lck; } /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ if (tdb_brlock(tdb, ltype, offset, 1, flags)) { return -1; } new_lck = &tdb->lockrecs[tdb->num_lockrecs]; new_lck->off = offset; new_lck->count = 1; new_lck->ltype = ltype; tdb->num_lockrecs++; return 0; } static int tdb_lock_and_recover(struct tdb_context *tdb) { int ret; /* We need to match locking order in transaction commit. */ if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT)) { return -1; } if (tdb_brlock(tdb, F_WRLCK, OPEN_LOCK, 1, TDB_LOCK_WAIT)) { tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); return -1; } ret = tdb_transaction_recover(tdb); tdb_brunlock(tdb, F_WRLCK, OPEN_LOCK, 1); tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); return ret; } static bool have_data_locks(const struct tdb_context *tdb) { int i; for (i = 0; i < tdb->num_lockrecs; i++) { if (tdb->lockrecs[i].off >= lock_offset(-1)) return true; } return false; } /* * A allrecord lock allows us to avoid per chain locks. Check if the allrecord * lock is strong enough. */ static int tdb_lock_covered_by_allrecord_lock(struct tdb_context *tdb, int ltype) { if (ltype == F_RDLCK) { /* * The allrecord_lock is equal (F_RDLCK) or stronger * (F_WRLCK). Pass. */ return 0; } if (tdb->allrecord_lock.ltype == F_RDLCK) { /* * We ask for ltype==F_WRLCK, but the allrecord_lock * is too weak. We can't upgrade here, so fail. */ tdb->ecode = TDB_ERR_LOCK; return -1; } /* * Asking for F_WRLCK, allrecord is F_WRLCK as well. Pass. */ return 0; } static int tdb_lock_list(struct tdb_context *tdb, int list, int ltype, enum tdb_lock_flags waitflag) { int ret; bool check = false; if (tdb->allrecord_lock.count) { return tdb_lock_covered_by_allrecord_lock(tdb, ltype); } /* * Check for recoveries: Someone might have kill -9'ed a process * during a commit. */ check = !have_data_locks(tdb); ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag); if (ret == 0 && check && tdb_needs_recovery(tdb)) { tdb_nest_unlock(tdb, lock_offset(list), ltype, false); if (tdb_lock_and_recover(tdb) == -1) { return -1; } return tdb_lock_list(tdb, list, ltype, waitflag); } return ret; } /* lock a list in the database. list -1 is the alloc list */ int tdb_lock(struct tdb_context *tdb, int list, int ltype) { int ret; ret = tdb_lock_list(tdb, list, ltype, TDB_LOCK_WAIT); if (ret) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " "ltype=%d (%s)\n", list, ltype, strerror(errno))); } return ret; } /* lock a list in the database. list -1 is the alloc list. non-blocking lock */ _PUBLIC_ int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) { return tdb_lock_list(tdb, list, ltype, TDB_LOCK_NOWAIT); } int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, bool mark_lock) { int ret = -1; struct tdb_lock_type *lck; if (tdb->flags & TDB_NOLOCK) return 0; /* Sanity checks */ if (offset >= lock_offset(tdb->hash_size)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: offset %u invalid (%d)\n", offset, tdb->hash_size)); return ret; } lck = find_nestlock(tdb, offset); if ((lck == NULL) || (lck->count == 0)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); return -1; } if (lck->count > 1) { lck->count--; return 0; } /* * This lock has count==1 left, so we need to unlock it in the * kernel. We don't bother with decrementing the in-memory array * element, we're about to overwrite it with the last array element * anyway. */ if (mark_lock) { ret = 0; } else { ret = tdb_brunlock(tdb, ltype, offset, 1); } /* * Shrink the array by overwriting the element just unlocked with the * last array element. */ *lck = tdb->lockrecs[--tdb->num_lockrecs]; /* * We don't bother with realloc when the array shrinks, but if we have * a completely idle tdb we should get rid of the locked array. */ if (ret) TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); return ret; } _PUBLIC_ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) { /* a global lock allows us to avoid per chain locks */ if (tdb->allrecord_lock.count) { return tdb_lock_covered_by_allrecord_lock(tdb, ltype); } return tdb_nest_unlock(tdb, lock_offset(list), ltype, false); } /* get the transaction lock */ int tdb_transaction_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags lockflags) { return tdb_nest_lock(tdb, TRANSACTION_LOCK, ltype, lockflags); } /* release the transaction lock */ int tdb_transaction_unlock(struct tdb_context *tdb, int ltype) { return tdb_nest_unlock(tdb, TRANSACTION_LOCK, ltype, false); } /* Returns 0 if all done, -1 if error, 1 if ok. */ static int tdb_allrecord_check(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable) { /* There are no locks on read-only dbs */ if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.count && tdb->allrecord_lock.ltype == (uint32_t)ltype) { tdb->allrecord_lock.count++; return 0; } if (tdb->allrecord_lock.count) { /* a global lock of a different type exists */ tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb_have_extra_locks(tdb)) { /* can't combine global and chain locks */ tdb->ecode = TDB_ERR_LOCK; return -1; } if (upgradable && ltype != F_RDLCK) { /* tdb error: you can't upgrade a write lock! */ tdb->ecode = TDB_ERR_LOCK; return -1; } return 1; } /* We only need to lock individual bytes, but Linux merges consecutive locks * so we lock in contiguous ranges. */ static int tdb_chainlock_gradual(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, size_t off, size_t len) { int ret; enum tdb_lock_flags nb_flags = (flags & ~TDB_LOCK_WAIT); if (len <= 4) { /* Single record. Just do blocking lock. */ return tdb_brlock(tdb, ltype, off, len, flags); } /* First we try non-blocking. */ ret = tdb_brlock(tdb, ltype, off, len, nb_flags); if (ret == 0) { return 0; } /* Try locking first half, then second. */ ret = tdb_chainlock_gradual(tdb, ltype, flags, off, len / 2); if (ret == -1) return -1; ret = tdb_chainlock_gradual(tdb, ltype, flags, off + len / 2, len - len / 2); if (ret == -1) { tdb_brunlock(tdb, ltype, off, len / 2); return -1; } return 0; } /* lock/unlock entire database. It can only be upgradable if you have some * other way of guaranteeing exclusivity (ie. transaction write lock). * We do the locking gradually to avoid being starved by smaller locks. */ int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable) { int ret; switch (tdb_allrecord_check(tdb, ltype, flags, upgradable)) { case -1: return -1; case 0: return 0; } /* We cover two kinds of locks: * 1) Normal chain locks. Taken for almost all operations. * 2) Individual records locks. Taken after normal or free * chain locks. * * It is (1) which cause the starvation problem, so we're only * gradual for that. */ if (tdb_have_mutexes(tdb)) { ret = tdb_mutex_allrecord_lock(tdb, ltype, flags); } else { ret = tdb_chainlock_gradual(tdb, ltype, flags, FREELIST_TOP, tdb->hash_size * 4); } if (ret == -1) { return -1; } /* Grab individual record locks. */ if (tdb_brlock(tdb, ltype, lock_offset(tdb->hash_size), 0, flags) == -1) { if (tdb_have_mutexes(tdb)) { tdb_mutex_allrecord_unlock(tdb); } else { tdb_brunlock(tdb, ltype, FREELIST_TOP, tdb->hash_size * 4); } return -1; } tdb->allrecord_lock.count = 1; /* If it's upgradable, it's actually exclusive so we can treat * it as a write lock. */ tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype; tdb->allrecord_lock.off = upgradable; if (tdb_needs_recovery(tdb)) { bool mark = flags & TDB_LOCK_MARK_ONLY; tdb_allrecord_unlock(tdb, ltype, mark); if (mark) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall_mark cannot do recovery\n")); return -1; } if (tdb_lock_and_recover(tdb) == -1) { return -1; } return tdb_allrecord_lock(tdb, ltype, flags, upgradable); } return 0; } /* unlock entire db */ int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock) { /* There are no locks on read-only dbs */ if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.count == 0) { tdb->ecode = TDB_ERR_LOCK; return -1; } /* Upgradable locks are marked as write locks. */ if (tdb->allrecord_lock.ltype != (uint32_t)ltype && (!tdb->allrecord_lock.off || ltype != F_RDLCK)) { tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.count > 1) { tdb->allrecord_lock.count--; return 0; } if (!mark_lock) { int ret; if (tdb_have_mutexes(tdb)) { ret = tdb_mutex_allrecord_unlock(tdb); if (ret == 0) { ret = tdb_brunlock(tdb, ltype, lock_offset(tdb->hash_size), 0); } } else { ret = tdb_brunlock(tdb, ltype, FREELIST_TOP, 0); } if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed " "(%s)\n", strerror(errno))); return -1; } } tdb->allrecord_lock.count = 0; tdb->allrecord_lock.ltype = 0; return 0; } /* lock entire database with write lock */ _PUBLIC_ int tdb_lockall(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall"); return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); } /* lock entire database with write lock - mark only */ _PUBLIC_ int tdb_lockall_mark(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_mark"); return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY, false); } /* unlock entire database with write lock - unmark only */ _PUBLIC_ int tdb_lockall_unmark(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_unmark"); return tdb_allrecord_unlock(tdb, F_WRLCK, true); } /* lock entire database with write lock - nonblocking varient */ _PUBLIC_ int tdb_lockall_nonblock(struct tdb_context *tdb) { int ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret); return ret; } /* unlock entire database with write lock */ _PUBLIC_ int tdb_unlockall(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_unlockall"); return tdb_allrecord_unlock(tdb, F_WRLCK, false); } /* lock entire database with read lock */ _PUBLIC_ int tdb_lockall_read(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_read"); return tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); } /* lock entire database with read lock - nonblock varient */ _PUBLIC_ int tdb_lockall_read_nonblock(struct tdb_context *tdb) { int ret = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_NOWAIT, false); tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret); return ret; } /* unlock entire database with read lock */ _PUBLIC_ int tdb_unlockall_read(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_unlockall_read"); return tdb_allrecord_unlock(tdb, F_RDLCK, false); } /* lock/unlock one hash chain. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ _PUBLIC_ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); tdb_trace_1rec(tdb, "tdb_chainlock", key); return ret; } /* lock/unlock one hash chain, non-blocking. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ _PUBLIC_ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret); return ret; } /* mark a chain as locked without actually locking it. Warning! use with great caution! */ _PUBLIC_ int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_nest_lock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), F_WRLCK, TDB_LOCK_MARK_ONLY); tdb_trace_1rec(tdb, "tdb_chainlock_mark", key); return ret; } /* unmark a chain as locked without actually locking it. Warning! use with great caution! */ _PUBLIC_ int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key); return tdb_nest_unlock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), F_WRLCK, true); } _PUBLIC_ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainunlock", key); return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } _PUBLIC_ int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) { int ret; ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); tdb_trace_1rec(tdb, "tdb_chainlock_read", key); return ret; } _PUBLIC_ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainunlock_read", key); return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); } _PUBLIC_ int tdb_chainlock_read_nonblock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); tdb_trace_1rec_ret(tdb, "tdb_chainlock_read_nonblock", key, ret); return ret; } /* record lock stops delete underneath */ int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) { if (tdb->allrecord_lock.count) { return 0; } return off ? tdb_brlock(tdb, F_RDLCK, off, 1, TDB_LOCK_WAIT) : 0; } /* Write locks override our own fcntl readlocks, so check it here. Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not an error to fail to get the lock here. */ int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off) { struct tdb_traverse_lock *i; if (tdb == NULL) { return -1; } for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) return -1; if (tdb->allrecord_lock.count) { if (tdb->allrecord_lock.ltype == F_WRLCK) { return 0; } return -1; } return tdb_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); } int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off) { if (tdb->allrecord_lock.count) { return 0; } return tdb_brunlock(tdb, F_WRLCK, off, 1); } /* fcntl locks don't stack: avoid unlocking someone else's */ int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) { struct tdb_traverse_lock *i; uint32_t count = 0; if (tdb->allrecord_lock.count) { return 0; } if (off == 0) return 0; for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) count++; return (count == 1 ? tdb_brunlock(tdb, F_RDLCK, off, 1) : 0); } bool tdb_have_extra_locks(struct tdb_context *tdb) { unsigned int extra = tdb->num_lockrecs; /* A transaction holds the lock for all records. */ if (!tdb->transaction && tdb->allrecord_lock.count) { return true; } /* We always hold the active lock if CLEAR_IF_FIRST. */ if (find_nestlock(tdb, ACTIVE_LOCK)) { extra--; } /* In a transaction, we expect to hold the transaction lock */ if (tdb->transaction && find_nestlock(tdb, TRANSACTION_LOCK)) { extra--; } return extra; } /* The transaction code uses this to remove all locks. */ void tdb_release_transaction_locks(struct tdb_context *tdb) { int i; unsigned int active = 0; if (tdb->allrecord_lock.count != 0) { tdb_allrecord_unlock(tdb, tdb->allrecord_lock.ltype, false); tdb->allrecord_lock.count = 0; } for (i=0;inum_lockrecs;i++) { struct tdb_lock_type *lck = &tdb->lockrecs[i]; /* Don't release the active lock! Copy it to first entry. */ if (lck->off == ACTIVE_LOCK) { tdb->lockrecs[active++] = *lck; } else { tdb_brunlock(tdb, lck->ltype, lck->off, 1); } } tdb->num_lockrecs = active; } /* Following functions are added specifically to support CTDB. */ /* Don't do actual fcntl locking, just mark tdb locked */ int tdb_transaction_write_lock_mark(struct tdb_context *tdb); _PUBLIC_ int tdb_transaction_write_lock_mark(struct tdb_context *tdb) { return tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY); } /* Don't do actual fcntl unlocking, just mark tdb unlocked */ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb); _PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb) { return tdb_nest_unlock(tdb, TRANSACTION_LOCK, F_WRLCK, true); } ldb-2.0.8/lib/tdb/common/mutex.c0000660000000000000000000005501013100601766016334 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. trivial database library Copyright (C) Volker Lendecke 2012,2013 Copyright (C) Stefan Metzmacher 2013,2014 Copyright (C) Michael Adam 2014 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" #include "system/threads.h" #ifdef USE_TDB_MUTEX_LOCKING /* * If we run with mutexes, we store the "struct tdb_mutexes" at the * beginning of the file. We store an additional tdb_header right * beyond the mutex area, page aligned. All the offsets within the tdb * are relative to the area behind the mutex area. tdb->map_ptr points * behind the mmap area as well, so the read and write path in the * mutex case can remain unchanged. * * Early in the mutex development the mutexes were placed between the hash * chain pointers and the real tdb data. This had two drawbacks: First, it * made pointer calculations more complex. Second, we had to mmap the mutex * area twice. One was the normal map_ptr in the tdb. This frequently changed * from within tdb_oob. At least the Linux glibc robust mutex code assumes * constant pointers in memory, so a constantly changing mmap area destroys * the mutex list. So we had to mmap the first bytes of the file with a second * mmap call. With that scheme, very weird errors happened that could be * easily fixed by doing the mutex mmap in a second file. It seemed that * mapping the same memory area twice does not end up in accessing the same * physical page, looking at the mutexes in gdb it seemed that old data showed * up after some re-mapping. To avoid a separate mutex file, the code now puts * the real content of the tdb file after the mutex area. This way we do not * have overlapping mmap areas, the mutex area is mmapped once and not * changed, the tdb data area's mmap is constantly changed but does not * overlap. */ struct tdb_mutexes { struct tdb_header hdr; /* protect allrecord_lock */ pthread_mutex_t allrecord_mutex; /* * F_UNLCK: free, * F_RDLCK: shared, * F_WRLCK: exclusive */ short int allrecord_lock; /* * Index 0 is the freelist mutex, followed by * one mutex per hashchain. */ pthread_mutex_t hashchains[1]; }; bool tdb_have_mutexes(struct tdb_context *tdb) { return ((tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) != 0); } size_t tdb_mutex_size(struct tdb_context *tdb) { size_t mutex_size; if (!tdb_have_mutexes(tdb)) { return 0; } mutex_size = sizeof(struct tdb_mutexes); mutex_size += tdb->hash_size * sizeof(pthread_mutex_t); return TDB_ALIGN(mutex_size, tdb->page_size); } /* * Get the index for a chain mutex */ static bool tdb_mutex_index(struct tdb_context *tdb, off_t off, off_t len, unsigned *idx) { /* * Weird but true: We fcntl lock 1 byte at an offset 4 bytes before * the 4 bytes of the freelist start and the hash chain that is about * to be locked. See lock_offset() where the freelist is -1 vs the * "+1" in TDB_HASH_TOP(). Because the mutex array is represented in * the tdb file itself as data, we need to adjust the offset here. */ const off_t freelist_lock_ofs = FREELIST_TOP - sizeof(tdb_off_t); if (!tdb_have_mutexes(tdb)) { return false; } if (len != 1) { /* Possibly the allrecord lock */ return false; } if (off < freelist_lock_ofs) { /* One of the special locks */ return false; } if (tdb->hash_size == 0) { /* tdb not initialized yet, called from tdb_open_ex() */ return false; } if (off >= TDB_DATA_START(tdb->hash_size)) { /* Single record lock from traverses */ return false; } /* * Now we know it's a freelist or hash chain lock. Those are always 4 * byte aligned. Paranoia check. */ if ((off % sizeof(tdb_off_t)) != 0) { abort(); } /* * Re-index the fcntl offset into an offset into the mutex array */ off -= freelist_lock_ofs; /* rebase to index 0 */ off /= sizeof(tdb_off_t); /* 0 for freelist 1-n for hashchain */ *idx = off; return true; } static bool tdb_have_mutex_chainlocks(struct tdb_context *tdb) { size_t i; for (i=0; i < tdb->num_lockrecs; i++) { bool ret; unsigned idx; ret = tdb_mutex_index(tdb, tdb->lockrecs[i].off, tdb->lockrecs[i].count, &idx); if (!ret) { continue; } if (idx == 0) { /* this is the freelist mutex */ continue; } return true; } return false; } static int chain_mutex_lock(pthread_mutex_t *m, bool waitflag) { int ret; if (waitflag) { ret = pthread_mutex_lock(m); } else { ret = pthread_mutex_trylock(m); } if (ret != EOWNERDEAD) { return ret; } /* * For chainlocks, we don't do any cleanup (yet?) */ return pthread_mutex_consistent(m); } static int allrecord_mutex_lock(struct tdb_mutexes *m, bool waitflag) { int ret; if (waitflag) { ret = pthread_mutex_lock(&m->allrecord_mutex); } else { ret = pthread_mutex_trylock(&m->allrecord_mutex); } if (ret != EOWNERDEAD) { return ret; } /* * The allrecord lock holder died. We need to reset the allrecord_lock * to F_UNLCK. This should also be the indication for * tdb_needs_recovery. */ m->allrecord_lock = F_UNLCK; return pthread_mutex_consistent(&m->allrecord_mutex); } bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, bool waitflag, int *pret) { struct tdb_mutexes *m = tdb->mutexes; pthread_mutex_t *chain; int ret; unsigned idx; bool allrecord_ok; if (!tdb_mutex_index(tdb, off, len, &idx)) { return false; } chain = &m->hashchains[idx]; again: ret = chain_mutex_lock(chain, waitflag); if (ret == EBUSY) { ret = EAGAIN; } if (ret != 0) { errno = ret; goto fail; } if (idx == 0) { /* * This is a freelist lock, which is independent to * the allrecord lock. So we're done once we got the * freelist mutex. */ *pret = 0; return true; } if (tdb_have_mutex_chainlocks(tdb)) { /* * We can only check the allrecord lock once. If we do it with * one chain mutex locked, we will deadlock with the allrecord * locker process in the following way: We lock the first hash * chain, we check for the allrecord lock. We keep the hash * chain locked. Then the allrecord locker locks the * allrecord_mutex. It walks the list of chain mutexes, * locking them all in sequence. Meanwhile, we have the chain * mutex locked, so the allrecord locker blocks trying to lock * our chain mutex. Then we come in and try to lock the second * chain lock, which in most cases will be the freelist. We * see that the allrecord lock is locked and put ourselves on * the allrecord_mutex. This will never be signalled though * because the allrecord locker waits for us to give up the * chain lock. */ *pret = 0; return true; } /* * Check if someone is has the allrecord lock: queue if so. */ allrecord_ok = false; if (m->allrecord_lock == F_UNLCK) { /* * allrecord lock not taken */ allrecord_ok = true; } if ((m->allrecord_lock == F_RDLCK) && (rw == F_RDLCK)) { /* * allrecord shared lock taken, but we only want to read */ allrecord_ok = true; } if (allrecord_ok) { *pret = 0; return true; } ret = pthread_mutex_unlock(chain); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(chain_mutex) failed: %s\n", strerror(ret))); errno = ret; goto fail; } ret = allrecord_mutex_lock(m, waitflag); if (ret == EBUSY) { ret = EAGAIN; } if (ret != 0) { if (waitflag || (ret != EAGAIN)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_%slock" "(allrecord_mutex) failed: %s\n", waitflag ? "" : "try_", strerror(ret))); } errno = ret; goto fail; } ret = pthread_mutex_unlock(&m->allrecord_mutex); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(allrecord_mutex) failed: %s\n", strerror(ret))); errno = ret; goto fail; } goto again; fail: *pret = -1; return true; } bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, int *pret) { struct tdb_mutexes *m = tdb->mutexes; pthread_mutex_t *chain; int ret; unsigned idx; if (!tdb_mutex_index(tdb, off, len, &idx)) { return false; } chain = &m->hashchains[idx]; ret = pthread_mutex_unlock(chain); if (ret == 0) { *pret = 0; return true; } errno = ret; *pret = -1; return true; } int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags) { struct tdb_mutexes *m = tdb->mutexes; int ret; uint32_t i; bool waitflag = (flags & TDB_LOCK_WAIT); int saved_errno; if (tdb->flags & TDB_NOLOCK) { return 0; } if (flags & TDB_LOCK_MARK_ONLY) { return 0; } ret = allrecord_mutex_lock(m, waitflag); if (!waitflag && (ret == EBUSY)) { errno = EAGAIN; tdb->ecode = TDB_ERR_LOCK; return -1; } if (ret != 0) { if (!(flags & TDB_LOCK_PROBE)) { TDB_LOG((tdb, TDB_DEBUG_TRACE, "allrecord_mutex_lock() failed: %s\n", strerror(ret))); } tdb->ecode = TDB_ERR_LOCK; return -1; } if (m->allrecord_lock != F_UNLCK) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); goto fail_unlock_allrecord_mutex; } m->allrecord_lock = (ltype == F_RDLCK) ? F_RDLCK : F_WRLCK; for (i=0; ihash_size; i++) { /* ignore hashchains[0], the freelist */ pthread_mutex_t *chain = &m->hashchains[i+1]; ret = chain_mutex_lock(chain, waitflag); if (!waitflag && (ret == EBUSY)) { errno = EAGAIN; goto fail_unroll_allrecord_lock; } if (ret != 0) { if (!(flags & TDB_LOCK_PROBE)) { TDB_LOG((tdb, TDB_DEBUG_TRACE, "chain_mutex_lock() failed: %s\n", strerror(ret))); } errno = ret; goto fail_unroll_allrecord_lock; } ret = pthread_mutex_unlock(chain); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(chainlock) failed: %s\n", strerror(ret))); errno = ret; goto fail_unroll_allrecord_lock; } } /* * We leave this routine with m->allrecord_mutex locked */ return 0; fail_unroll_allrecord_lock: m->allrecord_lock = F_UNLCK; fail_unlock_allrecord_mutex: saved_errno = errno; ret = pthread_mutex_unlock(&m->allrecord_mutex); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(allrecord_mutex) failed: %s\n", strerror(ret))); } errno = saved_errno; tdb->ecode = TDB_ERR_LOCK; return -1; } int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) { struct tdb_mutexes *m = tdb->mutexes; int ret; uint32_t i; if (tdb->flags & TDB_NOLOCK) { return 0; } /* * Our only caller tdb_allrecord_upgrade() * garantees that we already own the allrecord lock. * * Which means m->allrecord_mutex is still locked by us. */ if (m->allrecord_lock != F_RDLCK) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); return -1; } m->allrecord_lock = F_WRLCK; for (i=0; ihash_size; i++) { /* ignore hashchains[0], the freelist */ pthread_mutex_t *chain = &m->hashchains[i+1]; ret = chain_mutex_lock(chain, true); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_lock" "(chainlock) failed: %s\n", strerror(ret))); goto fail_unroll_allrecord_lock; } ret = pthread_mutex_unlock(chain); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(chainlock) failed: %s\n", strerror(ret))); goto fail_unroll_allrecord_lock; } } return 0; fail_unroll_allrecord_lock: m->allrecord_lock = F_RDLCK; tdb->ecode = TDB_ERR_LOCK; return -1; } void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) { struct tdb_mutexes *m = tdb->mutexes; /* * Our only caller tdb_allrecord_upgrade() (in the error case) * garantees that we already own the allrecord lock. * * Which means m->allrecord_mutex is still locked by us. */ if (m->allrecord_lock != F_WRLCK) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); return; } m->allrecord_lock = F_RDLCK; return; } int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) { struct tdb_mutexes *m = tdb->mutexes; short old; int ret; if (tdb->flags & TDB_NOLOCK) { return 0; } /* * Our only callers tdb_allrecord_unlock() and * tdb_allrecord_lock() (in the error path) * garantee that we already own the allrecord lock. * * Which means m->allrecord_mutex is still locked by us. */ if ((m->allrecord_lock != F_RDLCK) && (m->allrecord_lock != F_WRLCK)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); return -1; } old = m->allrecord_lock; m->allrecord_lock = F_UNLCK; ret = pthread_mutex_unlock(&m->allrecord_mutex); if (ret != 0) { m->allrecord_lock = old; TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(allrecord_mutex) failed: %s\n", strerror(ret))); return -1; } return 0; } int tdb_mutex_init(struct tdb_context *tdb) { struct tdb_mutexes *m; pthread_mutexattr_t ma; int i, ret; ret = tdb_mutex_mmap(tdb); if (ret == -1) { return -1; } m = tdb->mutexes; ret = pthread_mutexattr_init(&ma); if (ret != 0) { goto fail_munmap; } ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { goto fail; } ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); if (ret != 0) { goto fail; } ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); if (ret != 0) { goto fail; } for (i=0; ihash_size+1; i++) { pthread_mutex_t *chain = &m->hashchains[i]; ret = pthread_mutex_init(chain, &ma); if (ret != 0) { goto fail; } } m->allrecord_lock = F_UNLCK; ret = pthread_mutex_init(&m->allrecord_mutex, &ma); if (ret != 0) { goto fail; } ret = 0; fail: pthread_mutexattr_destroy(&ma); fail_munmap: if (ret == 0) { return 0; } tdb_mutex_munmap(tdb); errno = ret; return -1; } int tdb_mutex_mmap(struct tdb_context *tdb) { size_t len; void *ptr; len = tdb_mutex_size(tdb); if (len == 0) { return 0; } if (tdb->mutexes != NULL) { return 0; } ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE, tdb->fd, 0); if (ptr == MAP_FAILED) { return -1; } tdb->mutexes = (struct tdb_mutexes *)ptr; return 0; } int tdb_mutex_munmap(struct tdb_context *tdb) { size_t len; int ret; len = tdb_mutex_size(tdb); if (len == 0) { return 0; } ret = munmap(tdb->mutexes, len); if (ret == -1) { return -1; } tdb->mutexes = NULL; return 0; } static bool tdb_mutex_locking_cached; static bool tdb_mutex_locking_supported(void) { pthread_mutexattr_t ma; pthread_mutex_t m; int ret; static bool initialized; if (initialized) { return tdb_mutex_locking_cached; } initialized = true; ret = pthread_mutexattr_init(&ma); if (ret != 0) { return false; } ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutex_init(&m, &ma); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutex_lock(&m); if (ret != 0) { goto cleanup_m; } /* * This makes sure we have real mutexes * from a threading library instead of just * stubs from libc. */ ret = pthread_mutex_lock(&m); if (ret != EDEADLK) { goto cleanup_lock; } ret = pthread_mutex_unlock(&m); if (ret != 0) { goto cleanup_m; } tdb_mutex_locking_cached = true; goto cleanup_m; cleanup_lock: pthread_mutex_unlock(&m); cleanup_m: pthread_mutex_destroy(&m); cleanup_ma: pthread_mutexattr_destroy(&ma); return tdb_mutex_locking_cached; } static void (*tdb_robust_mutext_old_handler)(int) = SIG_ERR; static pid_t tdb_robust_mutex_pid = -1; static bool tdb_robust_mutex_setup_sigchild(void (*handler)(int), void (**p_old_handler)(int)) { #ifdef HAVE_SIGACTION struct sigaction act; struct sigaction oldact; memset(&act, '\0', sizeof(act)); act.sa_handler = handler; #ifdef SA_RESTART act.sa_flags = SA_RESTART; #endif sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGCHLD); sigaction(SIGCHLD, &act, &oldact); if (p_old_handler) { *p_old_handler = oldact.sa_handler; } return true; #else /* !HAVE_SIGACTION */ return false; #endif } static void tdb_robust_mutex_handler(int sig) { pid_t child_pid = tdb_robust_mutex_pid; if (child_pid != -1) { pid_t pid; pid = waitpid(child_pid, NULL, WNOHANG); if (pid == -1) { switch (errno) { case ECHILD: tdb_robust_mutex_pid = -1; return; default: return; } } if (pid == child_pid) { tdb_robust_mutex_pid = -1; return; } } if (tdb_robust_mutext_old_handler == SIG_DFL) { return; } if (tdb_robust_mutext_old_handler == SIG_IGN) { return; } if (tdb_robust_mutext_old_handler == SIG_ERR) { return; } tdb_robust_mutext_old_handler(sig); } static void tdb_robust_mutex_wait_for_child(pid_t *child_pid) { int options = WNOHANG; if (*child_pid == -1) { return; } while (tdb_robust_mutex_pid > 0) { pid_t pid; /* * First we try with WNOHANG, as the process might not exist * anymore. Once we've sent SIGKILL we block waiting for the * exit. */ pid = waitpid(*child_pid, NULL, options); if (pid == -1) { if (errno == EINTR) { continue; } else if (errno == ECHILD) { break; } else { abort(); } } if (pid == *child_pid) { break; } kill(*child_pid, SIGKILL); options = 0; } tdb_robust_mutex_pid = -1; *child_pid = -1; } _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) { void *ptr = NULL; pthread_mutex_t *m = NULL; pthread_mutexattr_t ma; int ret = 1; int pipe_down[2] = { -1, -1 }; int pipe_up[2] = { -1, -1 }; ssize_t nread; char c = 0; bool ok; static bool initialized; pid_t saved_child_pid = -1; bool cleanup_ma = false; if (initialized) { return tdb_mutex_locking_cached; } initialized = true; ok = tdb_mutex_locking_supported(); if (!ok) { return false; } tdb_mutex_locking_cached = false; ptr = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1 /* fd */, 0); if (ptr == MAP_FAILED) { return false; } ret = pipe(pipe_down); if (ret != 0) { goto cleanup; } ret = pipe(pipe_up); if (ret != 0) { goto cleanup; } ret = pthread_mutexattr_init(&ma); if (ret != 0) { goto cleanup; } cleanup_ma = true; ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { goto cleanup; } ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); if (ret != 0) { goto cleanup; } ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); if (ret != 0) { goto cleanup; } ret = pthread_mutex_init(ptr, &ma); if (ret != 0) { goto cleanup; } m = (pthread_mutex_t *)ptr; if (tdb_robust_mutex_setup_sigchild(tdb_robust_mutex_handler, &tdb_robust_mutext_old_handler) == false) { goto cleanup; } tdb_robust_mutex_pid = fork(); saved_child_pid = tdb_robust_mutex_pid; if (tdb_robust_mutex_pid == 0) { size_t nwritten; close(pipe_down[1]); close(pipe_up[0]); ret = pthread_mutex_lock(m); nwritten = write(pipe_up[1], &ret, sizeof(ret)); if (nwritten != sizeof(ret)) { _exit(1); } if (ret != 0) { _exit(1); } nread = read(pipe_down[0], &c, 1); if (nread != 1) { _exit(1); } /* leave locked */ _exit(0); } if (tdb_robust_mutex_pid == -1) { goto cleanup; } close(pipe_down[0]); pipe_down[0] = -1; close(pipe_up[1]); pipe_up[1] = -1; nread = read(pipe_up[0], &ret, sizeof(ret)); if (nread != sizeof(ret)) { goto cleanup; } ret = pthread_mutex_trylock(m); if (ret != EBUSY) { if (ret == 0) { pthread_mutex_unlock(m); } goto cleanup; } if (write(pipe_down[1], &c, 1) != 1) { goto cleanup; } nread = read(pipe_up[0], &c, 1); if (nread != 0) { goto cleanup; } tdb_robust_mutex_wait_for_child(&saved_child_pid); ret = pthread_mutex_trylock(m); if (ret != EOWNERDEAD) { if (ret == 0) { pthread_mutex_unlock(m); } goto cleanup; } ret = pthread_mutex_consistent(m); if (ret != 0) { goto cleanup; } ret = pthread_mutex_trylock(m); if (ret != EDEADLK && ret != EBUSY) { pthread_mutex_unlock(m); goto cleanup; } ret = pthread_mutex_unlock(m); if (ret != 0) { goto cleanup; } tdb_mutex_locking_cached = true; cleanup: /* * Note that we don't reset the signal handler we just reset * tdb_robust_mutex_pid to -1. This is ok as this code path is only * called once per process. * * Leaving our signal handler avoids races with other threads potentialy * setting up their SIGCHLD handlers. * * The worst thing that can happen is that the other newer signal * handler will get the SIGCHLD signal for our child and/or reap the * child with a wait() function. tdb_robust_mutex_wait_for_child() * handles the case where waitpid returns ECHILD. */ tdb_robust_mutex_wait_for_child(&saved_child_pid); if (m != NULL) { pthread_mutex_destroy(m); } if (cleanup_ma) { pthread_mutexattr_destroy(&ma); } if (pipe_down[0] != -1) { close(pipe_down[0]); } if (pipe_down[1] != -1) { close(pipe_down[1]); } if (pipe_up[0] != -1) { close(pipe_up[0]); } if (pipe_up[1] != -1) { close(pipe_up[1]); } if (ptr != NULL) { munmap(ptr, sizeof(pthread_mutex_t)); } return tdb_mutex_locking_cached; } #else size_t tdb_mutex_size(struct tdb_context *tdb) { return 0; } bool tdb_have_mutexes(struct tdb_context *tdb) { return false; } int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags) { tdb->ecode = TDB_ERR_LOCK; return -1; } int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) { return -1; } int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) { tdb->ecode = TDB_ERR_LOCK; return -1; } void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) { return; } int tdb_mutex_mmap(struct tdb_context *tdb) { errno = ENOSYS; return -1; } int tdb_mutex_munmap(struct tdb_context *tdb) { errno = ENOSYS; return -1; } int tdb_mutex_init(struct tdb_context *tdb) { errno = ENOSYS; return -1; } _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) { return false; } #endif ldb-2.0.8/lib/tdb/common/open.c0000660000000000000000000006055013573675413016156 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ static struct tdb_context *tdbs = NULL; /* We use two hashes to double-check they're using the right hash function. */ void tdb_header_hash(struct tdb_context *tdb, uint32_t *magic1_hash, uint32_t *magic2_hash) { TDB_DATA hash_key; uint32_t tdb_magic = TDB_MAGIC; hash_key.dptr = discard_const_p(unsigned char, TDB_MAGIC_FOOD); hash_key.dsize = sizeof(TDB_MAGIC_FOOD); *magic1_hash = tdb->hash_fn(&hash_key); hash_key.dptr = (unsigned char *)CONVERT(tdb_magic); hash_key.dsize = sizeof(tdb_magic); *magic2_hash = tdb->hash_fn(&hash_key); /* Make sure at least one hash is non-zero! */ if (*magic1_hash == 0 && *magic2_hash == 0) *magic1_hash = 1; } /* initialise a new database with a specified hash size */ static int tdb_new_database(struct tdb_context *tdb, struct tdb_header *header, int hash_size) { struct tdb_header *newdb; size_t size; int ret = -1; /* We make it up in memory, then write it out if not internal */ size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t); if (!(newdb = (struct tdb_header *)calloc(size, 1))) { tdb->ecode = TDB_ERR_OOM; return -1; } /* Fill in the header */ newdb->version = TDB_VERSION; newdb->hash_size = hash_size; tdb_header_hash(tdb, &newdb->magic1_hash, &newdb->magic2_hash); /* Make sure older tdbs (which don't check the magic hash fields) * will refuse to open this TDB. */ if (tdb->flags & TDB_INCOMPATIBLE_HASH) newdb->rwlocks = TDB_HASH_RWLOCK_MAGIC; /* * We create a tdb with TDB_FEATURE_FLAG_MUTEX support, * the flag combination and runtime feature checks * are done by the caller already. */ if (tdb->flags & TDB_MUTEX_LOCKING) { newdb->feature_flags |= TDB_FEATURE_FLAG_MUTEX; } /* * If we have any features we add the FEATURE_FLAG_MAGIC, overwriting the * TDB_HASH_RWLOCK_MAGIC above. */ if (newdb->feature_flags != 0) { newdb->rwlocks = TDB_FEATURE_FLAG_MAGIC; } /* * It's required for some following code pathes * to have the fields on 'tdb' up-to-date. * * E.g. tdb_mutex_size() requires it */ tdb->feature_flags = newdb->feature_flags; tdb->hash_size = newdb->hash_size; if (tdb->flags & TDB_INTERNAL) { tdb->map_size = size; tdb->map_ptr = (char *)newdb; memcpy(header, newdb, sizeof(*header)); /* Convert the `ondisk' version if asked. */ CONVERT(*newdb); return 0; } if (lseek(tdb->fd, 0, SEEK_SET) == -1) goto fail; if (ftruncate(tdb->fd, 0) == -1) goto fail; if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { newdb->mutex_size = tdb_mutex_size(tdb); tdb->hdr_ofs = newdb->mutex_size; } /* This creates an endian-converted header, as if read from disk */ CONVERT(*newdb); memcpy(header, newdb, sizeof(*header)); /* Don't endian-convert the magic food! */ memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); if (!tdb_write_all(tdb->fd, newdb, size)) goto fail; if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { /* * Now we init the mutex area * followed by a second header. */ ret = ftruncate( tdb->fd, newdb->mutex_size + sizeof(struct tdb_header)); if (ret == -1) { goto fail; } ret = tdb_mutex_init(tdb); if (ret == -1) { goto fail; } /* * Write a second header behind the mutexes. That's the area * that will be mmapp'ed. */ ret = lseek(tdb->fd, newdb->mutex_size, SEEK_SET); if (ret == -1) { goto fail; } if (!tdb_write_all(tdb->fd, newdb, size)) { goto fail; } } ret = 0; fail: SAFE_FREE(newdb); return ret; } static int tdb_already_open(dev_t device, ino_t ino) { struct tdb_context *i; for (i = tdbs; i; i = i->next) { if (i->device == device && i->inode == ino) { return 1; } } return 0; } /* open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the database file. A flags value of O_WRONLY is invalid. The hash size is advisory, use zero for a default value. Return is NULL on error, in which case errno is also set. Don't try to call tdb_error or tdb_errname, just do strerror(errno). @param name may be NULL for internal databases. */ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); } /* a default logging function */ static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { } static bool check_header_hash(struct tdb_context *tdb, struct tdb_header *header, bool default_hash, uint32_t *m1, uint32_t *m2) { tdb_header_hash(tdb, m1, m2); if (header->magic1_hash == *m1 && header->magic2_hash == *m2) { return true; } /* If they explicitly set a hash, always respect it. */ if (!default_hash) return false; /* Otherwise, try the other inbuilt hash. */ if (tdb->hash_fn == tdb_old_hash) tdb->hash_fn = tdb_jenkins_hash; else tdb->hash_fn = tdb_old_hash; return check_header_hash(tdb, header, false, m1, m2); } static bool tdb_mutex_open_ok(struct tdb_context *tdb, const struct tdb_header *header) { if (tdb->flags & TDB_NOLOCK) { /* * We don't look at locks, so it does not matter to have a * compatible mutex implementation. Allow the open. */ return true; } if (!(tdb->flags & TDB_MUTEX_LOCKING)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " "Can use mutexes only with " "MUTEX_LOCKING or NOLOCK\n", tdb->name)); return false; } if (tdb_mutex_size(tdb) != header->mutex_size) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " "Mutex size changed from %"PRIu32" to %zu\n.", tdb->name, header->mutex_size, tdb_mutex_size(tdb))); return false; } return true; } _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn) { int orig_errno = errno; struct tdb_header header = { .version = 0, }; struct tdb_context *tdb; struct stat st; int rev = 0; bool locked = false; unsigned char *vp; uint32_t vertest; unsigned v; const char *hash_alg; uint32_t magic1, magic2; int ret; if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { /* Can't log this */ errno = ENOMEM; goto fail; } tdb_io_init(tdb); if (tdb_flags & TDB_INTERNAL) { tdb_flags |= TDB_INCOMPATIBLE_HASH; } if (tdb_flags & TDB_MUTEX_LOCKING) { tdb_flags |= TDB_INCOMPATIBLE_HASH; } tdb->fd = -1; #ifdef TDB_TRACE tdb->tracefd = -1; #endif tdb->name = NULL; tdb->map_ptr = NULL; tdb->flags = tdb_flags; tdb->open_flags = open_flags; if (log_ctx) { tdb->log = *log_ctx; } else { tdb->log.log_fn = null_log_fn; tdb->log.log_private = NULL; } if (name == NULL && (tdb_flags & TDB_INTERNAL)) { name = "__TDB_INTERNAL__"; } if (name == NULL) { tdb->name = discard_const_p(char, "__NULL__"); TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n")); tdb->name = NULL; errno = EINVAL; goto fail; } /* now make a copy of the name, as the caller memory might go away */ if (!(tdb->name = (char *)strdup(name))) { /* * set the name as the given string, so that tdb_name() will * work in case of an error. */ tdb->name = discard_const_p(char, name); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n", name)); tdb->name = NULL; errno = ENOMEM; goto fail; } if (hash_fn) { tdb->hash_fn = hash_fn; hash_alg = "the user defined"; } else { /* This controls what we use when creating a tdb. */ if (tdb->flags & TDB_INCOMPATIBLE_HASH) { tdb->hash_fn = tdb_jenkins_hash; } else { tdb->hash_fn = tdb_old_hash; } hash_alg = "either default"; } /* cache the page size */ tdb->page_size = getpagesize(); if (tdb->page_size <= 0) { tdb->page_size = 0x2000; } tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0; if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", name)); errno = EINVAL; goto fail; } if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE; if ((open_flags & O_ACCMODE) == O_RDONLY) { tdb->read_only = 1; /* read only databases don't do locking or clear if first */ tdb->flags |= TDB_NOLOCK; tdb->flags &= ~(TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING); } if ((tdb->flags & TDB_ALLOW_NESTING) && (tdb->flags & TDB_DISALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "allow_nesting and disallow_nesting are not allowed together!")); errno = EINVAL; goto fail; } if (tdb->flags & TDB_MUTEX_LOCKING) { /* * Here we catch bugs in the callers, * the runtime check for existing tdb's comes later. */ if (tdb->flags & TDB_INTERNAL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING and " "TDB_INTERNAL are not allowed together\n", name)); errno = EINVAL; goto fail; } if (tdb->flags & TDB_NOMMAP) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING and " "TDB_NOMMAP are not allowed together\n", name)); errno = EINVAL; goto fail; } if (tdb->read_only) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING " "not allowed read only\n", name)); errno = EINVAL; goto fail; } /* * The callers should have called * tdb_runtime_check_for_robust_mutexes() * before using TDB_MUTEX_LOCKING! * * This makes sure the caller understands * that the locking may behave a bit differently * than with pure fcntl locking. E.g. multiple * read locks are not supported. */ if (!tdb_runtime_check_for_robust_mutexes()) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING " "requires support for robust_mutexes\n", name)); errno = ENOSYS; goto fail; } } if (getenv("TDB_NO_FSYNC")) { tdb->flags |= TDB_NOSYNC; } /* * TDB_ALLOW_NESTING is the default behavior. * Note: this may change in future versions! */ if (!(tdb->flags & TDB_DISALLOW_NESTING)) { tdb->flags |= TDB_ALLOW_NESTING; } /* internal databases don't mmap or lock, and start off cleared */ if (tdb->flags & TDB_INTERNAL) { tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); tdb->flags &= ~TDB_CLEAR_IF_FIRST; if (tdb_new_database(tdb, &header, hash_size) != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!")); goto fail; } tdb->hash_size = hash_size; goto internal; } if ((tdb->fd = open(name, open_flags, mode)) == -1) { TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n", name, strerror(errno))); goto fail; /* errno set by open(2) */ } /* on exec, don't inherit the fd */ v = fcntl(tdb->fd, F_GETFD, 0); fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); /* ensure there is only one process initialising at once */ if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n", name, strerror(errno))); goto fail; /* errno set by tdb_brlock */ } /* we need to zero database if we are the only one with it open */ if ((tdb_flags & TDB_CLEAR_IF_FIRST) && (!tdb->read_only)) { ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); locked = (ret == 0); if (locked) { ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "tdb_brlock failed for %s: %s\n", name, strerror(errno))); goto fail; } ret = tdb_new_database(tdb, &header, hash_size); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "tdb_new_database failed for " "%s: %s\n", name, strerror(errno))); tdb_unlockall(tdb); goto fail; } ret = tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "tdb_unlockall failed for %s: %s\n", name, strerror(errno))); goto fail; } ret = lseek(tdb->fd, 0, SEEK_SET); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "lseek failed for %s: %s\n", name, strerror(errno))); goto fail; } } } errno = 0; if (read(tdb->fd, &header, sizeof(header)) != sizeof(header) || strcmp(header.magic_food, TDB_MAGIC_FOOD) != 0) { if (!(open_flags & O_CREAT) || tdb_new_database(tdb, &header, hash_size) == -1) { if (errno == 0) { errno = EIO; /* ie bad format or something */ } goto fail; } rev = (tdb->flags & TDB_CONVERT); } else if (header.version != TDB_VERSION && !(rev = (header.version==TDB_BYTEREV(TDB_VERSION)))) { /* wrong version */ errno = EIO; goto fail; } vp = (unsigned char *)&header.version; vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; if (!rev) tdb->flags &= ~TDB_CONVERT; else { tdb->flags |= TDB_CONVERT; tdb_convert(&header, sizeof(header)); } /* * We only use st.st_dev and st.st_ino from the raw fstat() * call, everything else needs to use tdb_fstat() in order * to skip tdb->hdr_ofs! */ if (fstat(tdb->fd, &st) == -1) { goto fail; } tdb->device = st.st_dev; tdb->inode = st.st_ino; ZERO_STRUCT(st); if (header.rwlocks != 0 && header.rwlocks != TDB_FEATURE_FLAG_MAGIC && header.rwlocks != TDB_HASH_RWLOCK_MAGIC) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n")); errno = ENOSYS; goto fail; } if (header.hash_size == 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: invalid database: 0 hash_size\n")); errno = ENOSYS; goto fail; } tdb->hash_size = header.hash_size; if (header.rwlocks == TDB_FEATURE_FLAG_MAGIC) { tdb->feature_flags = header.feature_flags; } if (tdb->feature_flags & ~TDB_SUPPORTED_FEATURE_FLAGS) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: unsupported " "features in tdb %s: 0x%08x (supported: 0x%08x)\n", name, (unsigned)tdb->feature_flags, (unsigned)TDB_SUPPORTED_FEATURE_FLAGS)); errno = ENOSYS; goto fail; } if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { if (!tdb_mutex_open_ok(tdb, &header)) { errno = EINVAL; goto fail; } /* * We need to remember the hdr_ofs * also for the TDB_NOLOCK case * if the current library doesn't support * mutex locking. */ tdb->hdr_ofs = header.mutex_size; if ((!(tdb_flags & TDB_CLEAR_IF_FIRST)) && (!tdb->read_only)) { /* * Open an existing mutexed tdb, but without * CLEAR_IF_FIRST. We need to initialize the * mutex array and keep the CLEAR_IF_FIRST * lock locked. */ ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); locked = (ret == 0); if (locked) { ret = tdb_mutex_init(tdb); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: tdb_mutex_init " "failed for ""%s: %s\n", name, strerror(errno))); goto fail; } } } } if ((header.magic1_hash == 0) && (header.magic2_hash == 0)) { /* older TDB without magic hash references */ tdb->hash_fn = tdb_old_hash; } else if (!check_header_hash(tdb, &header, !hash_fn, &magic1, &magic2)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "%s was not created with %s hash function we are using\n" "magic1_hash[0x%08X %s 0x%08X] " "magic2_hash[0x%08X %s 0x%08X]\n", name, hash_alg, header.magic1_hash, (header.magic1_hash == magic1) ? "==" : "!=", magic1, header.magic2_hash, (header.magic2_hash == magic2) ? "==" : "!=", magic2)); errno = EINVAL; goto fail; } /* Is it already in the open list? If so, fail. */ if (tdb_already_open(tdb->device, tdb->inode)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "%s (%d,%d) is already open in this process\n", name, (int)tdb->device, (int)tdb->inode)); errno = EBUSY; goto fail; } /* * We had tdb_mmap(tdb) here before, * but we need to use tdb_fstat(), * which is triggered from tdb_oob() before calling tdb_mmap(). * As this skips tdb->hdr_ofs. */ tdb->map_size = 0; ret = tdb_oob(tdb, 0, 1, 0); if (ret == -1) { errno = EIO; goto fail; } if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { if (!(tdb->flags & TDB_NOLOCK)) { ret = tdb_mutex_mmap(tdb); if (ret != 0) { goto fail; } } } 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_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: " "failed to release ACTIVE_LOCK on %s: %s\n", name, strerror(errno))); goto fail; } } if (locked || (tdb_flags & TDB_CLEAR_IF_FIRST)) { /* * We always need to do this if the CLEAR_IF_FIRST * flag is set, even if we didn't get the initial * exclusive lock as we need to let all other users * know we're using it. */ ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT); if (ret == -1) { goto fail; } } /* if needed, run recovery */ if (tdb_transaction_recover(tdb) == -1) { goto fail; } #ifdef TDB_TRACE { char tracefile[strlen(name) + 32]; snprintf(tracefile, sizeof(tracefile), "%s.trace.%li", name, (long)getpid()); tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600); if (tdb->tracefd >= 0) { tdb_enable_seqnum(tdb); tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags, open_flags); } else TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile)); } #endif internal: /* Internal (memory-only) databases skip all the code above to * do with disk files, and resume here by releasing their * open lock and hooking into the active list. */ if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) { goto fail; } tdb->next = tdbs; tdbs = tdb; errno = orig_errno; return tdb; fail: { int save_errno = errno; if (!tdb) return NULL; #ifdef TDB_TRACE close(tdb->tracefd); #endif if (tdb->map_ptr) { if (tdb->flags & TDB_INTERNAL) SAFE_FREE(tdb->map_ptr); else tdb_munmap(tdb); } if (tdb->fd != -1) if (close(tdb->fd) != 0) TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); SAFE_FREE(tdb->lockrecs); SAFE_FREE(tdb->name); SAFE_FREE(tdb); errno = save_errno; return NULL; } } /* * Set the maximum number of dead records per hash chain */ _PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) { tdb->max_dead_records = max_dead; } /** * Close a database. * * @returns -1 for error; 0 for success. **/ _PUBLIC_ int tdb_close(struct tdb_context *tdb) { struct tdb_context **i; int ret = 0; if (tdb->transaction) { tdb_transaction_cancel(tdb); } tdb_trace(tdb, "tdb_close"); if (tdb->map_ptr) { if (tdb->flags & TDB_INTERNAL) SAFE_FREE(tdb->map_ptr); else tdb_munmap(tdb); } tdb_mutex_munmap(tdb); SAFE_FREE(tdb->name); if (tdb->fd != -1) { ret = close(tdb->fd); tdb->fd = -1; } SAFE_FREE(tdb->lockrecs); /* Remove from contexts list */ for (i = &tdbs; *i; i = &(*i)->next) { if (*i == tdb) { *i = tdb->next; break; } } #ifdef TDB_TRACE close(tdb->tracefd); #endif memset(tdb, 0, sizeof(*tdb)); SAFE_FREE(tdb); return ret; } /* register a loging function */ _PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx) { tdb->log = *log_ctx; } _PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb) { return tdb->log.log_private; } static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) { #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ !defined(LIBREPLACE_PWRITE_NOT_REPLACED) struct stat st; #endif if (tdb->flags & TDB_INTERNAL) { return 0; /* Nothing to do. */ } if (tdb_have_extra_locks(tdb)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n")); goto fail; } if (tdb->transaction != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n")); goto fail; } /* If we have real pread & pwrite, we can skip reopen. */ #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ !defined(LIBREPLACE_PWRITE_NOT_REPLACED) if (tdb_munmap(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); goto fail; } if (close(tdb->fd) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n")); tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); if (tdb->fd == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno))); goto fail; } /* * We only use st.st_dev and st.st_ino from the raw fstat() * call, everything else needs to use tdb_fstat() in order * to skip tdb->hdr_ofs! */ if (fstat(tdb->fd, &st) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); goto fail; } if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); goto fail; } ZERO_STRUCT(st); /* * We had tdb_mmap(tdb) here before, * but we need to use tdb_fstat(), * which is triggered from tdb_oob() before calling tdb_mmap(). * As this skips tdb->hdr_ofs. */ tdb->map_size = 0; if (tdb_oob(tdb, 0, 1, 0) != 0) { goto fail; } #endif /* fake pread or pwrite */ /* We may still think we hold the active lock. */ tdb->num_lockrecs = 0; SAFE_FREE(tdb->lockrecs); tdb->lockrecs_array_length = 0; if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n")); goto fail; } return 0; fail: tdb_close(tdb); return -1; } /* reopen a tdb - this can be used after a fork to ensure that we have an independent seek pointer from our parent and to re-establish locks */ _PUBLIC_ int tdb_reopen(struct tdb_context *tdb) { bool active_lock; active_lock = (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); return tdb_reopen_internal(tdb, active_lock); } /* reopen all tdb's */ _PUBLIC_ int tdb_reopen_all(int parent_longlived) { struct tdb_context *tdb; for (tdb=tdbs; tdb; tdb = tdb->next) { bool active_lock; active_lock = (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); /* * If the parent is longlived (ie. a * parent daemon architecture), we know * it will keep it's active lock on a * tdb opened with CLEAR_IF_FIRST. Thus * for child processes we don't have to * add an active lock. This is essential * to improve performance on systems that * keep POSIX locks as a non-scalable data * structure in the kernel. */ if (parent_longlived) { /* Ensure no clear-if-first. */ active_lock = false; } if (tdb_reopen_internal(tdb, active_lock) != 0) return -1; } return 0; } ldb-2.0.8/lib/tdb/common/rescue.c0000660000000000000000000002012113573675413016471 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library, rescue attempt code. Copyright (C) Rusty Russell 2012 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" #include struct found { tdb_off_t head; /* 0 -> invalid. */ struct tdb_record rec; TDB_DATA key; bool in_hash; bool in_free; }; struct found_table { /* As an ordered array (by head offset). */ struct found *arr; unsigned int num, max; }; static bool looks_like_valid_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec, TDB_DATA *key) { unsigned int hval; if (rec->magic != TDB_MAGIC) return false; if (rec->key_len + rec->data_len > rec->rec_len) return false; if (rec->rec_len % TDB_ALIGNMENT) return false; /* Next pointer must make some sense. */ if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)) return false; if (tdb_oob(tdb, rec->next, sizeof(*rec), 1)) return false; key->dsize = rec->key_len; key->dptr = tdb_alloc_read(tdb, off + sizeof(*rec), key->dsize); if (!key->dptr) return false; hval = tdb->hash_fn(key); if (hval != rec->full_hash) { free(key->dptr); return false; } /* Caller frees up key->dptr */ return true; } static bool add_to_table(struct found_table *found, tdb_off_t off, struct tdb_record *rec, TDB_DATA key) { if (found->num + 1 > found->max) { struct found *new; found->max = (found->max ? found->max * 2 : 128); new = realloc(found->arr, found->max * sizeof(found->arr[0])); if (!new) return false; found->arr = new; } found->arr[found->num].head = off; found->arr[found->num].rec = *rec; found->arr[found->num].key = key; found->arr[found->num].in_hash = false; found->arr[found->num].in_free = false; found->num++; return true; } static bool walk_record(struct tdb_context *tdb, const struct found *f, void (*walk)(TDB_DATA, TDB_DATA, void *private_data), void *private_data) { TDB_DATA data; data.dsize = f->rec.data_len; data.dptr = tdb_alloc_read(tdb, f->head + sizeof(f->rec) + f->rec.key_len, data.dsize); if (!data.dptr) { if (tdb->ecode == TDB_ERR_OOM) return false; /* I/O errors are expected. */ return true; } walk(f->key, data, private_data); free(data.dptr); return true; } /* First entry which has offset >= this one. */ static unsigned int find_entry(struct found_table *found, tdb_off_t off) { unsigned int start = 0, end = found->num; while (start < end) { /* We can't overflow here. */ unsigned int mid = (start + end) / 2; if (off < found->arr[mid].head) { end = mid; } else if (off > found->arr[mid].head) { start = mid + 1; } else { return mid; } } assert(start == end); return end; } static void found_in_hashchain(struct found_table *found, tdb_off_t head) { unsigned int match; match = find_entry(found, head); if (match < found->num && found->arr[match].head == head) { found->arr[match].in_hash = true; } } static void mark_free_area(struct found_table *found, tdb_off_t head, tdb_len_t len) { unsigned int match; match = find_entry(found, head); /* Mark everything within this free entry. */ while (match < found->num) { if (found->arr[match].head >= head + len) { break; } found->arr[match].in_free = true; match++; } } static int cmp_key(const void *a, const void *b) { const struct found *fa = a, *fb = b; if (fa->key.dsize < fb->key.dsize) { return -1; } else if (fa->key.dsize > fb->key.dsize) { return 1; } return memcmp(fa->key.dptr, fb->key.dptr, fa->key.dsize); } static bool key_eq(TDB_DATA a, TDB_DATA b) { return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; } static void free_table(struct found_table *found) { unsigned int i; for (i = 0; i < found->num; i++) { free(found->arr[i].key.dptr); } free(found->arr); } static void logging_suppressed(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { } _PUBLIC_ int tdb_rescue(struct tdb_context *tdb, void (*walk)(TDB_DATA, TDB_DATA, void *private_data), void *private_data) { struct found_table found = { NULL, 0, 0 }; tdb_off_t h, off, i; tdb_log_func oldlog = tdb->log.log_fn; struct tdb_record rec; TDB_DATA key; bool locked; /* Read-only databases use no locking at all: it's best-effort. * We may have a write lock already, so skip that case too. */ if (tdb->read_only || tdb->allrecord_lock.count != 0) { locked = false; } else { if (tdb_lockall_read(tdb) == -1) return -1; locked = true; } /* Make sure we know true size of the underlying file. */ tdb_oob(tdb, tdb->map_size, 1, 1); /* Suppress logging, since we anticipate errors. */ tdb->log.log_fn = logging_suppressed; /* Now walk entire db looking for records. */ for (off = TDB_DATA_START(tdb->hash_size); off < tdb->map_size; off += TDB_ALIGNMENT) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == -1) continue; if (looks_like_valid_record(tdb, off, &rec, &key)) { if (!add_to_table(&found, off, &rec, key)) { goto oom; } } } /* Walk hash chains to positive vet. */ for (h = 0; h < 1+tdb->hash_size; h++) { bool slow_chase = false; tdb_off_t slow_off = FREELIST_TOP + h*sizeof(tdb_off_t); if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), &off) == -1) continue; while (off && off != slow_off) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) != 0) { break; } /* 0 is the free list, rest are hash chains. */ if (h == 0) { /* Don't mark garbage as free. */ if (rec.magic != TDB_FREE_MAGIC) { break; } mark_free_area(&found, off, sizeof(rec) + rec.rec_len); } else { found_in_hashchain(&found, off); } off = rec.next; /* Loop detection using second pointer at half-speed */ if (slow_chase) { /* First entry happens to be next ptr */ tdb_ofs_read(tdb, slow_off, &slow_off); } slow_chase = !slow_chase; } } /* Recovery area: must be marked as free, since it often has old * records in there! */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off) == 0 && off != 0) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == 0) { mark_free_area(&found, off, sizeof(rec) + rec.rec_len); } } /* Now sort by key! */ if (found.arr != NULL) { qsort(found.arr, found.num, sizeof(found.arr[0]), cmp_key); } for (i = 0; (found.arr != NULL) && i < found.num; ) { unsigned int num, num_in_hash = 0; /* How many are identical? */ for (num = 0; num < found.num - i; num++) { if (!key_eq(found.arr[i].key, found.arr[i+num].key)) { break; } if (found.arr[i+num].in_hash) { if (!walk_record(tdb, &found.arr[i+num], walk, private_data)) goto oom; num_in_hash++; } } assert(num); /* If none were in the hash, we print any not in free list. */ if (num_in_hash == 0) { unsigned int j; for (j = i; j < i + num; j++) { if (!found.arr[j].in_free) { if (!walk_record(tdb, &found.arr[j], walk, private_data)) goto oom; } } } i += num; } tdb->log.log_fn = oldlog; if (locked) { tdb_unlockall_read(tdb); } return 0; oom: tdb->log.log_fn = oldlog; tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_rescue: failed allocating\n")); free_table(&found); if (locked) { tdb_unlockall_read(tdb); } return -1; } ldb-2.0.8/lib/tdb/common/summary.c0000660000000000000000000001362213573675413016710 0ustar rootroot00000000000000 /* Trivial Database: human-readable summary code Copyright (C) Rusty Russell 2010 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 . */ #include "tdb_private.h" #define SUMMARY_FORMAT \ "Size of file/data: %llu/%zu\n" \ "Header offset/logical size: %zu/%zu\n" \ "Number of records: %zu\n" \ "Incompatible hash: %s\n" \ "Active/supported feature flags: 0x%08x/0x%08x\n" \ "Robust mutexes locking: %s\n" \ "Smallest/average/largest keys: %zu/%zu/%zu\n" \ "Smallest/average/largest data: %zu/%zu/%zu\n" \ "Smallest/average/largest padding: %zu/%zu/%zu\n" \ "Number of dead records: %zu\n" \ "Smallest/average/largest dead records: %zu/%zu/%zu\n" \ "Number of free records: %zu\n" \ "Smallest/average/largest free records: %zu/%zu/%zu\n" \ "Number of hash chains: %zu\n" \ "Smallest/average/largest hash chains: %zu/%zu/%zu\n" \ "Number of uncoalesced records: %zu\n" \ "Smallest/average/largest uncoalesced runs: %zu/%zu/%zu\n" \ "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: %.0f/%.0f/%.0f/%.0f/%.0f/%.0f/%.0f\n" /* We don't use tally module, to keep upstream happy. */ struct tally { size_t min, max, total; size_t num; }; static void tally_init(struct tally *tally) { tally->total = 0; tally->num = 0; tally->min = tally->max = 0; } static void tally_add(struct tally *tally, size_t len) { if (tally->num == 0) tally->max = tally->min = len; else if (len > tally->max) tally->max = len; else if (len < tally->min) tally->min = len; tally->num++; tally->total += len; } static size_t tally_mean(const struct tally *tally) { if (!tally->num) return 0; return tally->total / tally->num; } static size_t get_hash_length(struct tdb_context *tdb, unsigned int i) { tdb_off_t rec_ptr; struct tdb_chainwalk_ctx chainwalk; size_t count = 0; if (tdb_ofs_read(tdb, TDB_HASH_TOP(i), &rec_ptr) == -1) return 0; tdb_chainwalk_init(&chainwalk, rec_ptr); /* keep looking until we find the right record */ while (rec_ptr) { struct tdb_record r; bool ok; ++count; if (tdb_rec_read(tdb, rec_ptr, &r) == -1) return 0; rec_ptr = r.next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return SIZE_MAX; } } return count; } _PUBLIC_ char *tdb_summary(struct tdb_context *tdb) { off_t file_size; tdb_off_t off, rec_off; struct tally freet, keys, data, dead, extra, hashval, uncoal; struct tdb_record rec; char *ret = NULL; bool locked; size_t unc = 0; int len; struct tdb_record recovery; /* Read-only databases use no locking at all: it's best-effort. * We may have a write lock already, so skip that case too. */ if (tdb->read_only || tdb->allrecord_lock.count != 0) { locked = false; } else { if (tdb_lockall_read(tdb) == -1) return NULL; locked = true; } if (tdb_recovery_area(tdb, tdb->methods, &rec_off, &recovery) != 0) { goto unlock; } tally_init(&freet); tally_init(&keys); tally_init(&data); tally_init(&dead); tally_init(&extra); tally_init(&hashval); tally_init(&uncoal); for (off = TDB_DATA_START(tdb->hash_size); off < tdb->map_size - 1; off += sizeof(rec) + rec.rec_len) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == -1) goto unlock; switch (rec.magic) { case TDB_MAGIC: tally_add(&keys, rec.key_len); tally_add(&data, rec.data_len); tally_add(&extra, rec.rec_len - (rec.key_len + rec.data_len)); if (unc > 1) tally_add(&uncoal, unc - 1); unc = 0; break; case TDB_FREE_MAGIC: tally_add(&freet, rec.rec_len); unc++; break; /* If we crash after ftruncate, we can get zeroes or fill. */ case TDB_RECOVERY_INVALID_MAGIC: case 0x42424242: unc++; /* If it's a valid recovery, we can trust rec_len. */ if (off != rec_off) { rec.rec_len = tdb_dead_space(tdb, off) - sizeof(rec); } FALL_THROUGH; case TDB_DEAD_MAGIC: tally_add(&dead, rec.rec_len); break; default: TDB_LOG((tdb, TDB_DEBUG_ERROR, "Unexpected record magic 0x%x at offset %u\n", rec.magic, off)); goto unlock; } } if (unc > 1) tally_add(&uncoal, unc - 1); for (off = 0; off < tdb->hash_size; off++) tally_add(&hashval, get_hash_length(tdb, off)); file_size = tdb->hdr_ofs + tdb->map_size; len = asprintf(&ret, SUMMARY_FORMAT, (unsigned long long)file_size, keys.total+data.total, (size_t)tdb->hdr_ofs, (size_t)tdb->map_size, keys.num, (tdb->hash_fn == tdb_jenkins_hash)?"yes":"no", (unsigned)tdb->feature_flags, TDB_SUPPORTED_FEATURE_FLAGS, (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX)?"yes":"no", keys.min, tally_mean(&keys), keys.max, data.min, tally_mean(&data), data.max, extra.min, tally_mean(&extra), extra.max, dead.num, dead.min, tally_mean(&dead), dead.max, freet.num, freet.min, tally_mean(&freet), freet.max, hashval.num, hashval.min, tally_mean(&hashval), hashval.max, uncoal.total, uncoal.min, tally_mean(&uncoal), uncoal.max, keys.total * 100.0 / file_size, data.total * 100.0 / file_size, extra.total * 100.0 / file_size, freet.total * 100.0 / file_size, dead.total * 100.0 / file_size, (keys.num + freet.num + dead.num) * (sizeof(struct tdb_record) + sizeof(uint32_t)) * 100.0 / file_size, tdb->hash_size * sizeof(tdb_off_t) * 100.0 / file_size); if (len == -1) { goto unlock; } unlock: if (locked) { tdb_unlockall_read(tdb); } return ret; } ldb-2.0.8/lib/tdb/common/tdb.c0000660000000000000000000007562213573675413015774 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" _PUBLIC_ TDB_DATA tdb_null; /* non-blocking increment of the tdb sequence number if the tdb has been opened using the TDB_SEQNUM flag */ _PUBLIC_ void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) { tdb_off_t seqnum=0; if (!(tdb->flags & TDB_SEQNUM)) { return; } /* we ignore errors from this, as we have no sane way of dealing with them. */ tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); seqnum++; tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); } /* increment the tdb sequence number if the tdb has been opened using the TDB_SEQNUM flag */ static void tdb_increment_seqnum(struct tdb_context *tdb) { if (!(tdb->flags & TDB_SEQNUM)) { return; } if (tdb->transaction != NULL) { tdb_increment_seqnum_nonblock(tdb); return; } if (tdb_nest_lock(tdb, TDB_SEQNUM_OFS, F_WRLCK, TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) { return; } tdb_increment_seqnum_nonblock(tdb); tdb_nest_unlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, false); } static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) { return memcmp(data.dptr, key.dptr, data.dsize); } void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr) { *ctx = (struct tdb_chainwalk_ctx) { .slow_ptr = ptr }; } bool tdb_chainwalk_check(struct tdb_context *tdb, struct tdb_chainwalk_ctx *ctx, tdb_off_t next_ptr) { int ret; if (ctx->slow_chase) { ret = tdb_ofs_read(tdb, ctx->slow_ptr, &ctx->slow_ptr); if (ret == -1) { return false; } } ctx->slow_chase = !ctx->slow_chase; if (next_ptr == ctx->slow_ptr) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_chainwalk_check: circular chain\n")); return false; } return true; } /* Returns 0 on fail. On success, return offset of record, and fills in rec */ static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, struct tdb_record *r) { tdb_off_t rec_ptr; struct tdb_chainwalk_ctx chainwalk; /* read in the hash top */ if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) return 0; tdb_chainwalk_init(&chainwalk, rec_ptr); /* keep looking until we find the right record */ while (rec_ptr) { bool ok; if (tdb_rec_read(tdb, rec_ptr, r) == -1) return 0; if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), r->key_len, tdb_key_compare, NULL) == 0) { return rec_ptr; } rec_ptr = r->next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return 0; } } tdb->ecode = TDB_ERR_NOEXIST; return 0; } /* As tdb_find, but if you succeed, keep the lock */ tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, struct tdb_record *rec) { uint32_t rec_ptr; if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) return 0; if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) tdb_unlock(tdb, BUCKET(hash), locktype); return rec_ptr; } static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key); struct tdb_update_hash_state { const TDB_DATA *dbufs; int num_dbufs; tdb_len_t dbufs_len; }; static int tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data) { struct tdb_update_hash_state *state = private_data; unsigned char *dptr = data.dptr; int i; if (state->dbufs_len != data.dsize) { return -1; } for (i=0; inum_dbufs; i++) { TDB_DATA dbuf = state->dbufs[i]; if( dbuf.dsize > 0) { int ret; ret = memcmp(dptr, dbuf.dptr, dbuf.dsize); if (ret != 0) { return -1; } dptr += dbuf.dsize; } } return 0; } /* update an entry in place - this only works if the new data size is <= the old data size and the key exists. on failure return -1. */ static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, const TDB_DATA *dbufs, int num_dbufs, tdb_len_t dbufs_len) { struct tdb_record rec; tdb_off_t rec_ptr, ofs; int i; /* find entry */ if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) return -1; /* it could be an exact duplicate of what is there - this is * surprisingly common (eg. with a ldb re-index). */ if (rec.data_len == dbufs_len) { struct tdb_update_hash_state state = { .dbufs = dbufs, .num_dbufs = num_dbufs, .dbufs_len = dbufs_len }; int ret; ret = tdb_parse_record(tdb, key, tdb_update_hash_cmp, &state); if (ret == 0) { return 0; } } /* must be long enough key, data and tailer */ if (rec.rec_len < key.dsize + dbufs_len + sizeof(tdb_off_t)) { tdb->ecode = TDB_SUCCESS; /* Not really an error */ return -1; } ofs = rec_ptr + sizeof(rec) + rec.key_len; for (i=0; imethods->tdb_write(tdb, ofs, dbuf.dptr, dbuf.dsize); if (ret == -1) { return -1; } ofs += dbuf.dsize; } if (dbufs_len != rec.data_len) { /* update size */ rec.data_len = dbufs_len; return tdb_rec_write(tdb, rec_ptr, &rec); } return 0; } /* find an entry in the database given a key */ /* If an entry doesn't exist tdb_err will be set to * TDB_ERR_NOEXIST. If a key has no data attached * then the TDB_DATA will have zero length but * a non-zero pointer */ static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key) { tdb_off_t rec_ptr; struct tdb_record rec; TDB_DATA ret; uint32_t hash; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) return tdb_null; ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, rec.data_len); ret.dsize = rec.data_len; tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return ret; } _PUBLIC_ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) { TDB_DATA ret = _tdb_fetch(tdb, key); tdb_trace_1rec_retrec(tdb, "tdb_fetch", key, ret); return ret; } /* * Find an entry in the database and hand the record's data to a parsing * function. The parsing function is executed under the chain read lock, so it * should be fast and should not block on other syscalls. * * DON'T CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS. * * For mmapped tdb's that do not have a transaction open it points the parsing * function directly at the mmap area, it avoids the malloc/memcpy in this * case. If a transaction is open or no mmap is available, it has to do * malloc/read/parse/free. * * This is interesting for all readers of potentially large data structures in * the tdb records, ldb indexes being one example. * * Return -1 if the record was not found. */ _PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { tdb_off_t rec_ptr; struct tdb_record rec; int ret; uint32_t hash; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { /* record not found */ tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, -1); tdb->ecode = TDB_ERR_NOEXIST; return -1; } tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, 0); ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, rec.data_len, parser, private_data); tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return ret; } /* check if an entry in the database exists note that 1 is returned if the key is found and 0 is returned if not found this doesn't match the conventions in the rest of this module, but is compatible with gdbm */ static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) { struct tdb_record rec; if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) return 0; tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return 1; } _PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) { uint32_t hash = tdb->hash_fn(&key); int ret; ret = tdb_exists_hash(tdb, key, hash); tdb_trace_1rec_ret(tdb, "tdb_exists", key, ret); return ret; } /* * Move a dead record to the freelist. The hash chain and freelist * must be locked. */ static int tdb_del_dead(struct tdb_context *tdb, uint32_t last_ptr, uint32_t rec_ptr, struct tdb_record *rec, bool *deleted) { int ret; ret = tdb_write_lock_record(tdb, rec_ptr); if (ret == -1) { /* Someone traversing here: Just leave it dead */ return 0; } ret = tdb_write_unlock_record(tdb, rec_ptr); if (ret == -1) { return -1; } ret = tdb_ofs_write(tdb, last_ptr, &rec->next); if (ret == -1) { return -1; } *deleted = true; ret = tdb_free(tdb, rec_ptr, rec); return ret; } /* * Walk the hash chain and leave tdb->max_dead_records around. Move * the rest of dead records to the freelist. */ int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash) { struct tdb_chainwalk_ctx chainwalk; struct tdb_record rec; tdb_off_t last_ptr, rec_ptr; bool locked_freelist = false; int num_dead = 0; int ret; last_ptr = TDB_HASH_TOP(hash); /* * Init chainwalk with the pointer to the hash top. It might * be that the very first record in the chain is a dead one * that we have to delete. */ tdb_chainwalk_init(&chainwalk, last_ptr); ret = tdb_ofs_read(tdb, last_ptr, &rec_ptr); if (ret == -1) { return -1; } while (rec_ptr != 0) { bool deleted = false; uint32_t next; ret = tdb_rec_read(tdb, rec_ptr, &rec); if (ret == -1) { goto fail; } /* * Make a copy of rec.next: Further down we might * delete and put the record on the freelist. Make * sure that modifications in that code path can't * break the chainwalk here. */ next = rec.next; if (rec.magic == TDB_DEAD_MAGIC) { num_dead += 1; if (num_dead > tdb->max_dead_records) { if (!locked_freelist) { /* * Lock the freelist only if * it's really required. */ ret = tdb_lock(tdb, -1, F_WRLCK); if (ret == -1) { goto fail; }; locked_freelist = true; } ret = tdb_del_dead( tdb, last_ptr, rec_ptr, &rec, &deleted); if (ret == -1) { goto fail; } } } /* * Don't do the chainwalk check if "rec_ptr" was * deleted. We reduced the chain, and the chainwalk * check might catch up early. Imagine a valid chain * with just dead records: We never can bump the * "slow" pointer in chainwalk_check, as there isn't * anything left to jump to and compare. */ if (!deleted) { bool ok; last_ptr = rec_ptr; ok = tdb_chainwalk_check(tdb, &chainwalk, next); if (!ok) { ret = -1; goto fail; } } rec_ptr = next; } ret = 0; fail: if (locked_freelist) { tdb_unlock(tdb, -1, F_WRLCK); } return ret; } /* delete an entry in the database given a key */ static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) { tdb_off_t rec_ptr; struct tdb_record rec; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec); if (rec_ptr == 0) { return -1; } /* * Mark the record dead */ rec.magic = TDB_DEAD_MAGIC; ret = tdb_rec_write(tdb, rec_ptr, &rec); if (ret == -1) { goto done; } tdb_increment_seqnum(tdb); ret = tdb_trim_dead(tdb, hash); done: if (tdb_unlock(tdb, BUCKET(hash), F_WRLCK) != 0) TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); return ret; } _PUBLIC_ int tdb_delete(struct tdb_context *tdb, TDB_DATA key) { uint32_t hash = tdb->hash_fn(&key); int ret; ret = tdb_delete_hash(tdb, key, hash); tdb_trace_1rec_ret(tdb, "tdb_delete", key, ret); return ret; } /* * See if we have a dead record around with enough space */ tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, struct tdb_record *r, tdb_len_t length, tdb_off_t *p_last_ptr) { tdb_off_t rec_ptr, last_ptr; struct tdb_chainwalk_ctx chainwalk; tdb_off_t best_rec_ptr = 0; tdb_off_t best_last_ptr = 0; struct tdb_record best = { .rec_len = UINT32_MAX }; length += sizeof(tdb_off_t); /* tailer */ last_ptr = TDB_HASH_TOP(hash); /* read in the hash top */ if (tdb_ofs_read(tdb, last_ptr, &rec_ptr) == -1) return 0; tdb_chainwalk_init(&chainwalk, rec_ptr); /* keep looking until we find the right record */ while (rec_ptr) { bool ok; if (tdb_rec_read(tdb, rec_ptr, r) == -1) return 0; if (TDB_DEAD(r) && (r->rec_len >= length) && (r->rec_len < best.rec_len)) { best_rec_ptr = rec_ptr; best_last_ptr = last_ptr; best = *r; } last_ptr = rec_ptr; rec_ptr = r->next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return 0; } } if (best.rec_len == UINT32_MAX) { return 0; } *r = best; *p_last_ptr = best_last_ptr; return best_rec_ptr; } static int _tdb_storev(struct tdb_context *tdb, TDB_DATA key, const TDB_DATA *dbufs, int num_dbufs, int flag, uint32_t hash) { struct tdb_record rec; tdb_off_t rec_ptr, ofs; tdb_len_t rec_len, dbufs_len; int i; int ret = -1; dbufs_len = 0; for (i=0; iecode = TDB_ERR_EINVAL; goto fail; } dbufs_len += dsize; if (dbufs_len < dsize) { tdb->ecode = TDB_ERR_OOM; goto fail; } } rec_len = key.dsize + dbufs_len; if ((rec_len < key.dsize) || (rec_len < dbufs_len)) { tdb->ecode = TDB_ERR_OOM; goto fail; } /* check for it existing, on insert. */ if (flag == TDB_INSERT) { if (tdb_exists_hash(tdb, key, hash)) { tdb->ecode = TDB_ERR_EXISTS; goto fail; } } else { /* first try in-place update, on modify or replace. */ if (tdb_update_hash(tdb, key, hash, dbufs, num_dbufs, dbufs_len) == 0) { goto done; } if (tdb->ecode == TDB_ERR_NOEXIST && flag == TDB_MODIFY) { /* if the record doesn't exist and we are in TDB_MODIFY mode then we should fail the store */ goto fail; } } /* reset the error code potentially set by the tdb_update_hash() */ tdb->ecode = TDB_SUCCESS; /* delete any existing record - if it doesn't exist we don't care. Doing this first reduces fragmentation, and avoids coalescing with `allocated' block before it's updated. */ if (flag != TDB_INSERT) tdb_delete_hash(tdb, key, hash); /* we have to allocate some space */ rec_ptr = tdb_allocate(tdb, hash, rec_len, &rec); if (rec_ptr == 0) { goto fail; } /* Read hash top into next ptr */ if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) goto fail; rec.key_len = key.dsize; rec.data_len = dbufs_len; rec.full_hash = hash; rec.magic = TDB_MAGIC; ofs = rec_ptr; /* write out and point the top of the hash chain at it */ ret = tdb_rec_write(tdb, ofs, &rec); if (ret == -1) { goto fail; } ofs += sizeof(rec); ret = tdb->methods->tdb_write(tdb, ofs, key.dptr, key.dsize); if (ret == -1) { goto fail; } ofs += key.dsize; for (i=0; imethods->tdb_write(tdb, ofs, dbufs[i].dptr, dbufs[i].dsize); if (ret == -1) { goto fail; } ofs += dbufs[i].dsize; } ret = tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr); if (ret == -1) { /* Need to tdb_unallocate() here */ goto fail; } done: ret = 0; fail: if (ret == 0) { tdb_increment_seqnum(tdb); } return ret; } static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag, uint32_t hash) { return _tdb_storev(tdb, key, &dbuf, 1, flag, hash); } /* store an element in the database, replacing any existing element with the same key return 0 on success, -1 on failure */ _PUBLIC_ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) { uint32_t hash; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, -1); return -1; } /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; ret = _tdb_store(tdb, key, dbuf, flag, hash); tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, ret); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); return ret; } _PUBLIC_ int tdb_storev(struct tdb_context *tdb, TDB_DATA key, const TDB_DATA *dbufs, int num_dbufs, int flag) { uint32_t hash; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, dbufs, num_dbufs, flag, -1); return -1; } /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; ret = _tdb_storev(tdb, key, dbufs, num_dbufs, flag, hash); tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, dbufs, num_dbufs, flag, -1); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); return ret; } /* Append to an entry. Create if not exist. */ _PUBLIC_ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) { uint32_t hash; TDB_DATA dbufs[2]; int ret = -1; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; dbufs[0] = _tdb_fetch(tdb, key); dbufs[1] = new_dbuf; ret = _tdb_storev(tdb, key, dbufs, 2, 0, hash); tdb_trace_2rec_retrec(tdb, "tdb_append", key, dbufs[0], dbufs[1]); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); SAFE_FREE(dbufs[0].dptr); return ret; } /* return the name of the current tdb file useful for external logging functions */ _PUBLIC_ const char *tdb_name(struct tdb_context *tdb) { return tdb->name; } /* return the underlying file descriptor being used by tdb, or -1 useful for external routines that want to check the device/inode of the fd */ _PUBLIC_ int tdb_fd(struct tdb_context *tdb) { return tdb->fd; } /* return the current logging function useful for external tdb routines that wish to log tdb errors */ _PUBLIC_ tdb_log_func tdb_log_fn(struct tdb_context *tdb) { return tdb->log.log_fn; } /* get the tdb sequence number. Only makes sense if the writers opened with TDB_SEQNUM set. Note that this sequence number will wrap quite quickly, so it should only be used for a 'has something changed' test, not for code that relies on the count of the number of changes made. If you want a counter then use a tdb record. The aim of this sequence number is to allow for a very lightweight test of a possible tdb change. */ _PUBLIC_ int tdb_get_seqnum(struct tdb_context *tdb) { tdb_off_t seqnum=0; tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); return seqnum; } _PUBLIC_ int tdb_hash_size(struct tdb_context *tdb) { return tdb->hash_size; } _PUBLIC_ size_t tdb_map_size(struct tdb_context *tdb) { return tdb->map_size; } _PUBLIC_ int tdb_get_flags(struct tdb_context *tdb) { return tdb->flags; } _PUBLIC_ void tdb_add_flags(struct tdb_context *tdb, unsigned flags) { if ((flags & TDB_ALLOW_NESTING) && (flags & TDB_DISALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_add_flags: " "allow_nesting and disallow_nesting are not allowed together!")); return; } if (flags & TDB_ALLOW_NESTING) { tdb->flags &= ~TDB_DISALLOW_NESTING; } if (flags & TDB_DISALLOW_NESTING) { tdb->flags &= ~TDB_ALLOW_NESTING; } tdb->flags |= flags; } _PUBLIC_ void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) { if ((flags & TDB_ALLOW_NESTING) && (flags & TDB_DISALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " "allow_nesting and disallow_nesting are not allowed together!")); return; } if ((flags & TDB_NOLOCK) && (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) && (tdb->mutexes == NULL)) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " "Can not remove NOLOCK flag on mutexed databases")); return; } if (flags & TDB_ALLOW_NESTING) { tdb->flags |= TDB_DISALLOW_NESTING; } if (flags & TDB_DISALLOW_NESTING) { tdb->flags |= TDB_ALLOW_NESTING; } tdb->flags &= ~flags; } /* enable sequence number handling on an open tdb */ _PUBLIC_ void tdb_enable_seqnum(struct tdb_context *tdb) { tdb->flags |= TDB_SEQNUM; } /* add a region of the file to the freelist. Length is the size of the region in bytes, which includes the free list header that needs to be added */ static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) { struct tdb_record rec; if (length <= sizeof(rec)) { /* the region is not worth adding */ return 0; } if (length + offset > tdb->map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); return -1; } memset(&rec,'\0',sizeof(rec)); rec.rec_len = length - sizeof(rec); if (tdb_free(tdb, offset, &rec) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n")); return -1; } return 0; } /* wipe the entire database, deleting all records. This can be done very fast by using a allrecord lock. The entire data portion of the file becomes a single entry in the freelist. This code carefully steps around the recovery area, leaving it alone */ _PUBLIC_ int tdb_wipe_all(struct tdb_context *tdb) { uint32_t i; tdb_off_t offset = 0; ssize_t data_len; tdb_off_t recovery_head; tdb_len_t recovery_size = 0; if (tdb_lockall(tdb) != 0) { return -1; } tdb_trace(tdb, "tdb_wipe_all"); /* see if the tdb has a recovery area, and remember its size if so. We don't want to lose this as otherwise each tdb_wipe_all() in a transaction will increase the size of the tdb by the size of the recovery area */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n")); goto failed; } if (recovery_head != 0) { struct tdb_record rec; if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); return -1; } recovery_size = rec.rec_len + sizeof(rec); } /* wipe the hashes */ for (i=0;ihash_size;i++) { if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); goto failed; } } /* wipe the freelist */ if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); goto failed; } /* add all the rest of the file to the freelist, possibly leaving a gap for the recovery area */ if (recovery_size == 0) { /* the simple case - the whole file can be used as a freelist */ data_len = (tdb->map_size - TDB_DATA_START(tdb->hash_size)); if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { goto failed; } } else { /* we need to add two freelist entries - one on either side of the recovery area Note that we cannot shift the recovery area during this operation. Only the transaction.c code may move the recovery area or we risk subtle data corruption */ data_len = (recovery_head - TDB_DATA_START(tdb->hash_size)); if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { goto failed; } /* and the 2nd free list entry after the recovery area - if any */ data_len = tdb->map_size - (recovery_head+recovery_size); if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { goto failed; } } tdb_increment_seqnum_nonblock(tdb); if (tdb_unlockall(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); goto failed; } return 0; failed: tdb_unlockall(tdb); return -1; } struct traverse_state { bool error; struct tdb_context *dest_db; }; /* traverse function for repacking */ static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { struct traverse_state *state = (struct traverse_state *)private_data; if (tdb_store(state->dest_db, key, data, TDB_INSERT) != 0) { state->error = true; return -1; } return 0; } /* repack a tdb */ _PUBLIC_ int tdb_repack(struct tdb_context *tdb) { struct tdb_context *tmp_db; struct traverse_state state; tdb_trace(tdb, "tdb_repack"); if (tdb_transaction_start(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to start transaction\n")); return -1; } tmp_db = tdb_open("tmpdb", tdb_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0); if (tmp_db == NULL) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to create tmp_db\n")); tdb_transaction_cancel(tdb); return -1; } state.error = false; state.dest_db = tmp_db; if (tdb_traverse_read(tdb, repack_traverse, &state) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying out\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } if (state.error) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during traversal\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } if (tdb_wipe_all(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to wipe database\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } state.error = false; state.dest_db = tdb; if (tdb_traverse_read(tmp_db, repack_traverse, &state) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying back\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } if (state.error) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during second traversal\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } tdb_close(tmp_db); if (tdb_transaction_commit(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to commit\n")); return -1; } return 0; } /* Even on files, we can get partial writes due to signals. */ bool tdb_write_all(int fd, const void *buf, size_t count) { while (count) { ssize_t ret; ret = write(fd, buf, count); if (ret < 0) return false; buf = (const char *)buf + ret; count -= ret; } return true; } bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret) { tdb_off_t ret = a + b; if ((ret < a) || (ret < b)) { return false; } *pret = ret; return true; } #ifdef TDB_TRACE static void tdb_trace_write(struct tdb_context *tdb, const char *str) { if (!tdb_write_all(tdb->tracefd, str, strlen(str))) { close(tdb->tracefd); tdb->tracefd = -1; } } static void tdb_trace_start(struct tdb_context *tdb) { tdb_off_t seqnum=0; char msg[sizeof(tdb_off_t) * 4 + 1]; tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); snprintf(msg, sizeof(msg), "%u ", seqnum); tdb_trace_write(tdb, msg); } static void tdb_trace_end(struct tdb_context *tdb) { tdb_trace_write(tdb, "\n"); } static void tdb_trace_end_ret(struct tdb_context *tdb, int ret) { char msg[sizeof(ret) * 4 + 4]; snprintf(msg, sizeof(msg), " = %i\n", ret); tdb_trace_write(tdb, msg); } static void tdb_trace_record(struct tdb_context *tdb, TDB_DATA rec) { char msg[20 + rec.dsize*2], *p; unsigned int i; /* We differentiate zero-length records from non-existent ones. */ if (rec.dptr == NULL) { tdb_trace_write(tdb, " NULL"); return; } /* snprintf here is purely cargo-cult programming. */ p = msg; p += snprintf(p, sizeof(msg), " %zu:", rec.dsize); for (i = 0; i < rec.dsize; i++) p += snprintf(p, 2, "%02x", rec.dptr[i]); tdb_trace_write(tdb, msg); } void tdb_trace(struct tdb_context *tdb, const char *op) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_end(tdb); } void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op) { char msg[sizeof(tdb_off_t) * 4 + 1]; snprintf(msg, sizeof(msg), "%u ", seqnum); tdb_trace_write(tdb, msg); tdb_trace_write(tdb, op); tdb_trace_end(tdb); } void tdb_trace_open(struct tdb_context *tdb, const char *op, unsigned hash_size, unsigned tdb_flags, unsigned open_flags) { char msg[128]; snprintf(msg, sizeof(msg), "%s %u 0x%x 0x%x", op, hash_size, tdb_flags, open_flags); tdb_trace_start(tdb); tdb_trace_write(tdb, msg); tdb_trace_end(tdb); } void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_end_ret(tdb, ret); } void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_write(tdb, " ="); tdb_trace_record(tdb, ret); tdb_trace_end(tdb); } void tdb_trace_1rec(struct tdb_context *tdb, const char *op, TDB_DATA rec) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); tdb_trace_end(tdb); } void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, int ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); tdb_trace_end_ret(tdb, ret); } void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, TDB_DATA rec, TDB_DATA ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); tdb_trace_write(tdb, " ="); tdb_trace_record(tdb, ret); tdb_trace_end(tdb); } void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec1, TDB_DATA rec2, unsigned flag, int ret) { char msg[1 + sizeof(ret) * 4]; snprintf(msg, sizeof(msg), " %#x", flag); tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec1); tdb_trace_record(tdb, rec2); tdb_trace_write(tdb, msg); tdb_trace_end_ret(tdb, ret); } void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, const TDB_DATA *recs, int num_recs, unsigned flag, int ret) { char msg[1 + sizeof(ret) * 4]; int i; snprintf(msg, sizeof(msg), " %#x", flag); tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); for (i=0; if) #endif #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION (0x26011967 + 6) #define TDB_MAGIC (0x26011999U) #define TDB_FREE_MAGIC (~TDB_MAGIC) #define TDB_DEAD_MAGIC (0xFEE1DEAD) #define TDB_RECOVERY_MAGIC (0xf53bc0e7U) #define TDB_RECOVERY_INVALID_MAGIC (0x0) #define TDB_HASH_RWLOCK_MAGIC (0xbad1a51U) #define TDB_FEATURE_FLAG_MAGIC (0xbad1a52U) #define TDB_ALIGNMENT 4 #define DEFAULT_HASH_SIZE 131 #define FREELIST_TOP (sizeof(struct tdb_header)) #define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) #define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) #define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) #define TDB_HASHTABLE_SIZE(tdb) ((tdb->hash_size+1)*sizeof(tdb_off_t)) #define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) #define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) #define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) #define TDB_PAD_BYTE 0x42 #define TDB_PAD_U32 0x42424242 #define TDB_FEATURE_FLAG_MUTEX 0x00000001 #define TDB_SUPPORTED_FEATURE_FLAGS ( \ TDB_FEATURE_FLAG_MUTEX | \ 0) /* NB assumes there is a local variable called "tdb" that is the * current context, also takes doubly-parenthesized print-style * argument. */ #define TDB_LOG(x) tdb->log.log_fn x #ifdef TDB_TRACE void tdb_trace(struct tdb_context *tdb, const char *op); void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op); void tdb_trace_open(struct tdb_context *tdb, const char *op, unsigned hash_size, unsigned tdb_flags, unsigned open_flags); void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret); void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret); void tdb_trace_1rec(struct tdb_context *tdb, const char *op, TDB_DATA rec); void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, int ret); void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, TDB_DATA rec, TDB_DATA ret); void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec1, TDB_DATA rec2, unsigned flag, int ret); void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, const TDB_DATA *recs, int num_recs, unsigned flag, int ret); void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op, TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret); #else #define tdb_trace(tdb, op) #define tdb_trace_seqnum(tdb, seqnum, op) #define tdb_trace_open(tdb, op, hash_size, tdb_flags, open_flags) #define tdb_trace_ret(tdb, op, ret) #define tdb_trace_retrec(tdb, op, ret) #define tdb_trace_1rec(tdb, op, rec) #define tdb_trace_1rec_ret(tdb, op, rec, ret) #define tdb_trace_1rec_retrec(tdb, op, rec, ret) #define tdb_trace_2rec_flag_ret(tdb, op, rec1, rec2, flag, ret) #define tdb_trace_1plusn_rec_flag_ret(tdb, op, rec, recs, num_recs, flag, ret); #define tdb_trace_2rec_retrec(tdb, op, rec1, rec2, ret) #endif /* !TDB_TRACE */ /* lock offsets */ #define OPEN_LOCK 0 #define ACTIVE_LOCK 4 #define TRANSACTION_LOCK 8 /* free memory if the pointer is valid and zero the pointer */ #ifndef SAFE_FREE #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) #endif /* * Note: the BUCKET macro is broken as it returns an unexpected result when * called as BUCKET(-1) for the freelist: * * -1 is sign converted to an unsigned int 4294967295 and then the modulo * tdb->hashtable_size is computed. So with a hashtable_size of 10 the result * is * * 4294967295 % hashtable_size = 5. * * where it should be -1 (C uses symmetric modulo). * * As all callers will lock the same wrong list consistently locking is still * consistent. We can not change this without an incompatible on-disk format * change, otherwise different tdb versions would use incompatible locking. */ #define BUCKET(hash) ((hash) % tdb->hash_size) #define DOCONV() (tdb->flags & TDB_CONVERT) #define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) /* the body of the database is made of one tdb_record for the free space plus a separate data list for each hash value */ struct tdb_record { tdb_off_t next; /* offset of the next record in the list */ tdb_len_t rec_len; /* total byte length of record */ tdb_len_t key_len; /* byte length of key */ tdb_len_t data_len; /* byte length of data */ uint32_t full_hash; /* the full 32 bit hash of the key */ uint32_t magic; /* try to catch errors */ /* the following union is implied: union { char record[rec_len]; struct { char key[key_len]; char data[data_len]; } uint32_t totalsize; (tailer) } */ }; /* this is stored at the front of every database */ struct tdb_header { char magic_food[32]; /* for /etc/magic */ uint32_t version; /* version of the code */ uint32_t hash_size; /* number of hash entries */ tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ tdb_off_t recovery_start; /* offset of transaction recovery region */ tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */ uint32_t magic2_hash; /* hash of TDB_MAGIC. */ uint32_t feature_flags; tdb_len_t mutex_size; /* set if TDB_FEATURE_FLAG_MUTEX is set */ tdb_off_t reserved[25]; }; struct tdb_lock_type { uint32_t off; uint32_t count; uint32_t ltype; }; struct tdb_chainwalk_ctx { tdb_off_t slow_ptr; bool slow_chase; }; struct tdb_traverse_lock { struct tdb_traverse_lock *next; uint32_t off; uint32_t list; int lock_rw; }; void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr); bool tdb_chainwalk_check(struct tdb_context *tdb, struct tdb_chainwalk_ctx *ctx, tdb_off_t next_ptr); enum tdb_lock_flags { /* WAIT == F_SETLKW, NOWAIT == F_SETLK */ TDB_LOCK_NOWAIT = 0, TDB_LOCK_WAIT = 1, /* If set, don't log an error on failure. */ TDB_LOCK_PROBE = 2, /* If set, don't actually lock at all. */ TDB_LOCK_MARK_ONLY = 4, }; struct tdb_methods { int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); void (*next_hash_chain)(struct tdb_context *, uint32_t *); int (*tdb_oob)(struct tdb_context *, tdb_off_t , tdb_len_t, int ); int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); }; struct tdb_mutexes; struct tdb_context { char *name; /* the name of the database */ void *map_ptr; /* where it is currently mapped */ int fd; /* open file descriptor for the database */ tdb_len_t map_size; /* how much space has been mapped */ int read_only; /* opened read-only */ int traverse_read; /* read-only traversal */ int traverse_write; /* read-write traversal */ struct tdb_lock_type allrecord_lock; /* .offset == upgradable */ int num_lockrecs; struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ int lockrecs_array_length; tdb_off_t hdr_ofs; /* this is 0 or header.mutex_size */ struct tdb_mutexes *mutexes; /* mmap of the mutex area */ enum TDB_ERROR ecode; /* error code for last tdb error */ uint32_t hash_size; uint32_t feature_flags; uint32_t flags; /* the flags passed to tdb_open */ struct tdb_traverse_lock travlocks; /* current traversal locks */ struct tdb_context *next; /* all tdbs to avoid multiple opens */ dev_t device; /* uniquely identifies this tdb */ ino_t inode; /* uniquely identifies this tdb */ struct tdb_logging_context log; unsigned int (*hash_fn)(TDB_DATA *key); int open_flags; /* flags used in the open - needed by reopen */ const struct tdb_methods *methods; struct tdb_transaction *transaction; int page_size; int max_dead_records; #ifdef TDB_TRACE int tracefd; #endif volatile sig_atomic_t *interrupt_sig_ptr; }; /* internal prototypes */ int tdb_munmap(struct tdb_context *tdb); int tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, enum tdb_lock_flags flags); int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, bool mark_lock); int tdb_unlock(struct tdb_context *tdb, int list, int ltype); int tdb_brlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len, enum tdb_lock_flags flags); int tdb_brunlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len); bool tdb_have_extra_locks(struct tdb_context *tdb); void tdb_release_transaction_locks(struct tdb_context *tdb); int tdb_transaction_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags lockflags); int tdb_transaction_unlock(struct tdb_context *tdb, int ltype); int tdb_recovery_area(struct tdb_context *tdb, const struct tdb_methods *methods, tdb_off_t *recovery_offset, struct tdb_record *rec); int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable); int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock); int tdb_allrecord_upgrade(struct tdb_context *tdb); int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); void *tdb_convert(void *buf, uint32_t size); int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, struct tdb_record *rec); int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe); static inline int tdb_oob( struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { if (likely((off + len >= off) && (off + len <= tdb->map_size))) { return 0; } return _tdb_oob(tdb, off, len, probe); } int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); bool tdb_needs_recovery(struct tdb_context *tdb); int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, tdb_off_t offset, tdb_len_t len, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, struct tdb_record *rec); tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, struct tdb_record *r, tdb_len_t length, tdb_off_t *p_last_ptr); int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash); void tdb_io_init(struct tdb_context *tdb); int tdb_expand(struct tdb_context *tdb, tdb_off_t size); tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size); int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec); bool tdb_write_all(int fd, const void *buf, size_t count); int tdb_transaction_recover(struct tdb_context *tdb); void tdb_header_hash(struct tdb_context *tdb, uint32_t *magic1_hash, uint32_t *magic2_hash); unsigned int tdb_old_hash(TDB_DATA *key); size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off); bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret); /* tdb_off_t and tdb_len_t right now are both uint32_t */ #define tdb_add_len_t tdb_add_off_t size_t tdb_mutex_size(struct tdb_context *tdb); bool tdb_have_mutexes(struct tdb_context *tdb); int tdb_mutex_init(struct tdb_context *tdb); int tdb_mutex_mmap(struct tdb_context *tdb); int tdb_mutex_munmap(struct tdb_context *tdb); bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, bool waitflag, int *pret); bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, int *pret); int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags); int tdb_mutex_allrecord_unlock(struct tdb_context *tdb); int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb); void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb); #endif /* TDB_PRIVATE_H */ ldb-2.0.8/lib/tdb/common/transaction.c0000660000000000000000000011616513573675413017546 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 2005 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* transaction design: - only allow a single transaction at a time per database. This makes using the transaction API simpler, as otherwise the caller would have to cope with temporary failures in transactions that conflict with other current transactions - keep the transaction recovery information in the same file as the database, using a special 'transaction recovery' record pointed at by the header. This removes the need for extra journal files as used by some other databases - dynamically allocated the transaction recover record, re-using it for subsequent transactions. If a larger record is needed then tdb_free() the old record to place it on the normal tdb freelist before allocating the new record - during transactions, keep a linked list of all writes that have been performed by intercepting all tdb_write() calls. The hooked transaction versions of tdb_read() and tdb_write() check this linked list and try to use the elements of the list in preference to the real database. - don't allow any locks to be held when a transaction starts, otherwise we can end up with deadlock (plus lack of lock nesting in posix locks would mean the lock is lost) - if the caller gains a lock during the transaction but doesn't release it then fail the commit - allow for nested calls to tdb_transaction_start(), re-using the existing transaction record. If the inner transaction is cancelled then a subsequent commit will fail - keep a mirrored copy of the tdb hash chain heads to allow for the fast hash heads scan on traverse, updating the mirrored copy in the transaction version of tdb_write - allow callers to mix transaction and non-transaction use of tdb, although once a transaction is started then an exclusive lock is gained until the transaction is committed or cancelled - the commit stategy involves first saving away all modified data into a linearised buffer in the transaction recovery area, then marking the transaction recovery area with a magic value to indicate a valid recovery record. In total 4 fsync/msync calls are needed per commit to prevent race conditions. It might be possible to reduce this to 3 or even 2 with some more work. - check for a valid recovery record on open of the tdb, while the open lock is held. Automatically recover from the transaction recovery area if needed, then continue with the open as usual. This allows for smooth crash recovery with no administrator intervention. - if TDB_NOSYNC is passed to flags in tdb_open then transactions are still available, but no fsync/msync calls are made. This means we are still proof against a process dying during transaction commit, but not against machine reboot. - if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using tdb_add_flags() transaction nesting is enabled. It resets the TDB_DISALLOW_NESTING flag, as both cannot be used together. The default is that transaction nesting is allowed. Note: this default may change in future versions of tdb. Beware. when transactions are nested a transaction successfully completed with tdb_transaction_commit() can be silently unrolled later. - if TDB_DISALLOW_NESTING is passed to flags in tdb open, or added using tdb_add_flags() transaction nesting is disabled. It resets the TDB_ALLOW_NESTING flag, as both cannot be used together. An attempt create a nested transaction will fail with TDB_ERR_NESTING. The default is that transaction nesting is allowed. Note: this default may change in future versions of tdb. */ /* hold the context of any current transaction */ struct tdb_transaction { /* we keep a mirrored copy of the tdb hash heads here so tdb_next_hash_chain() can operate efficiently */ uint32_t *hash_heads; /* the original io methods - used to do IOs to the real db */ const struct tdb_methods *io_methods; /* the list of transaction blocks. When a block is first written to, it gets created in this list */ uint8_t **blocks; uint32_t num_blocks; uint32_t block_size; /* bytes in each block */ uint32_t last_block_size; /* number of valid bytes in the last block */ /* non-zero when an internal transaction error has occurred. All write operations will then fail until the transaction is ended */ int transaction_error; /* when inside a transaction we need to keep track of any nested tdb_transaction_start() calls, as these are allowed, but don't create a new transaction */ int nesting; /* set when a prepare has already occurred */ bool prepared; tdb_off_t magic_offset; /* old file size before transaction */ tdb_len_t old_map_size; /* did we expand in this transaction */ bool expanded; }; /* read while in a transaction. We need to check first if the data is in our list of transaction elements, then if not do a real read */ static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { uint32_t blk; /* break it down into block sized ops */ while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); if (transaction_read(tdb, off, buf, len2, cv) != 0) { return -1; } len -= len2; off += len2; buf = (void *)(len2 + (char *)buf); } if (len == 0) { return 0; } blk = off / tdb->transaction->block_size; /* see if we have it in the block list */ if (tdb->transaction->num_blocks <= blk || tdb->transaction->blocks[blk] == NULL) { /* nope, do a real read */ if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { goto fail; } return 0; } /* it is in the block list. Now check for the last block */ if (blk == tdb->transaction->num_blocks-1) { if (len > tdb->transaction->last_block_size) { goto fail; } } /* now copy it out of this block */ memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); if (cv) { tdb_convert(buf, len); } return 0; fail: TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%u len=%u\n", off, len)); tdb->ecode = TDB_ERR_IO; tdb->transaction->transaction_error = 1; return -1; } /* write while in a transaction */ static int transaction_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { uint32_t blk; if (buf == NULL) { return -1; } /* Only a commit is allowed on a prepared transaction */ if (tdb->transaction->prepared) { tdb->ecode = TDB_ERR_EINVAL; TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: transaction already prepared, write not allowed\n")); tdb->transaction->transaction_error = 1; return -1; } /* if the write is to a hash head, then update the transaction hash heads */ if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) { uint32_t chain = (off-FREELIST_TOP) / sizeof(tdb_off_t); memcpy(&tdb->transaction->hash_heads[chain], buf, len); } /* break it up into block sized chunks */ while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); if (transaction_write(tdb, off, buf, len2) != 0) { return -1; } len -= len2; off += len2; buf = (const void *)(len2 + (const char *)buf); } if (len == 0) { return 0; } blk = off / tdb->transaction->block_size; off = off % tdb->transaction->block_size; if (tdb->transaction->num_blocks <= blk) { uint8_t **new_blocks; /* expand the blocks array */ new_blocks = (uint8_t **)realloc(tdb->transaction->blocks, (blk+1)*sizeof(uint8_t *)); if (new_blocks == NULL) { tdb->ecode = TDB_ERR_OOM; goto fail; } memset(&new_blocks[tdb->transaction->num_blocks], 0, (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); tdb->transaction->blocks = new_blocks; tdb->transaction->num_blocks = blk+1; tdb->transaction->last_block_size = 0; } /* allocate and fill a block? */ if (tdb->transaction->blocks[blk] == NULL) { tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); if (tdb->transaction->blocks[blk] == NULL) { tdb->ecode = TDB_ERR_OOM; tdb->transaction->transaction_error = 1; return -1; } if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size; if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); } if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, tdb->transaction->blocks[blk], len2, 0) != 0) { SAFE_FREE(tdb->transaction->blocks[blk]); tdb->ecode = TDB_ERR_IO; goto fail; } if (blk == tdb->transaction->num_blocks-1) { tdb->transaction->last_block_size = len2; } } } /* overwrite part of an existing block */ memcpy(tdb->transaction->blocks[blk] + off, buf, len); if (blk == tdb->transaction->num_blocks-1) { if (len + off > tdb->transaction->last_block_size) { tdb->transaction->last_block_size = len + off; } } return 0; fail: TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%u len=%u\n", (blk*tdb->transaction->block_size) + off, len)); tdb->transaction->transaction_error = 1; return -1; } /* write while in a transaction - this variant never expands the transaction blocks, it only updates existing blocks. This means it cannot change the recovery size */ static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { uint32_t blk; /* break it up into block sized chunks */ while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); if (transaction_write_existing(tdb, off, buf, len2) != 0) { return -1; } len -= len2; off += len2; if (buf != NULL) { buf = (const void *)(len2 + (const char *)buf); } } if (len == 0 || buf == NULL) { return 0; } blk = off / tdb->transaction->block_size; off = off % tdb->transaction->block_size; if (tdb->transaction->num_blocks <= blk || tdb->transaction->blocks[blk] == NULL) { return 0; } if (blk == tdb->transaction->num_blocks-1 && off + len > tdb->transaction->last_block_size) { if (off >= tdb->transaction->last_block_size) { return 0; } len = tdb->transaction->last_block_size - off; } /* overwrite part of an existing block */ memcpy(tdb->transaction->blocks[blk] + off, buf, len); return 0; } /* accelerated hash chain head search, using the cached hash heads */ static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) { uint32_t h = *chain; for (;h < tdb->hash_size;h++) { /* the +1 takes account of the freelist */ if (0 != tdb->transaction->hash_heads[h+1]) { break; } } (*chain) = h; } /* out of bounds check during a transaction */ static int transaction_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { /* * This duplicates functionality from tdb_oob(). Don't remove: * we still have direct callers of tdb->methods->tdb_oob() * inside transaction.c. */ if (off + len >= off && off + len <= tdb->map_size) { return 0; } tdb->ecode = TDB_ERR_IO; return -1; } /* transaction version of tdb_expand(). */ static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { const char buf_zero[8192] = {0}; size_t buf_len = sizeof(buf_zero); while (addition > 0) { size_t n = MIN(addition, buf_len); int ret; ret = transaction_write(tdb, size, buf_zero, n); if (ret != 0) { return ret; } addition -= n; size += n; } tdb->transaction->expanded = true; return 0; } static const struct tdb_methods transaction_methods = { transaction_read, transaction_write, transaction_next_hash_chain, transaction_oob, transaction_expand_file, }; /* * Is a transaction currently active on this context? * */ _PUBLIC_ bool tdb_transaction_active(struct tdb_context *tdb) { return (tdb->transaction != NULL); } /* start a tdb transaction. No token is returned, as only a single transaction is allowed to be pending per tdb_context */ static int _tdb_transaction_start(struct tdb_context *tdb, enum tdb_lock_flags lockflags) { /* some sanity checks */ if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n")); tdb->ecode = TDB_ERR_EINVAL; return -1; } /* cope with nested tdb_transaction_start() calls */ if (tdb->transaction != NULL) { if (!(tdb->flags & TDB_ALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; return -1; } tdb->transaction->nesting++; TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", tdb->transaction->nesting)); return 0; } if (tdb_have_extra_locks(tdb)) { /* the caller must not have any locks when starting a transaction as otherwise we'll be screwed by lack of nested locks in posix */ TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n")); tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->travlocks.next != NULL) { /* you cannot use transactions inside a traverse (although you can use traverse inside a transaction) as otherwise you can end up with deadlock */ TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n")); tdb->ecode = TDB_ERR_LOCK; return -1; } tdb->transaction = (struct tdb_transaction *) calloc(sizeof(struct tdb_transaction), 1); if (tdb->transaction == NULL) { tdb->ecode = TDB_ERR_OOM; return -1; } /* a page at a time seems like a reasonable compromise between compactness and efficiency */ tdb->transaction->block_size = tdb->page_size; /* get the transaction write lock. This is a blocking lock. As discussed with Volker, there are a number of ways we could make this async, which we will probably do in the future */ if (tdb_transaction_lock(tdb, F_WRLCK, lockflags) == -1) { SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction); if ((lockflags & TDB_LOCK_WAIT) == 0) { tdb->ecode = TDB_ERR_NOLOCK; } else { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: " "failed to get transaction lock\n")); } return -1; } /* get a read lock from the freelist to the end of file. This is upgraded to a write lock during the commit */ if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, true) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n")); goto fail_allrecord_lock; } /* setup a copy of the hash table heads so the hash scan in traverse can be fast */ tdb->transaction->hash_heads = (uint32_t *) calloc(tdb->hash_size+1, sizeof(uint32_t)); if (tdb->transaction->hash_heads == NULL) { tdb->ecode = TDB_ERR_OOM; goto fail; } if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads, TDB_HASHTABLE_SIZE(tdb), 0) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n")); tdb->ecode = TDB_ERR_IO; goto fail; } /* make sure we know about any file expansions already done by anyone else */ tdb_oob(tdb, tdb->map_size, 1, 1); tdb->transaction->old_map_size = tdb->map_size; /* finally hook the io methods, replacing them with transaction specific methods */ tdb->transaction->io_methods = tdb->methods; tdb->methods = &transaction_methods; /* Trace at the end, so we get sequence number correct. */ tdb_trace(tdb, "tdb_transaction_start"); return 0; fail: tdb_allrecord_unlock(tdb, F_RDLCK, false); fail_allrecord_lock: tdb_transaction_unlock(tdb, F_WRLCK); SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return -1; } _PUBLIC_ int tdb_transaction_start(struct tdb_context *tdb) { return _tdb_transaction_start(tdb, TDB_LOCK_WAIT); } _PUBLIC_ int tdb_transaction_start_nonblock(struct tdb_context *tdb) { return _tdb_transaction_start(tdb, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); } /* sync to disk */ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) { if (tdb->flags & TDB_NOSYNC) { return 0; } #ifdef HAVE_FDATASYNC if (fdatasync(tdb->fd) != 0) { #else if (fsync(tdb->fd) != 0) { #endif tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); return -1; } #ifdef HAVE_MMAP if (tdb->map_ptr) { tdb_off_t moffset = offset & ~(tdb->page_size-1); if (msync(moffset + (char *)tdb->map_ptr, length + (offset - moffset), MS_SYNC) != 0) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", strerror(errno))); return -1; } } #endif return 0; } static int _tdb_transaction_cancel(struct tdb_context *tdb) { uint32_t i; int ret = 0; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); return -1; } if (tdb->transaction->nesting != 0) { tdb->transaction->transaction_error = 1; tdb->transaction->nesting--; return 0; } tdb->map_size = tdb->transaction->old_map_size; /* free all the transaction blocks */ for (i=0;itransaction->num_blocks;i++) { if ((tdb->transaction->blocks != NULL) && tdb->transaction->blocks[i] != NULL) { free(tdb->transaction->blocks[i]); } } SAFE_FREE(tdb->transaction->blocks); if (tdb->transaction->magic_offset) { const struct tdb_methods *methods = tdb->transaction->io_methods; const uint32_t invalid = TDB_RECOVERY_INVALID_MAGIC; /* remove the recovery marker */ if (methods->tdb_write(tdb, tdb->transaction->magic_offset, &invalid, 4) == -1 || transaction_sync(tdb, tdb->transaction->magic_offset, 4) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_cancel: failed to remove recovery magic\n")); ret = -1; } } /* This also removes the OPEN_LOCK, if we have it. */ tdb_release_transaction_locks(tdb); /* restore the normal io methods */ tdb->methods = tdb->transaction->io_methods; SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return ret; } /* cancel the current transaction */ _PUBLIC_ int tdb_transaction_cancel(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_transaction_cancel"); return _tdb_transaction_cancel(tdb); } /* work out how much space the linearised recovery data will consume */ static bool tdb_recovery_size(struct tdb_context *tdb, tdb_len_t *result) { tdb_len_t recovery_size = 0; uint32_t i; recovery_size = sizeof(uint32_t); for (i=0;itransaction->num_blocks;i++) { tdb_len_t block_size; if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { break; } if (tdb->transaction->blocks[i] == NULL) { continue; } if (!tdb_add_len_t(recovery_size, 2*sizeof(tdb_off_t), &recovery_size)) { return false; } if (i == tdb->transaction->num_blocks-1) { block_size = tdb->transaction->last_block_size; } else { block_size = tdb->transaction->block_size; } if (!tdb_add_len_t(recovery_size, block_size, &recovery_size)) { return false; } } *result = recovery_size; return true; } int tdb_recovery_area(struct tdb_context *tdb, const struct tdb_methods *methods, tdb_off_t *recovery_offset, struct tdb_record *rec) { int ret; if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, recovery_offset) == -1) { return -1; } if (*recovery_offset == 0) { rec->rec_len = 0; return 0; } if (methods->tdb_read(tdb, *recovery_offset, rec, sizeof(*rec), DOCONV()) == -1) { return -1; } /* ignore invalid recovery regions: can happen in crash */ if (rec->magic != TDB_RECOVERY_MAGIC && rec->magic != TDB_RECOVERY_INVALID_MAGIC) { *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; } /* allocate the recovery area, or use an existing recovery area if it is large enough */ static int tdb_recovery_allocate(struct tdb_context *tdb, tdb_len_t *recovery_size, tdb_off_t *recovery_offset, tdb_len_t *recovery_max_size) { struct tdb_record rec; const struct tdb_methods *methods = tdb->transaction->io_methods; tdb_off_t recovery_head, new_end; if (tdb_recovery_area(tdb, methods, &recovery_head, &rec) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); return -1; } if (!tdb_recovery_size(tdb, recovery_size)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " "overflow recovery size\n")); return -1; } /* Existing recovery area? */ if (recovery_head != 0 && *recovery_size <= rec.rec_len) { /* it fits in the existing area */ *recovery_max_size = rec.rec_len; *recovery_offset = recovery_head; return 0; } /* If recovery area in middle of file, we need a new one. */ if (recovery_head == 0 || recovery_head + sizeof(rec) + rec.rec_len != tdb->map_size) { /* we need to free up the old recovery area, then allocate a new one at the end of the file. Note that we cannot use tdb_allocate() to allocate the new one as that might return us an area that is being currently used (as of the start of the transaction) */ if (recovery_head) { if (tdb_free(tdb, recovery_head, &rec) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to" " free previous recovery area\n")); return -1; } /* the tdb_free() call might have increased * the recovery size */ if (!tdb_recovery_size(tdb, recovery_size)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " "overflow recovery size\n")); return -1; } } /* New head will be at end of file. */ recovery_head = tdb->map_size; } /* Now we know where it will be. */ *recovery_offset = recovery_head; /* Expand by more than we need, so we don't do it often. */ *recovery_max_size = tdb_expand_adjust(tdb->map_size, *recovery_size, tdb->page_size) - sizeof(rec); if (!tdb_add_off_t(recovery_head, sizeof(rec), &new_end) || !tdb_add_off_t(new_end, *recovery_max_size, &new_end)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " "overflow recovery area\n")); return -1; } if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, new_end - tdb->transaction->old_map_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); return -1; } /* remap the file (if using mmap) */ methods->tdb_oob(tdb, tdb->map_size, 1, 1); /* we have to reset the old map size so that we don't try to expand the file again in the transaction commit, which would destroy the recovery area */ tdb->transaction->old_map_size = tdb->map_size; /* write the recovery header offset and sync - we can sync without a race here as the magic ptr in the recovery record has not been set */ CONVERT(recovery_head); if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; } if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; } return 0; } /* setup the recovery data that will be used on a crash during commit */ static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t *magic_offset) { tdb_len_t recovery_size; unsigned char *data, *p; const struct tdb_methods *methods = tdb->transaction->io_methods; struct tdb_record *rec; 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; /* check that the recovery area has enough space */ if (tdb_recovery_allocate(tdb, &recovery_size, &recovery_offset, &recovery_max_size) == -1) { return -1; } rec = malloc(recovery_size + sizeof(*rec)); if (rec == NULL) { tdb->ecode = TDB_ERR_OOM; return -1; } memset(rec, 0, sizeof(*rec)); rec->magic = TDB_RECOVERY_INVALID_MAGIC; rec->data_len = recovery_size; rec->rec_len = recovery_max_size; 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); for (i=0;itransaction->num_blocks;i++) { tdb_off_t offset; tdb_len_t length; if (tdb->transaction->blocks[i] == NULL) { continue; } offset = i * tdb->transaction->block_size; length = tdb->transaction->block_size; if (i == tdb->transaction->num_blocks-1) { length = tdb->transaction->last_block_size; } if (offset >= old_map_size) { continue; } if (offset + length > tdb->transaction->old_map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); free(data); tdb->ecode = TDB_ERR_CORRUPT; return -1; } memcpy(p, &offset, 4); memcpy(p+4, &length, 4); if (DOCONV()) { tdb_convert(p, 8); } /* the recovery area contains the old data, not the new data, so we have to call the original tdb_read method to get it */ if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { free(data); tdb->ecode = TDB_ERR_IO; return -1; } p += 8 + length; } /* and the tailer */ tailer = sizeof(*rec) + recovery_max_size; memcpy(p, &tailer, 4); if (DOCONV()) { tdb_convert(p, 4); } /* write the recovery data to the recovery area */ if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n")); free(data); tdb->ecode = TDB_ERR_IO; return -1; } if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); free(data); tdb->ecode = TDB_ERR_IO; return -1; } /* as we don't have ordered writes, we have to sync the recovery data before we update the magic to indicate that the recovery data is present */ if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { free(data); return -1; } free(data); magic = TDB_RECOVERY_MAGIC; CONVERT(magic); *magic_offset = recovery_offset + offsetof(struct tdb_record, magic); if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); tdb->ecode = TDB_ERR_IO; return -1; } /* ensure the recovery magic marker is on disk */ if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { return -1; } return 0; } static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) { const struct tdb_methods *methods; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: no transaction\n")); return -1; } if (tdb->transaction->prepared) { tdb->ecode = TDB_ERR_EINVAL; _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction already prepared\n")); return -1; } if (tdb->transaction->transaction_error) { tdb->ecode = TDB_ERR_IO; _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction error pending\n")); return -1; } if (tdb->transaction->nesting != 0) { return 0; } /* check for a null transaction */ if (tdb->transaction->blocks == NULL) { return 0; } methods = tdb->transaction->io_methods; /* if there are any locks pending then the caller has not nested their locks properly, so fail the transaction */ if (tdb_have_extra_locks(tdb)) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: locks pending on commit\n")); _tdb_transaction_cancel(tdb); return -1; } /* upgrade the main transaction lock region to a write lock */ if (tdb_allrecord_upgrade(tdb) == -1) { if (tdb->ecode == TDB_ERR_RDONLY && tdb->read_only) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: " "failed to upgrade hash locks: " "database is read only\n")); } else if (tdb->ecode == TDB_ERR_RDONLY && tdb->traverse_read) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: " "failed to upgrade hash locks: " "a database traverse is in progress\n")); } else { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: " "failed to upgrade hash locks: %s\n", tdb_errorstr(tdb))); } _tdb_transaction_cancel(tdb); return -1; } /* get the open lock - this prevents new users attaching to the database during the commit */ if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to get open lock\n")); _tdb_transaction_cancel(tdb); return -1; } /* write the recovery data to the end of the file */ if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: failed to setup recovery data\n")); _tdb_transaction_cancel(tdb); return -1; } tdb->transaction->prepared = true; /* expand the file to the new size if needed */ if (tdb->map_size != tdb->transaction->old_map_size) { if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, tdb->map_size - tdb->transaction->old_map_size) == -1) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: expansion failed\n")); _tdb_transaction_cancel(tdb); return -1; } tdb->map_size = tdb->transaction->old_map_size; methods->tdb_oob(tdb, tdb->map_size, 1, 1); } /* Keep the open lock until the actual commit */ return 0; } /* prepare to commit the current transaction */ _PUBLIC_ int tdb_transaction_prepare_commit(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_transaction_prepare_commit"); return _tdb_transaction_prepare_commit(tdb); } /* A repack is worthwhile if the largest is less than half total free. */ static bool repack_worthwhile(struct tdb_context *tdb) { tdb_off_t ptr; struct tdb_record rec; tdb_len_t total = 0, largest = 0; if (tdb_ofs_read(tdb, FREELIST_TOP, &ptr) == -1) { return false; } while (ptr != 0 && tdb_rec_free_read(tdb, ptr, &rec) == 0) { total += rec.rec_len; if (rec.rec_len > largest) { largest = rec.rec_len; } ptr = rec.next; } return total > largest * 2; } /* commit the current transaction */ _PUBLIC_ int tdb_transaction_commit(struct tdb_context *tdb) { const struct tdb_methods *methods; uint32_t i; bool need_repack = false; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); return -1; } tdb_trace(tdb, "tdb_transaction_commit"); if (tdb->transaction->transaction_error) { tdb->ecode = TDB_ERR_IO; _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n")); return -1; } if (tdb->transaction->nesting != 0) { tdb->transaction->nesting--; return 0; } /* check for a null transaction */ if (tdb->transaction->blocks == NULL) { _tdb_transaction_cancel(tdb); return 0; } if (!tdb->transaction->prepared) { int ret = _tdb_transaction_prepare_commit(tdb); if (ret) return ret; } methods = tdb->transaction->io_methods; /* perform all the writes */ for (i=0;itransaction->num_blocks;i++) { tdb_off_t offset; tdb_len_t length; if (tdb->transaction->blocks[i] == NULL) { continue; } offset = i * tdb->transaction->block_size; length = tdb->transaction->block_size; if (i == tdb->transaction->num_blocks-1) { length = tdb->transaction->last_block_size; } if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); /* we've overwritten part of the data and possibly expanded the file, so we need to run the crash recovery code */ tdb->methods = methods; tdb_transaction_recover(tdb); _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); return -1; } SAFE_FREE(tdb->transaction->blocks[i]); } /* Do this before we drop lock or blocks. */ if (tdb->transaction->expanded) { need_repack = repack_worthwhile(tdb); } SAFE_FREE(tdb->transaction->blocks); tdb->transaction->num_blocks = 0; /* ensure the new data is on disk */ if (transaction_sync(tdb, 0, tdb->map_size) == -1) { return -1; } /* TODO: maybe write to some dummy hdr field, or write to magic offset without mmap, before the last sync, instead of the utime() call */ /* on some systems (like Linux 2.6.x) changes via mmap/msync don't change the mtime of the file, this means the file may not be backed up (as tdb rounding to block sizes means that file size changes are quite rare too). The following forces mtime changes when a transaction completes */ #ifdef HAVE_UTIME utime(tdb->name, NULL); #endif /* use a transaction cancel to free memory and remove the transaction locks */ _tdb_transaction_cancel(tdb); if (need_repack) { int ret = tdb_repack(tdb); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to repack database (not fatal)\n")); } /* * Ignore the error. * * Why? * * We just committed to the DB above, so anything * written during the transaction is committed, the * caller needs to know that the long-term state was * successfully modified. * * tdb_repack is an optimization that can fail for * reasons like lock ordering and we cannot recover * the transaction lock at this point, having released * it above. * * If we return a failure the caller thinks the * transaction was rolled back. */ } return 0; } /* recover from an aborted transaction. Must be called with exclusive database write access already established (including the open lock to prevent new processes attaching) */ int tdb_transaction_recover(struct tdb_context *tdb) { tdb_off_t recovery_head, recovery_eof; unsigned char *data, *p; uint32_t zero = 0; struct tdb_record rec; /* find the recovery area */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (recovery_head == 0) { /* we have never allocated a recovery record */ return 0; } /* read the recovery record */ if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (rec.magic != TDB_RECOVERY_MAGIC) { /* there is no valid recovery data */ return 0; } if (tdb->read_only) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n")); tdb->ecode = TDB_ERR_CORRUPT; return -1; } recovery_eof = rec.key_len; data = (unsigned char *)malloc(rec.data_len); if (data == NULL) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); tdb->ecode = TDB_ERR_OOM; return -1; } /* read the full recovery data */ if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, rec.data_len, 0) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); tdb->ecode = TDB_ERR_IO; return -1; } /* recover the file data */ p = data; while (p+8 < data + rec.data_len) { uint32_t ofs, len; if (DOCONV()) { tdb_convert(p, 8); } memcpy(&ofs, p, 4); memcpy(&len, p+4, 4); if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) { free(data); TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %u bytes at offset %u\n", len, ofs)); tdb->ecode = TDB_ERR_IO; return -1; } p += 8 + len; } free(data); if (transaction_sync(tdb, 0, tdb->map_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n")); tdb->ecode = TDB_ERR_IO; return -1; } /* if the recovery area is after the recovered eof then remove it */ if (recovery_eof <= recovery_head) { if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); tdb->ecode = TDB_ERR_IO; return -1; } } /* remove the recovery magic */ if (tdb_ofs_write(tdb, recovery_head + offsetof(struct tdb_record, magic), &zero) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (transaction_sync(tdb, 0, recovery_eof) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n")); tdb->ecode = TDB_ERR_IO; return -1; } TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %u byte database\n", recovery_eof)); /* all done */ return 0; } /* Any I/O failures we say "needs recovery". */ bool tdb_needs_recovery(struct tdb_context *tdb) { tdb_off_t recovery_head; struct tdb_record rec; /* find the recovery area */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { return true; } if (recovery_head == 0) { /* we have never allocated a recovery record */ return false; } /* read the recovery record */ if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { return true; } return (rec.magic == TDB_RECOVERY_MAGIC); } ldb-2.0.8/lib/tdb/common/traverse.c0000660000000000000000000003312613573675413017047 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" #define TDB_NEXT_LOCK_ERR ((tdb_off_t)-1) /* Uses traverse lock: 0 = finish, TDB_NEXT_LOCK_ERR = error, other = record offset */ static tdb_off_t tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock, struct tdb_record *rec) { int want_next = (tlock->off != 0); /* Lock each chain from the start one. */ for (; tlock->list < tdb->hash_size; tlock->list++) { if (!tlock->off && tlock->list != 0) { /* this is an optimisation for the common case where the hash chain is empty, which is particularly common for the use of tdb with ldb, where large hashes are used. In that case we spend most of our time in tdb_brlock(), locking empty hash chains. To avoid this, we do an unlocked pre-check to see if the hash chain is empty before starting to look inside it. If it is empty then we can avoid that hash chain. If it isn't empty then we can't believe the value we get back, as we read it without a lock, so instead we get the lock and re-fetch the value below. Notice that not doing this optimisation on the first hash chain is critical. We must guarantee that we have done at least one fcntl lock at the start of a search to guarantee that memory is coherent on SMP systems. If records are added by others during the search then thats OK, and we could possibly miss those with this trick, but we could miss them anyway without this trick, so the semantics don't change. With a non-indexed ldb search this trick gains us a factor of around 80 in speed on a linux 2.6.x system (testing using ldbtest). */ tdb->methods->next_hash_chain(tdb, &tlock->list); if (tlock->list == tdb->hash_size) { continue; } } if (tdb_lock(tdb, tlock->list, tlock->lock_rw) == -1) return TDB_NEXT_LOCK_ERR; /* No previous record? Start at top of chain. */ if (!tlock->off) { if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->list), &tlock->off) == -1) goto fail; } else { /* Otherwise unlock the previous record. */ if (tdb_unlock_record(tdb, tlock->off) != 0) goto fail; } if (want_next) { /* We have offset of old record: grab next */ if (tdb_rec_read(tdb, tlock->off, rec) == -1) goto fail; tlock->off = rec->next; } /* Iterate through chain */ while( tlock->off) { if (tdb_rec_read(tdb, tlock->off, rec) == -1) goto fail; /* Detect infinite loops. From "Shlomi Yaakobovich" . */ if (tlock->off == rec->next) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n")); goto fail; } if (!TDB_DEAD(rec)) { /* Woohoo: we found one! */ if (tdb_lock_record(tdb, tlock->off) != 0) goto fail; return tlock->off; } tlock->off = rec->next; } tdb_unlock(tdb, tlock->list, tlock->lock_rw); want_next = 0; } /* We finished iteration without finding anything */ tdb->ecode = TDB_SUCCESS; return 0; fail: tlock->off = 0; if (tdb_unlock(tdb, tlock->list, tlock->lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n")); return TDB_NEXT_LOCK_ERR; } /* traverse the entire database - calling fn(tdb, key, data) on each element. return -1 on error or the record count traversed if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop */ static int tdb_traverse_internal(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data, struct tdb_traverse_lock *tl) { TDB_DATA key, dbuf; struct tdb_record rec; int ret = 0, count = 0; tdb_off_t off; size_t recbuf_len; recbuf_len = 4096; key.dptr = malloc(recbuf_len); if (key.dptr == NULL) { return -1; } /* This was in the initialization, above, but the IRIX compiler * did not like it. crh */ tl->next = tdb->travlocks.next; /* fcntl locks don't stack: beware traverse inside traverse */ tdb->travlocks.next = tl; /* 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; 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; /* * No realloc, we don't need the old data and thus can * do without the memcpy */ free(key.dptr); key.dptr = malloc(recbuf_len); if (key.dptr == NULL) { ret = -1; if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) { goto out; } if (tdb_unlock_record(tdb, tl->off) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: malloc " "failed and unlock_record " "failed!\n")); } goto out; } } count++; /* now read the full record */ nread = tdb->methods->tdb_read(tdb, tl->off + sizeof(rec), key.dptr, full_len, 0); if (nread == -1) { ret = -1; if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) goto out; if (tdb_unlock_record(tdb, tl->off) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); goto out; } key.dsize = rec.key_len; dbuf.dptr = key.dptr + rec.key_len; dbuf.dsize = rec.data_len; tdb_trace_1rec_retrec(tdb, "traverse", key, dbuf); /* Drop chain lock, call out */ if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) { ret = -1; goto out; } if (fn && fn(tdb, key, dbuf, private_data)) { /* They want us to terminate traversal */ tdb_trace_ret(tdb, "tdb_traverse_end", count); if (tdb_unlock_record(tdb, tl->off) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; ret = -1; } goto out; } } tdb_trace(tdb, "tdb_traverse_end"); out: SAFE_FREE(key.dptr); tdb->travlocks.next = tl->next; if (ret < 0) return -1; else return count; } /* a read style traverse - temporarily marks each record read only */ _PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; int ret; tdb->traverse_read++; tdb_trace(tdb, "tdb_traverse_read_start"); ret = tdb_traverse_internal(tdb, fn, private_data, &tl); tdb->traverse_read--; return ret; } /* a write style traverse - needs to get the transaction lock to prevent deadlocks WARNING: The data buffer given to the callback fn does NOT meet the alignment guarantees malloc gives you. */ _PUBLIC_ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; enum tdb_lock_flags lock_flags; int ret; if (tdb->read_only || tdb->traverse_read) { return tdb_traverse_read(tdb, fn, private_data); } lock_flags = TDB_LOCK_WAIT; if (tdb->allrecord_lock.count != 0) { /* * This avoids a deadlock between tdb_lockall() and * tdb_traverse(). See * https://bugzilla.samba.org/show_bug.cgi?id=11381 */ lock_flags = TDB_LOCK_NOWAIT; } if (tdb_transaction_lock(tdb, F_WRLCK, lock_flags)) { return -1; } tdb->traverse_write++; tdb_trace(tdb, "tdb_traverse_start"); ret = tdb_traverse_internal(tdb, fn, private_data, &tl); tdb->traverse_write--; tdb_transaction_unlock(tdb, F_WRLCK); return ret; } /* find the first entry in the database and return its key */ _PUBLIC_ TDB_DATA tdb_firstkey(struct tdb_context *tdb) { TDB_DATA key; struct tdb_record rec; tdb_off_t off; /* release any old lock */ if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) return tdb_null; tdb->travlocks.off = tdb->travlocks.list = 0; tdb->travlocks.lock_rw = F_RDLCK; /* Grab first record: locks chain and returned record. */ off = tdb_next_lock(tdb, &tdb->travlocks, &rec); if (off == 0 || off == TDB_NEXT_LOCK_ERR) { tdb_trace_retrec(tdb, "tdb_firstkey", tdb_null); return tdb_null; } /* now read the key */ key.dsize = rec.key_len; key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); tdb_trace_retrec(tdb, "tdb_firstkey", key); /* Unlock the hash chain of the record we just read. */ if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); return key; } /* find the next entry in the database, returning its key */ _PUBLIC_ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) { uint32_t oldlist; TDB_DATA key = tdb_null; struct tdb_record rec; unsigned char *k = NULL; tdb_off_t off; /* Is locked key the old key? If so, traverse will be reliable. */ if (tdb->travlocks.off) { if (tdb_lock(tdb,tdb->travlocks.list,tdb->travlocks.lock_rw)) return tdb_null; if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), rec.key_len)) || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { /* No, it wasn't: unlock it and start from scratch */ if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) { tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, tdb_null); SAFE_FREE(k); return tdb_null; } if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) { SAFE_FREE(k); return tdb_null; } tdb->travlocks.off = 0; } SAFE_FREE(k); } if (!tdb->travlocks.off) { /* No previous element: do normal find, and lock record */ tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); if (!tdb->travlocks.off) { tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, tdb_null); return tdb_null; } tdb->travlocks.list = BUCKET(rec.full_hash); if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); return tdb_null; } } oldlist = tdb->travlocks.list; /* Grab next record: locks chain and returned record, unlocks old record */ off = tdb_next_lock(tdb, &tdb->travlocks, &rec); if (off != TDB_NEXT_LOCK_ERR && off != 0) { key.dsize = rec.key_len; key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), key.dsize); /* Unlock the chain of this new record */ if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); } /* Unlock the chain of old record */ if (tdb_unlock(tdb, oldlist, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, key); return key; } _PUBLIC_ int tdb_traverse_chain(struct tdb_context *tdb, unsigned chain, tdb_traverse_func fn, void *private_data) { tdb_off_t rec_ptr; struct tdb_chainwalk_ctx chainwalk; int count = 0; int ret; if (chain >= tdb->hash_size) { tdb->ecode = TDB_ERR_EINVAL; return -1; } if (tdb->traverse_read != 0) { tdb->ecode = TDB_ERR_LOCK; return -1; } ret = tdb_lock(tdb, chain, F_RDLCK); if (ret == -1) { return -1; } tdb->traverse_read += 1; ret = tdb_ofs_read(tdb, TDB_HASH_TOP(chain), &rec_ptr); if (ret == -1) { goto fail; } tdb_chainwalk_init(&chainwalk, rec_ptr); while (rec_ptr != 0) { struct tdb_record rec; bool ok; ret = tdb_rec_read(tdb, rec_ptr, &rec); if (ret == -1) { goto fail; } if (!TDB_DEAD(&rec)) { /* no overflow checks, tdb_rec_read checked it */ tdb_off_t key_ofs = rec_ptr + sizeof(rec); size_t full_len = rec.key_len + rec.data_len; uint8_t *buf = NULL; TDB_DATA key = { .dsize = rec.key_len }; TDB_DATA data = { .dsize = rec.data_len }; if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { ret = tdb_oob(tdb, key_ofs, full_len, 0); if (ret == -1) { goto fail; } key.dptr = (uint8_t *)tdb->map_ptr + key_ofs; } else { buf = tdb_alloc_read(tdb, key_ofs, full_len); if (buf == NULL) { goto fail; } key.dptr = buf; } data.dptr = key.dptr + key.dsize; ret = fn(tdb, key, data, private_data); free(buf); count += 1; if (ret != 0) { break; } } rec_ptr = rec.next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { goto fail; } } tdb->traverse_read -= 1; tdb_unlock(tdb, chain, F_RDLCK); return count; fail: tdb->traverse_read -= 1; tdb_unlock(tdb, chain, F_RDLCK); return -1; } _PUBLIC_ int tdb_traverse_key_chain(struct tdb_context *tdb, TDB_DATA key, tdb_traverse_func fn, void *private_data) { uint32_t hash, chain; int ret; hash = tdb->hash_fn(&key); chain = BUCKET(hash); ret = tdb_traverse_chain(tdb, chain, fn, private_data); return ret; } ldb-2.0.8/lib/tdb/configure0000770000000000000000000000066013573675413015463 0ustar rootroot00000000000000#!/bin/sh PREVPATH=`dirname $0` if [ -f $PREVPATH/../../buildtools/bin/waf ]; then WAF=../../buildtools/bin/waf elif [ -f $PREVPATH/buildtools/bin/waf ]; then WAF=./buildtools/bin/waf else echo "replace: Unable to find waf" exit 1 fi # using JOBS=1 gives maximum compatibility with # systems like AIX which have broken threading in python JOBS=1 export JOBS cd . || exit 1 $PYTHON $WAF configure "$@" || exit 1 cd $PREVPATH ldb-2.0.8/lib/tdb/docs/README0000660000000000000000000002446013573675413015371 0ustar rootroot00000000000000tdb - a trivial database system tridge@linuxcare.com December 1999 ================================== This is a simple database API. It was inspired by the realisation that in Samba we have several ad-hoc bits of code that essentially implement small databases for sharing structures between parts of Samba. As I was about to add another I realised that a generic database module was called for to replace all the ad-hoc bits. I based the interface on gdbm. I couldn't use gdbm as we need to be able to have multiple writers to the databases at one time. Compilation ----------- add HAVE_MMAP=1 to use mmap instead of read/write add NOLOCK=1 to disable locking code Testing ------- Compile tdbtest.c and link with gdbm for testing. tdbtest will perform identical operations via tdb and gdbm then make sure the result is the same Also included is tdbtool, which allows simple database manipulation on the commandline. tdbtest and tdbtool are not built as part of Samba, but are included for completeness. Interface --------- The interface is very similar to gdbm except for the following: - different open interface. The tdb_open call is more similar to a traditional open() - no tdbm_reorganise() function - no tdbm_sync() function. No operations are cached in the library anyway - added a tdb_traverse() function for traversing the whole database - added transactions support A general rule for using tdb is that the caller frees any returned TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA return value called p. This is the same as gdbm. here is a full list of tdb functions with brief descriptions. ---------------------------------------------------------------------- TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the database file. A flags value of O_WRONLY is invalid The hash size is advisory, use zero for a default value. return is NULL on error possible tdb_flags are: TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open TDB_INTERNAL - don't use a file, instead store the data in memory. The filename is ignored in this case. TDB_NOLOCK - don't do any locking TDB_NOMMAP - don't use mmap TDB_NOSYNC - don't synchronise transactions to disk TDB_SEQNUM - maintain a sequence number TDB_VOLATILE - activate the per-hashchain freelist, default 5 TDB_ALLOW_NESTING - allow transactions to nest TDB_DISALLOW_NESTING - disallow transactions to nest ---------------------------------------------------------------------- TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn) This is like tdb_open(), but allows you to pass an initial logging and hash function. Be careful when passing a hash function - all users of the database must use the same hash function or you will get data corruption. ---------------------------------------------------------------------- char *tdb_error(TDB_CONTEXT *tdb); return a error string for the last tdb error ---------------------------------------------------------------------- int tdb_close(TDB_CONTEXT *tdb); close a database ---------------------------------------------------------------------- TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); fetch an entry in the database given a key if the return value has a null dptr then a error occurred caller must free the resulting data ---------------------------------------------------------------------- int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); Hand a record to a parser function without allocating it. This function is meant as a fast tdb_fetch alternative for large records that are frequently read. The "key" and "data" arguments point directly into the tdb shared memory, they are not aligned at any boundary. WARNING: The parser is called while tdb holds a lock on the record. DO NOT call other tdb routines from within the parser. Also, for good performance you should make the parser fast to allow parallel operations. tdb_parse_record returns -1 if the record was not found. If the record was found, the return value of "parser" is passed up to the caller. ---------------------------------------------------------------------- int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); check if an entry in the database exists note that 1 is returned if the key is found and 0 is returned if not found this doesn't match the conventions in the rest of this module, but is compatible with gdbm ---------------------------------------------------------------------- int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state), void *state); traverse the entire database - calling fn(tdb, key, data, state) on each element. return -1 on error or the record count traversed if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop. Traversal callbacks may not start transactions. WARNING: The data buffer given to the callback fn does NOT meet the alignment restrictions malloc gives you. ---------------------------------------------------------------------- int tdb_traverse_read(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state), void *state); traverse the entire database - calling fn(tdb, key, data, state) on each element, but marking the database read only during the traversal, so any write operations will fail. This allows tdb to use read locks, which increases the parallelism possible during the traversal. return -1 on error or the record count traversed if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop. Traversal callbacks may not start transactions. ---------------------------------------------------------------------- TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); find the first entry in the database and return its key the caller must free the returned data ---------------------------------------------------------------------- TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); find the next entry in the database, returning its key the caller must free the returned data ---------------------------------------------------------------------- int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); delete an entry in the database given a key ---------------------------------------------------------------------- int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); store an element in the database, replacing any existing element with the same key If flag==TDB_INSERT then don't overwrite an existing entry If flag==TDB_MODIFY then don't create a new entry return 0 on success, -1 on failure ---------------------------------------------------------------------- int tdb_writelock(TDB_CONTEXT *tdb); lock the database. If we already have it locked then don't do anything ---------------------------------------------------------------------- int tdb_writeunlock(TDB_CONTEXT *tdb); unlock the database ---------------------------------------------------------------------- int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); lock one hash chain. This is meant to be used to reduce locking contention - it cannot guarantee how many records will be locked ---------------------------------------------------------------------- int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); unlock one hash chain ---------------------------------------------------------------------- int tdb_transaction_start(TDB_CONTEXT *tdb) start a transaction. All operations after the transaction start can either be committed with tdb_transaction_commit() or cancelled with tdb_transaction_cancel(). If you call tdb_transaction_start() again on the same tdb context while a transaction is in progress, then the same transaction buffer is re-used. The number of tdb_transaction_{commit,cancel} operations must match the number of successful tdb_transaction_start() calls. Note that transactions are by default disk synchronous, and use a recover area in the database to automatically recover the database on the next open if the system crashes during a transaction. You can disable the synchronous transaction recovery setup using the TDB_NOSYNC flag, which will greatly speed up operations at the risk of corrupting your database if the system crashes. Operations made within a transaction are not visible to other users of the database until a successful commit. ---------------------------------------------------------------------- int tdb_transaction_cancel(TDB_CONTEXT *tdb) cancel a current transaction, discarding all write and lock operations that have been made since the transaction started. ---------------------------------------------------------------------- int tdb_transaction_commit(TDB_CONTEXT *tdb) commit a current transaction, updating the database and releasing the transaction locks. ---------------------------------------------------------------------- int tdb_transaction_prepare_commit(TDB_CONTEXT *tdb) prepare to commit a current transaction, for two-phase commits. Once prepared for commit, the only allowed calls are tdb_transaction_commit() or tdb_transaction_cancel(). Preparing allocates disk space for the pending updates, so a subsequent commit should succeed (barring any hardware failures). ---------------------------------------------------------------------- int tdb_check(TDB_CONTEXT *tdb, int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data);) check the consistency of the database, calling back the check function (if non-NULL) with each record. If some consistency check fails, or the supplied check function returns -1, tdb_check returns -1, otherwise 0. Note that logging function (if set) will be called with additional information on the corruption found. ldb-2.0.8/lib/tdb/docs/mainpage.dox0000660000000000000000000000362712406075657017006 0ustar rootroot00000000000000/** @mainpage This is a simple database API. It was inspired by the realisation that in Samba we have several ad-hoc bits of code that essentially implement small databases for sharing structures between parts of Samba. The interface is based on gdbm. gdbm couldn't be use as we needed to be able to have multiple writers to the databases at one time. @section tdb_download Download You can download the latest releases of tdb from the tdb directory on the samba public source archive. You can download the latest code either via git or rsync. To fetch via git see the following guide: Using Git for Samba Development Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory. To fetch via rsync use these commands:
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
and build in tdb. It will find the replace library in the directory above automatically. @section tdb_bugs Discussion and bug reports tdb does not currently have its own mailing list or bug tracking system. For now, please use the samba-technical mailing list, and the Samba bugzilla bug tracking system. @section tdb_compilation Compilation add HAVE_MMAP=1 to use mmap instead of read/write add NOLOCK=1 to disable locking code @section tdb_testing Testing Compile tdbtest.c and link with gdbm for testing. tdbtest will perform identical operations via tdb and gdbm then make sure the result is the same Also included is tdbtool, which allows simple database manipulation on the commandline. tdbtest and tdbtool are not built as part of Samba, but are included for completeness. */ ldb-2.0.8/lib/tdb/docs/mutex.txt0000660000000000000000000001630312632255624016402 0ustar rootroot00000000000000Tdb is a hashtable database with multiple concurrent writer and external record lock support. For speed reasons, wherever possible tdb uses a shared memory mapped area for data access. In its currently released form, it uses fcntl byte-range locks to coordinate access to the data itself. The tdb data is organized as a hashtable. Hash collisions are dealt with by forming a linked list of records that share a hash value. The individual linked lists are protected across processes with 1-byte fcntl locks on the starting pointer of the linked list representing a hash value. The external locking API of tdb allows one to lock individual records. Instead of really locking individual records, the tdb API locks a complete linked list with a fcntl lock. The external locking API of tdb also allows one to lock the complete database, and ctdb uses this facility to freeze databases during a recovery. While the so-called allrecord lock is held, all linked lists and all individual records are frozen alltogether. Tdb achieves this by locking the complete file range with a single fcntl lock. Individual 1-byte locks for the linked lists conflict with this. Access to records is prevented by the one large fnctl byte range lock. Fcntl locks have been chosen for tdb for two reasons: First they are portable across all current unixes. Secondly they provide auto-cleanup. If a process dies while holding a fcntl lock, the lock is given up as if it was explicitly unlocked. Thus fcntl locks provide a very robust locking scheme, if a process dies for any reason the database will not stay blocked until reboot. This robustness is very important for long-running services, a reboot is not an option for most users of tdb. Unfortunately, during stress testing, fcntl locks have turned out to be a major problem for performance. The particular problem that was seen happens when ctdb on a busy server does a recovery. A recovery means that ctdb has to freeze all tdb databases for some time, usually a few seconds. This is done with the allrecord lock. During the recovery phase on a busy server many smbd processes try to access the tdb file with blocking fcntl calls. The specific test in question easily reproduces 7,000 processes piling up waiting for 1-byte fcntl locks. When ctdb is done with the recovery, it gives up the allrecord lock, covering the whole file range. All 7,000 processes waiting for 1-byte fcntl locks are woken up, trying to acquire their lock. The special implementation of fcntl locks in Linux (up to 2013-02-12 at least) protects all fcntl lock operations with a single system-wide spinlock. If 7,000 process waiting for the allrecord lock to become released this leads to a thundering herd condition, all CPUs are spinning on that single spinlock. Functionally the kernel is fine, eventually the thundering herd slows down and every process correctly gets his share and locking range, but the performance of the system while the herd is active is worse than expected. The thundering herd is only the worst case scenario for fcntl lock use. The single spinlock for fcntl operations is also a performance penalty for normal operations. In the cluster case, every read and write SMB request has to do two fcntl calls to provide correct SMB mandatory locks. The single spinlock is one source of serialization for the SMB read/write requests, limiting the parallelism that can be achieved in a multi-core system. While trying to tune his servers, Ira Cooper, Samba Team member, found fcntl locks to be a problem on Solaris as well. Ira pointed out that there is a potential alternative locking mechanism that might be more scalable: Process shared robust mutexes, as defined by Posix 2008 for example via http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html Pthread mutexes provide one of the core mechanisms in posix threads to protect in-process data structures from concurrent access by multiple threads. In the Linux implementation, a pthread_mutex_t is represented by a data structure in user space that requires no kernel calls in the uncontended case for locking and unlocking. Locking and unlocking in the uncontended case is implemented purely in user space with atomic CPU instructions and thus are very fast. The setpshared functions indicate to the kernel that the mutex is about to be shared between processes in a common shared memory area. The process shared posix mutexes have the potential to replace fcntl locking to coordinate mmap access for tdbs. However, they are missing the criticial auto-cleanup property that fcntl provides when a process dies. A process that dies hard while holding a shared mutex has no chance to clean up the protected data structures and unlock the shared mutex. Thus with a pure process shared mutex the mutex will remain locked forever until the data structures are re-initialized from scratch. With the robust mutexes defined by Posix the process shared mutexes have been extended with a limited auto-cleanup property. If a mutex has been declared robust, when a process exits while holding that mutex, the next process trying to lock the mutex will get the special error message EOWNERDEAD. This informs the caller that the data structures the mutex protects are potentially corrupt and need to be cleaned up. The error message EOWNERDEAD when trying to lock a mutex is an extension over the fcntl functionality. A process that does a blocking fcntl lock call is not informed about whether the lock was explicitly freed by a process still alive or due to an unplanned process exit. At the time of this writing (February 2013), at least Linux and OpenSolaris also implement the robustness feature of process-shared mutexes. Converting the tdb locking mechanism from fcntl to mutexes has to take care of both types of locks that are used on tdb files. The easy part is to use mutexes to replace the 1-byte linked list locks covering the individual hashes. Those can be represented by a mutex each. Covering the allrecord lock is more difficult. The allrecord lock uses a fcntl lock spanning all hash list locks simultaneously. This basic functionality is not easily possible with mutexes. A mutex carries 1 bit of information, a fcntl lock can carry an arbitrary amount of information. In order to support the allrecord lock, we have an allrecord_lock variable protected by an allrecord_mutex. The coordination between the allrecord lock and the chainlocks works like this: - Getting a chain lock works like this: 1. get chain mutex 2. return success if allrecord_lock is F_UNLCK (not locked) 3. return success if allrecord_lock is F_RDLCK (locked readonly) and we only need a read lock. 4. release chain mutex 5. wait for allrecord_mutex 6. unlock allrecord_mutex 7. goto 1. - Getting the allrecord lock: 1. get the allrecord mutex 2. return error if allrecord_lock is not F_UNLCK (it's locked) 3. set allrecord_lock to the desired value. 4. in a loop: lock(blocking) / unlock each chain mutex. 5. return success. - allrecord lock upgrade: 1. check we already have the allrecord lock with F_RDLCK. 3. set allrecord_lock to F_WRLCK 4. in a loop: lock(blocking) / unlock each chain mutex. 5. return success. ldb-2.0.8/lib/tdb/docs/tdb.magic0000660000000000000000000000053112406075657016253 0ustar rootroot00000000000000# Magic file(1) information about tdb files. # # Install this into /etc/magic or the corresponding location for your # system, or pass as a -m argument to file(1). # You may use and redistribute this file without restriction. 0 string TDB\ file TDB database >32 lelong =0x2601196D version 6, little-endian >>36 lelong x hash size %d bytes ldb-2.0.8/lib/tdb/docs/tracing.txt0000660000000000000000000000356412406075657016701 0ustar rootroot00000000000000How And Why To Use TDB Tracing ============================== You can trace all TDB operations, using TDB_TRACE. It is not complete (error conditions which expect to the logged will not always be traced correctly, so you should set up a logging function too), but is designed to collect benchmark-style traces to allow us to optimize TDB. Note: tracing is not efficient, and the trace files are huge: a traverse of the database is particularly large! But they compress very well with rzip (http://rzip.samba.org) How to gather trace files: -------------------------- 1) Uncomment /* #define TDB_TRACE 1 */ in tdb_private.h. 2) Rebuild TDB, and everything that uses it. 3) Run something. Your trace files will be called .trace.. These files will not be overwritten: if the same process reopens the same TDB, an error will be logged and tracing will be disabled. How to replay trace files: -------------------------- 1) For benchmarking, remember to rebuild tdb with #define TDB_TRACE commented out again! 2) Grab the latest "replace_trace.c" from CCAN's tdb module (tools/ dir): http://ccan.ozlabs.org/tarballs/tdb.tar.bz2 3) Compile up replay_trace, munging as necessary. 4) Run replay_trace ... If given more than one trace file (presumably from the same tdb) replay_trace will try to figure out the dependencies between the operations and fire off a child to run each trace. Occasionally it gets stuck, in which case it will add another dependency and retry. Eventually it will give a speed value. replay_trace can intuit the existence of previous data in the tdb (ie. activity prior to the trace(s) supplied) and will prepopulate as neccessary. You can run --quiet for straight benchmark results, and -n to run multiple times (this saves time, since it need only calculate dependencies once). Good luck! Rusty Russell ldb-2.0.8/lib/tdb/doxy.config0000660000000000000000000021316112406075657015727 0ustar rootroot00000000000000# Doxyfile 1.7.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = tdb # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 1.2.9 # Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = docs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = include \ docs # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [0,1..20]) # that doxygen will group on one line in the generated HTML documentation. # Note that a value of 0 will completely suppress the enum values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NONE # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN \ PRINTF_ATTRIBUTE(x,y)= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called Helvetica to the output # directory and reference it in all dot files that doxygen generates. # When you want a differently looking font you can specify the font name # using DOT_FONTNAME. You need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, svg, gif or svg. # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES ldb-2.0.8/lib/tdb/include/tdb.h0000660000000000000000000010203513573675413016121 0ustar rootroot00000000000000#ifndef __TDB_H__ #define __TDB_H__ /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2004 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #ifdef __cplusplus extern "C" { #endif #include #include /** * @defgroup tdb The tdb API * * tdb is a Trivial database. In concept, it is very much like GDBM, and BSD's * DB except that it allows multiple simultaneous writers and uses locking * internally to keep writers from trampling on each other. tdb is also * extremely small. * * @section tdb_interface Interface * * The interface is very similar to gdbm except for the following: * *
    *
  • different open interface. The tdb_open call is more similar to a * traditional open()
  • *
  • no tdbm_reorganise() function
  • *
  • no tdbm_sync() function. No operations are cached in the library * anyway
  • *
  • added a tdb_traverse() function for traversing the whole database
  • *
  • added transactions support
  • *
* * A general rule for using tdb is that the caller frees any returned TDB_DATA * structures. Just call free(p.dptr) to free a TDB_DATA return value called p. * This is the same as gdbm. * * @{ */ /** Flags to tdb_store() */ #define TDB_REPLACE 1 /** Unused */ #define TDB_INSERT 2 /** Don't overwrite an existing entry */ #define TDB_MODIFY 3 /** Don't create an existing entry */ /** Flags for tdb_open() */ #define TDB_DEFAULT 0 /** just a readability place holder */ #define TDB_CLEAR_IF_FIRST 1 /** If this is the first open, wipe the db */ #define TDB_INTERNAL 2 /** Don't store on disk */ #define TDB_NOLOCK 4 /** Don't do any locking */ #define TDB_NOMMAP 8 /** Don't use mmap */ #define TDB_CONVERT 16 /** Convert endian (internal use) */ #define TDB_BIGENDIAN 32 /** Header is big-endian (internal use) */ #define TDB_NOSYNC 64 /** Don't use synchronous transactions */ #define TDB_SEQNUM 128 /** Maintain a sequence number */ #define TDB_VOLATILE 256 /** Activate the per-hashchain freelist, default 5 */ #define TDB_ALLOW_NESTING 512 /** Allow transactions to nest */ #define TDB_DISALLOW_NESTING 1024 /** Disallow transactions to nest */ #define TDB_INCOMPATIBLE_HASH 2048 /** Better hashing: can't be opened by tdb < 1.2.6. */ #define TDB_MUTEX_LOCKING 4096 /** optimized locking using robust mutexes if supported, only with tdb >= 1.3.0 and TDB_CLEAR_IF_FIRST after checking tdb_runtime_check_for_robust_mutexes() */ /** The tdb error codes */ enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY, TDB_ERR_NESTING}; /** Debugging uses one of the following levels */ enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; /** The tdb data structure */ typedef struct TDB_DATA { unsigned char *dptr; size_t dsize; } TDB_DATA; #ifndef PRINTF_ATTRIBUTE #if (__GNUC__ >= 3) /** Use gcc attribute to check printf fns. a1 is the 1-based index of * the parameter containing the format, and a2 the index of the first * argument. Note that some gcc 2.x versions don't handle this * properly **/ #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) #else #define PRINTF_ATTRIBUTE(a1, a2) #endif #endif /** This is the context structure that is returned from a db open. */ typedef struct tdb_context TDB_CONTEXT; typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4); typedef unsigned int (*tdb_hash_func)(TDB_DATA *key); struct tdb_logging_context { tdb_log_func log_fn; void *log_private; }; /** * @brief Open the database and creating it if necessary. * * @param[in] name The name of the db to open. * * @param[in] hash_size The hash size is advisory, use zero for a default * value. * * @param[in] tdb_flags The flags to use to open the db:\n\n * TDB_CLEAR_IF_FIRST - Clear database if we are the * only one with it open\n * TDB_INTERNAL - Don't use a file, instead store the * data in memory. The filename is * ignored in this case.\n * TDB_NOLOCK - Don't do any locking\n * TDB_NOMMAP - Don't use mmap\n * TDB_NOSYNC - Don't synchronise transactions to disk\n * TDB_SEQNUM - Maintain a sequence number\n * TDB_VOLATILE - activate the per-hashchain freelist, * default 5.\n * TDB_ALLOW_NESTING - Allow transactions to nest.\n * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, * can't be opened by tdb < 1.3.0. * Only valid in combination with TDB_CLEAR_IF_FIRST * after checking tdb_runtime_check_for_robust_mutexes()\n * * @param[in] open_flags Flags for the open(2) function. * * @param[in] mode The mode for the open(2) function. * * @return A tdb context structure, NULL on error. */ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); /** * @brief Open the database and creating it if necessary. * * This is like tdb_open(), but allows you to pass an initial logging and * hash function. Be careful when passing a hash function - all users of the * database must use the same hash function or you will get data corruption. * * @param[in] name The name of the db to open. * * @param[in] hash_size The hash size is advisory, use zero for a default * value. * * @param[in] tdb_flags The flags to use to open the db:\n\n * TDB_CLEAR_IF_FIRST - Clear database if we are the * only one with it open\n * TDB_INTERNAL - Don't use a file, instead store the * data in memory. The filename is * ignored in this case.\n * TDB_NOLOCK - Don't do any locking\n * TDB_NOMMAP - Don't use mmap\n * TDB_NOSYNC - Don't synchronise transactions to disk\n * TDB_SEQNUM - Maintain a sequence number\n * TDB_VOLATILE - activate the per-hashchain freelist, * default 5.\n * TDB_ALLOW_NESTING - Allow transactions to nest.\n * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, * can't be opened by tdb < 1.3.0. * Only valid in combination with TDB_CLEAR_IF_FIRST * after checking tdb_runtime_check_for_robust_mutexes()\n * * @param[in] open_flags Flags for the open(2) function. * * @param[in] mode The mode for the open(2) function. * * @param[in] log_ctx The logging function to use. * * @param[in] hash_fn The hash function you want to use. * * @return A tdb context structure, NULL on error. * * @see tdb_open() */ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn); /** * @brief Set the maximum number of dead records per hash chain. * * @param[in] tdb The database handle to set the maximum. * * @param[in] max_dead The maximum number of dead records per hash chain. */ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); /** * @brief Reopen a tdb. * * This can be used after a fork to ensure that we have an independent seek * pointer from our parent and to re-establish locks. * * @param[in] tdb The database to reopen. It will be free'd on error! * * @return 0 on success, -1 on error. * * @note Don't call tdb_error() after this function cause the tdb context will * be freed on error. */ int tdb_reopen(struct tdb_context *tdb); /** * @brief Reopen all tdb's * * If the parent is longlived (ie. a parent daemon architecture), we know it * will keep it's active lock on a tdb opened with CLEAR_IF_FIRST. Thus for * child processes we don't have to add an active lock. This is essential to * improve performance on systems that keep POSIX locks as a non-scalable data * structure in the kernel. * * @param[in] parent_longlived Whether the parent is longlived or not. * * @return 0 on success, -1 on error. */ int tdb_reopen_all(int parent_longlived); /** * @brief Set a different tdb logging function. * * @param[in] tdb The tdb to set the logging function. * * @param[in] log_ctx The logging function to set. */ void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); /** * @brief Get the tdb last error code. * * @param[in] tdb The tdb to get the error code from. * * @return A TDB_ERROR code. * * @see TDB_ERROR */ enum TDB_ERROR tdb_error(struct tdb_context *tdb); /** * @brief Get a error string for the last tdb error * * @param[in] tdb The tdb to get the error code from. * * @return An error string. */ const char *tdb_errorstr(struct tdb_context *tdb); /** * @brief Fetch an entry in the database given a key. * * The caller must free the resulting data. * * @param[in] tdb The tdb to fetch the key. * * @param[in] key The key to fetch. * * @return The key entry found in the database, NULL on error with * TDB_ERROR set. * * @see tdb_error() * @see tdb_errorstr() */ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); /** * @brief Hand a record to a parser function without allocating it. * * This function is meant as a fast tdb_fetch alternative for large records * that are frequently read. The "key" and "data" arguments point directly * into the tdb shared memory, they are not aligned at any boundary. * * @warning The parser is called while tdb holds a lock on the record. DO NOT * call other tdb routines from within the parser. Also, for good performance * you should make the parser fast to allow parallel operations. * * @param[in] tdb The tdb to parse the record. * * @param[in] key The key to parse. * * @param[in] parser The parser to use to parse the data. * * @param[in] private_data A private data pointer which is passed to the parser * function. * * @return -1 if the record was not found. If the record was found, * the return value of "parser" is passed up to the caller. */ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); /** * @brief Delete an entry in the database given a key. * * @param[in] tdb The tdb to delete the key. * * @param[in] key The key to delete. * * @return 0 on success, -1 if the key doesn't exist. */ int tdb_delete(struct tdb_context *tdb, TDB_DATA key); /** * @brief Store an element in the database. * * This replaces any existing element with the same key. * * @param[in] tdb The tdb to store the entry. * * @param[in] key The key to use to store the entry. * * @param[in] dbuf The data to store under the key. * * @param[in] flag The flags to store the key:\n\n * TDB_INSERT: Don't overwrite an existing entry.\n * TDB_MODIFY: Don't create a new entry\n * * @return 0 on success, -1 on error with error code set. * * @see tdb_error() * @see tdb_errorstr() */ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); /** * @brief Store an element in the database. * * This replaces any existing element with the same key. * * @param[in] tdb The tdb to store the entry. * * @param[in] key The key to use to store the entry. * * @param[in] dbufs A vector of memory chunks to write * * @param[in] num_dbufs Length of the dbufs vector * * @param[in] flag The flags to store the key:\n\n * TDB_INSERT: Don't overwrite an existing entry.\n * TDB_MODIFY: Don't create a new entry\n * * @return 0 on success, -1 on error with error code set. * * @see tdb_error() * @see tdb_errorstr() */ int tdb_storev(struct tdb_context *tdb, TDB_DATA key, const TDB_DATA *dbufs, int num_dbufs, int flag); /** * @brief Append data to an entry. * * If the entry doesn't exist, it will create a new one. * * @param[in] tdb The database to use. * * @param[in] key The key to append the data. * * @param[in] new_dbuf The data to append to the key. * * @return 0 on success, -1 on error with error code set. * * @see tdb_error() * @see tdb_errorstr() */ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); /** * @brief Close a database. * * @param[in] tdb The database to close. The context will be free'd. * * @return 0 for success, -1 on error. * * @note Don't call tdb_error() after this function cause the tdb context will * be freed on error. */ int tdb_close(struct tdb_context *tdb); /** * @brief Find the first entry in the database and return its key. * * The caller must free the returned data. * * @param[in] tdb The database to use. * * @return The first entry of the database, an empty TDB_DATA entry * if the database is empty. */ TDB_DATA tdb_firstkey(struct tdb_context *tdb); /** * @brief Find the next entry in the database, returning its key. * * The caller must free the returned data. * * @param[in] tdb The database to use. * * @param[in] key The key from which you want the next key. * * @return The next entry of the current key, an empty TDB_DATA * entry if there is no entry. */ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); /** * @brief Traverse the entire database. * * While traversing the function fn(tdb, key, data, state) is called on each * element. If fn is NULL then it is not called. A non-zero return value from * fn() indicates that the traversal should stop. Traversal callbacks may not * start transactions. * * @warning The data buffer given to the callback fn does NOT meet the alignment * restrictions malloc gives you. * * @param[in] tdb The database to traverse. * * @param[in] fn The function to call on each entry. * * @param[in] private_data The private data which should be passed to the * traversing function. * * @return The record count traversed, -1 on error. */ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); /** * @brief Traverse the entire database. * * While traversing the database the function fn(tdb, key, data, state) is * called on each element, but marking the database read only during the * traversal, so any write operations will fail. This allows tdb to use read * locks, which increases the parallelism possible during the traversal. * * @param[in] tdb The database to traverse. * * @param[in] fn The function to call on each entry. * * @param[in] private_data The private data which should be passed to the * traversing function. * * @return The record count traversed, -1 on error. */ int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); /** * @brief Traverse a single hash chain * * Traverse a single hash chain under a single lock operation. No * database modification is possible in the callback. * * This exists for background cleanup of databases. In normal * operations, traversing a complete database can be much too * expensive. Databases can have many chains, which will all have to * be looked at before tdb_traverse finishes. Also tdb_traverse does a * lot of fcntl activity to protect against concurrent record deletes. * * With this you can walk a fraction of the whole tdb, collect the * entries you want to prune, leave the traverse, and then modify or * delete the records in a subsequent step. * * To walk the entire database, call this function tdb_hash_size() * times, with 0<=chain 2015-04-25 tdbbackup 8 Samba System Administration tools 3.6 tdbbackup tool for backing up and for validating the integrity of samba .tdb files tdbbackup -s suffix -v -h -n hashsize -l DESCRIPTION This tool is part of the samba 1 suite. tdbbackup is a tool that may be used to backup samba .tdb files. This tool may also be used to verify the integrity of the .tdb files prior to samba startup or during normal operation. If it finds file damage and it finds a prior backup the backup file will be restored. OPTIONS -h Get help information. -s suffix The -s option allows the administrator to specify a file backup extension. This way it is possible to keep a history of tdb backup files by using a new suffix for each backup. -v The -v will check the database for damages (corrupt data) which if detected causes the backup to be restored. -n hashsize The -n option sets the hash size for the new backup tdb. -l This options disables any locking, by passing TDB_NOLOCK to tdb_open_ex(). Only use this for database files which are not used by any other process! And also only if it is otherwise not possible to open the database, e.g. databases which were created with mutex locking. COMMANDS GENERAL INFORMATION The tdbbackup utility can safely be run at any time. It was designed so that it can be used at any time to validate the integrity of tdb files, even during Samba operation. Typical usage for the command will be: tdbbackup [-s suffix] *.tdb Before restarting samba the following command may be run to validate .tdb files: tdbbackup -v [-s suffix] *.tdb Samba .tdb files are stored in various locations, be sure to run backup all .tdb file on the system. Important files includes: secrets.tdb - usual location is in the /usr/local/samba/private directory, or on some systems in /etc/samba. passdb.tdb - usual location is in the /usr/local/samba/private directory, or on some systems in /etc/samba. *.tdb located in the /usr/local/samba/var directory or on some systems in the /var/cache or /var/lib/samba directories. VERSION This man page is correct for version 3 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. The tdbbackup man page was written by John H Terpstra. ldb-2.0.8/lib/tdb/man/tdbdump.8.xml0000660000000000000000000000470412520121120016626 0ustar rootroot00000000000000 2015-04-25 tdbdump 8 Samba System Administration tools 3.6 tdbdump tool for printing the contents of a TDB file tdbdump -k keyname -e -h filename DESCRIPTION This tool is part of the samba 1 suite. tdbdump is a very simple utility that 'dumps' the contents of a TDB (Trivial DataBase) file to standard output in a human-readable format. This tool can be used when debugging problems with TDB files. It is intended for those who are somewhat familiar with Samba internals. OPTIONS -h Get help information. -k keyname The -k option restricts dumping to a single key, if found. -e The -e tries to dump out from a corrupt database. Naturally, such a dump is unreliable, at best. VERSION This man page is correct for version 3 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. The tdbdump man page was written by Jelmer Vernooij. ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml0000660000000000000000000000367312520121120017350 0ustar rootroot00000000000000 2015-04-25 tdbrestore 8 Samba System Administration tools 3.6 tdbrestore tool for creating a TDB file out of a tdbdump output tdbrestore tdbfilename DESCRIPTION This tool is part of the samba 1 suite. tdbrestore is a very simple utility that 'restores' the contents of dump file into TDB (Trivial DataBase) file. The dump file is obtained from the tdbdump command. This tool wait on the standard input for the content of the dump and will write the tdb in the tdbfilename parameter. This tool can be used for unpacking the content of tdb as backup mean. VERSION This man page is correct for version 3 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. This tool was initially written by Volker Lendecke based on an idea by Simon McVittie. The tdbrestore man page was written by Matthieu Patou. ldb-2.0.8/lib/tdb/man/tdbtool.8.xml0000660000000000000000000001466713100601766016665 0ustar rootroot00000000000000 2015-04-25 tdbtool 8 Samba System Administration tools 4.0 tdbtool manipulate the contents TDB files tdbtool tdbtool -l TDBFILE COMMANDS DESCRIPTION This tool is part of the samba 1 suite. tdbtool a tool for displaying and altering the contents of Samba TDB (Trivial DataBase) files. Each of the commands listed below can be entered interactively or provided on the command line. OPTIONS -l This options disables any locking, by passing TDB_NOLOCK to tdb_open_ex(). Only use this for database files which are not used by any other process! And also only if it is otherwise not possible to open the database, e.g. databases which were created with mutex locking. COMMANDS TDBFILE Create a new database named TDBFILE. TDBFILE Open an existing database named TDBFILE. Erase the current database. Dump the current database as strings. Dump the current database as connection records. Dump the current database keys as strings. Dump the current database keys as hex values. Print summary information about the current database. KEY DATA Insert a record into the current database. KEY TDBFILE Move a record from the current database into TDBFILE. KEY DATA Store (replace) a record in the current database. KEY DATA Store (replace) a record in the current database where key and data are in hex format. KEY Show a record by key. KEY Delete a record by key. Print the current database hash table and free list. Print the current database and free list. COMMAND Execute the given system command. Print the first record in the current database. Print the next record in the current database. Check the integrity of the current database. Repack a database using a temporary file to remove fragmentation. Exit tdbtool. CAVEATS The contents of the Samba TDB files are private to the implementation and should not be altered with tdbtool. VERSION This man page is correct for version 3.6 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. ldb-2.0.8/lib/tdb/pytdb.c0000660000000000000000000005153213573675413015047 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python interface to tdb. Copyright (C) 2004-2006 Tim Potter Copyright (C) 2007-2008 Jelmer Vernooij ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include #include "replace.h" #include "system/filesys.h" /* Include tdb headers */ #include #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #define PyInt_Check PyLong_Check #define PyInt_AsLong PyLong_AsLong #define Py_TPFLAGS_HAVE_ITER 0 #endif /* discard signature of 'func' in favour of 'target_sig' */ #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func typedef struct { PyObject_HEAD TDB_CONTEXT *ctx; bool closed; } PyTdbObject; static PyTypeObject PyTdb; static void PyErr_SetTDBError(TDB_CONTEXT *tdb) { PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue("(i,s)", tdb_error(tdb), tdb_errorstr(tdb))); } static TDB_DATA PyBytes_AsTDB_DATA(PyObject *data) { TDB_DATA ret; ret.dptr = (unsigned char *)PyBytes_AsString(data); ret.dsize = PyBytes_Size(data); return ret; } static PyObject *PyBytes_FromTDB_DATA(TDB_DATA data) { if (data.dptr == NULL && data.dsize == 0) { Py_RETURN_NONE; } else { PyObject *ret = PyBytes_FromStringAndSize((const char *)data.dptr, data.dsize); free(data.dptr); return ret; } } #define PyErr_TDB_ERROR_IS_ERR_RAISE(ret, tdb) \ if (ret != 0) { \ PyErr_SetTDBError(tdb); \ return NULL; \ } #define PyErr_TDB_RAISE_IF_CLOSED(self) \ if (self->closed) { \ PyErr_SetObject(PyExc_RuntimeError, \ Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ return NULL; \ } #define PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self) \ if (self->closed) { \ PyErr_SetObject(PyExc_RuntimeError, \ Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ return -1; \ } static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) { char *name = NULL; int hash_size = 0, tdb_flags = TDB_DEFAULT, flags = O_RDWR, mode = 0600; TDB_CONTEXT *ctx; PyTdbObject *ret; const char *_kwnames[] = { "name", "hash_size", "tdb_flags", "flags", "mode", NULL }; char **kwnames = discard_const_p(char *, _kwnames); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|siiii", kwnames, &name, &hash_size, &tdb_flags, &flags, &mode)) return NULL; if (name == NULL) { tdb_flags |= TDB_INTERNAL; } ctx = tdb_open(name, hash_size, tdb_flags, flags, mode); if (ctx == NULL) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } ret = PyObject_New(PyTdbObject, &PyTdb); if (!ret) { tdb_close(ctx); return NULL; } ret->ctx = ctx; ret->closed = false; return (PyObject *)ret; } static PyObject *obj_transaction_cancel(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_cancel(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_transaction_commit(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_commit(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_transaction_prepare_commit(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_prepare_commit(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_transaction_start(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_start(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_reopen(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_reopen(self->ctx); if (ret != 0) { self->closed = true; PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue("(i,s)", TDB_ERR_IO, "Failed to reopen database")); return NULL; } Py_RETURN_NONE; } static PyObject *obj_lockall(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_lockall(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_unlockall(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_unlockall(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_lockall_read(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_lockall_read(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_unlockall_read(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret = tdb_unlockall_read(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_close(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; if (self->closed) Py_RETURN_NONE; ret = tdb_close(self->ctx); self->closed = true; if (ret != 0) { PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue("(i,s)", TDB_ERR_IO, "Failed to close database")); return NULL; } Py_RETURN_NONE; } static PyObject *obj_get(PyTdbObject *self, PyObject *args) { TDB_DATA key; PyObject *py_key; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; return PyBytes_FromTDB_DATA(tdb_fetch(self->ctx, key)); } static PyObject *obj_append(PyTdbObject *self, PyObject *args) { TDB_DATA key, data; PyObject *py_key, *py_data; int ret; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; data = PyBytes_AsTDB_DATA(py_data); if (!data.dptr) return NULL; ret = tdb_append(self->ctx, key, data); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_firstkey(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyBytes_FromTDB_DATA(tdb_firstkey(self->ctx)); } static PyObject *obj_nextkey(PyTdbObject *self, PyObject *args) { TDB_DATA key; PyObject *py_key; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; return PyBytes_FromTDB_DATA(tdb_nextkey(self->ctx, key)); } static PyObject *obj_delete(PyTdbObject *self, PyObject *args) { TDB_DATA key; PyObject *py_key; int ret; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; ret = tdb_delete(self->ctx, key); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static int obj_contains(PyTdbObject *self, PyObject *py_key) { TDB_DATA key; int ret; PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) { PyErr_BadArgument(); return -1; } ret = tdb_exists(self->ctx, key); if (ret) return 1; return 0; } #if PY_MAJOR_VERSION < 3 static PyObject *obj_has_key(PyTdbObject *self, PyObject *args) { int ret; PyObject *py_key; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; ret = obj_contains(self, py_key); if (ret == -1) return NULL; if (ret) Py_RETURN_TRUE; Py_RETURN_FALSE; } #endif static PyObject *obj_store(PyTdbObject *self, PyObject *args) { TDB_DATA key, value; int ret; int flag = TDB_REPLACE; PyObject *py_key, *py_value; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "OO|i", &py_key, &py_value, &flag)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; value = PyBytes_AsTDB_DATA(py_value); if (!value.dptr) return NULL; ret = tdb_store(self->ctx, key, value, flag); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_add_flags(PyTdbObject *self, PyObject *args) { unsigned flags; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "I", &flags)) return NULL; tdb_add_flags(self->ctx, flags); Py_RETURN_NONE; } static PyObject *obj_remove_flags(PyTdbObject *self, PyObject *args) { unsigned flags; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "I", &flags)) return NULL; tdb_remove_flags(self->ctx, flags); Py_RETURN_NONE; } typedef struct { PyObject_HEAD TDB_DATA current; PyTdbObject *iteratee; } PyTdbIteratorObject; static PyObject *tdb_iter_next(PyTdbIteratorObject *self) { TDB_DATA current; PyObject *ret; if (self->current.dptr == NULL && self->current.dsize == 0) return NULL; current = self->current; self->current = tdb_nextkey(self->iteratee->ctx, self->current); ret = PyBytes_FromTDB_DATA(current); return ret; } static void tdb_iter_dealloc(PyTdbIteratorObject *self) { Py_DECREF(self->iteratee); PyObject_Del(self); } PyTypeObject PyTdbIterator = { .tp_name = "Iterator", .tp_basicsize = sizeof(PyTdbIteratorObject), .tp_iternext = (iternextfunc)tdb_iter_next, .tp_dealloc = (destructor)tdb_iter_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_iter = PyObject_SelfIter, }; static PyObject *tdb_object_iter(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyTdbIteratorObject *ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = PyObject_New(PyTdbIteratorObject, &PyTdbIterator); if (!ret) return NULL; ret->current = tdb_firstkey(self->ctx); ret->iteratee = self; Py_INCREF(self); return (PyObject *)ret; } static PyObject *obj_clear(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_wipe_all(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_repack(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_repack(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_enable_seqnum(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_TDB_RAISE_IF_CLOSED(self); tdb_enable_seqnum(self->ctx); Py_RETURN_NONE; } static PyObject *obj_increment_seqnum_nonblock(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_TDB_RAISE_IF_CLOSED(self); tdb_increment_seqnum_nonblock(self->ctx); Py_RETURN_NONE; } static PyMethodDef tdb_object_methods[] = { { "transaction_cancel", (PyCFunction)obj_transaction_cancel, METH_NOARGS, "S.transaction_cancel() -> None\n" "Cancel the currently active transaction." }, { "transaction_commit", (PyCFunction)obj_transaction_commit, METH_NOARGS, "S.transaction_commit() -> None\n" "Commit the currently active transaction." }, { "transaction_prepare_commit", (PyCFunction)obj_transaction_prepare_commit, METH_NOARGS, "S.transaction_prepare_commit() -> None\n" "Prepare to commit the currently active transaction" }, { "transaction_start", (PyCFunction)obj_transaction_start, METH_NOARGS, "S.transaction_start() -> None\n" "Start a new transaction." }, { "reopen", (PyCFunction)obj_reopen, METH_NOARGS, "Reopen this file." }, { "lock_all", (PyCFunction)obj_lockall, METH_NOARGS, NULL }, { "unlock_all", (PyCFunction)obj_unlockall, METH_NOARGS, NULL }, { "read_lock_all", (PyCFunction)obj_lockall_read, METH_NOARGS, NULL }, { "read_unlock_all", (PyCFunction)obj_unlockall_read, METH_NOARGS, NULL }, { "close", (PyCFunction)obj_close, METH_NOARGS, NULL }, { "get", (PyCFunction)obj_get, METH_VARARGS, "S.get(key) -> value\n" "Fetch a value." }, { "append", (PyCFunction)obj_append, METH_VARARGS, "S.append(key, value) -> None\n" "Append data to an existing key." }, { "firstkey", (PyCFunction)obj_firstkey, METH_NOARGS, "S.firstkey() -> data\n" "Return the first key in this database." }, { "nextkey", (PyCFunction)obj_nextkey, METH_VARARGS, "S.nextkey(key) -> data\n" "Return the next key in this database." }, { "delete", (PyCFunction)obj_delete, METH_VARARGS, "S.delete(key) -> None\n" "Delete an entry." }, #if PY_MAJOR_VERSION < 3 { "has_key", (PyCFunction)obj_has_key, METH_VARARGS, "S.has_key(key) -> None\n" "Check whether key exists in this database." }, #endif { "store", (PyCFunction)obj_store, METH_VARARGS, "S.store(key, data, flag=REPLACE) -> None" "Store data." }, { "add_flags", (PyCFunction)obj_add_flags, METH_VARARGS, "S.add_flags(flags) -> None" }, { "remove_flags", (PyCFunction)obj_remove_flags, METH_VARARGS, "S.remove_flags(flags) -> None" }, #if PY_MAJOR_VERSION >= 3 { "keys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, #else { "iterkeys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, #endif { "clear", (PyCFunction)obj_clear, METH_NOARGS, "S.clear() -> None\n" "Wipe the entire database." }, { "repack", (PyCFunction)obj_repack, METH_NOARGS, "S.repack() -> None\n" "Repack the entire database." }, { "enable_seqnum", (PyCFunction)obj_enable_seqnum, METH_NOARGS, "S.enable_seqnum() -> None" }, { "increment_seqnum_nonblock", (PyCFunction)obj_increment_seqnum_nonblock, METH_NOARGS, "S.increment_seqnum_nonblock() -> None" }, { NULL } }; static PyObject *obj_get_hash_size(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_hash_size(self->ctx)); } static int obj_set_max_dead(PyTdbObject *self, PyObject *max_dead, void *closure) { PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); if (!PyInt_Check(max_dead)) return -1; tdb_set_max_dead(self->ctx, PyInt_AsLong(max_dead)); return 0; } static PyObject *obj_get_map_size(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_map_size(self->ctx)); } static PyObject *obj_get_freelist_size(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_freelist_size(self->ctx)); } static PyObject *obj_get_flags(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_get_flags(self->ctx)); } static PyObject *obj_get_filename(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyBytes_FromString(tdb_name(self->ctx)); } static PyObject *obj_get_seqnum(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_get_seqnum(self->ctx)); } static PyObject *obj_get_text(PyTdbObject *self, void *closure) { PyObject *mod, *cls, *inst; mod = PyImport_ImportModule("_tdb_text"); if (mod == NULL) return NULL; cls = PyObject_GetAttrString(mod, "TdbTextWrapper"); if (cls == NULL) { Py_DECREF(mod); return NULL; } inst = PyObject_CallFunction(cls, discard_const_p(char, "O"), self); Py_DECREF(mod); Py_DECREF(cls); return inst; } static PyGetSetDef tdb_object_getsetters[] = { { .name = discard_const_p(char, "hash_size"), .get = (getter)obj_get_hash_size, }, { .name = discard_const_p(char, "map_size"), .get = (getter)obj_get_map_size, }, { .name = discard_const_p(char, "freelist_size"), .get = (getter)obj_get_freelist_size, }, { .name = discard_const_p(char, "flags"), .get = (getter)obj_get_flags, }, { .name = discard_const_p(char, "max_dead"), .set = (setter)obj_set_max_dead, }, { .name = discard_const_p(char, "filename"), .get = (getter)obj_get_filename, .doc = discard_const_p(char, "The filename of this TDB file."), }, { .name = discard_const_p(char, "seqnum"), .get = (getter)obj_get_seqnum, }, { .name = discard_const_p(char, "text"), .get = (getter)obj_get_text, }, { .name = NULL } }; static PyObject *tdb_object_repr(PyTdbObject *self) { PyErr_TDB_RAISE_IF_CLOSED(self); if (tdb_get_flags(self->ctx) & TDB_INTERNAL) { return PyUnicode_FromString("Tdb()"); } else { return PyUnicode_FromFormat("Tdb('%s')", tdb_name(self->ctx)); } } static void tdb_object_dealloc(PyTdbObject *self) { if (!self->closed) tdb_close(self->ctx); Py_TYPE(self)->tp_free(self); } static PyObject *obj_getitem(PyTdbObject *self, PyObject *key) { TDB_DATA tkey, val; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyBytes_Check(key)) { PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); return NULL; } tkey.dptr = (unsigned char *)PyBytes_AsString(key); tkey.dsize = PyBytes_Size(key); val = tdb_fetch(self->ctx, tkey); if (val.dptr == NULL) { /* * if the key doesn't exist raise KeyError(key) to be * consistent with python dict */ PyErr_SetObject(PyExc_KeyError, key); return NULL; } else { return PyBytes_FromTDB_DATA(val); } } static int obj_setitem(PyTdbObject *self, PyObject *key, PyObject *value) { TDB_DATA tkey, tval; int ret; PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); if (!PyBytes_Check(key)) { PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); return -1; } tkey = PyBytes_AsTDB_DATA(key); if (value == NULL) { ret = tdb_delete(self->ctx, tkey); } else { if (!PyBytes_Check(value)) { PyErr_SetString(PyExc_TypeError, "Expected string as value"); return -1; } tval = PyBytes_AsTDB_DATA(value); ret = tdb_store(self->ctx, tkey, tval, TDB_REPLACE); } if (ret != 0) { PyErr_SetTDBError(self->ctx); return -1; } return ret; } static PyMappingMethods tdb_object_mapping = { .mp_subscript = (binaryfunc)obj_getitem, .mp_ass_subscript = (objobjargproc)obj_setitem, }; static PySequenceMethods tdb_object_seq = { .sq_contains = (objobjproc)obj_contains, }; static PyTypeObject PyTdb = { .tp_name = "tdb.Tdb", .tp_basicsize = sizeof(PyTdbObject), .tp_methods = tdb_object_methods, .tp_getset = tdb_object_getsetters, .tp_new = py_tdb_open, .tp_doc = "A TDB file", .tp_repr = (reprfunc)tdb_object_repr, .tp_dealloc = (destructor)tdb_object_dealloc, .tp_as_mapping = &tdb_object_mapping, .tp_as_sequence = &tdb_object_seq, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, .tp_iter = PY_DISCARD_FUNC_SIG(getiterfunc,tdb_object_iter), }; static PyMethodDef tdb_methods[] = { { .ml_name = "open", .ml_meth = PY_DISCARD_FUNC_SIG(PyCFunction, py_tdb_open), .ml_flags = METH_VARARGS|METH_KEYWORDS, .ml_doc = "open(name, hash_size=0, tdb_flags=TDB_DEFAULT, " "flags=O_RDWR, mode=0600)\nOpen a TDB file." }, { .ml_name = NULL } }; #define MODULE_DOC "simple key-value database that supports multiple writers." #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, .m_name = "tdb", .m_doc = MODULE_DOC, .m_size = -1, .m_methods = tdb_methods, }; #endif PyObject* module_init(void); PyObject* module_init(void) { PyObject *m; if (PyType_Ready(&PyTdb) < 0) return NULL; if (PyType_Ready(&PyTdbIterator) < 0) return NULL; #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); #else m = Py_InitModule3("tdb", tdb_methods, MODULE_DOC); #endif if (m == NULL) return NULL; PyModule_AddIntConstant(m, "REPLACE", TDB_REPLACE); PyModule_AddIntConstant(m, "INSERT", TDB_INSERT); PyModule_AddIntConstant(m, "MODIFY", TDB_MODIFY); PyModule_AddIntConstant(m, "DEFAULT", TDB_DEFAULT); PyModule_AddIntConstant(m, "CLEAR_IF_FIRST", TDB_CLEAR_IF_FIRST); PyModule_AddIntConstant(m, "INTERNAL", TDB_INTERNAL); PyModule_AddIntConstant(m, "NOLOCK", TDB_NOLOCK); PyModule_AddIntConstant(m, "NOMMAP", TDB_NOMMAP); PyModule_AddIntConstant(m, "CONVERT", TDB_CONVERT); PyModule_AddIntConstant(m, "BIGENDIAN", TDB_BIGENDIAN); PyModule_AddIntConstant(m, "NOSYNC", TDB_NOSYNC); PyModule_AddIntConstant(m, "SEQNUM", TDB_SEQNUM); PyModule_AddIntConstant(m, "VOLATILE", TDB_VOLATILE); PyModule_AddIntConstant(m, "ALLOW_NESTING", TDB_ALLOW_NESTING); PyModule_AddIntConstant(m, "DISALLOW_NESTING", TDB_DISALLOW_NESTING); PyModule_AddIntConstant(m, "INCOMPATIBLE_HASH", TDB_INCOMPATIBLE_HASH); PyModule_AddStringConstant(m, "__docformat__", "restructuredText"); PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); Py_INCREF(&PyTdb); PyModule_AddObject(m, "Tdb", (PyObject *)&PyTdb); Py_INCREF(&PyTdbIterator); return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit_tdb(void); PyMODINIT_FUNC PyInit_tdb(void) { return module_init(); } #else void inittdb(void); void inittdb(void) { module_init(); } #endif ldb-2.0.8/lib/tdb/python/tdbdump.py0000660000000000000000000000051413573675413017105 0ustar rootroot00000000000000#!/usr/bin/env python3 # Trivial reimplementation of tdbdump in Python from __future__ import print_function import tdb, sys if len(sys.argv) < 2: print("Usage: tdbdump.py ") 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)) ldb-2.0.8/lib/tdb/python/tests/simple.py0000660000000000000000000002173313573675413020107 0ustar rootroot00000000000000#!/usr/bin/env python3 # Some simple tests for the Python bindings for TDB # Note that this tests the interface of the Python bindings # It does not test tdb itself. # # Copyright (C) 2007-2008 Jelmer Vernooij # Published under the GNU LGPLv3 or later import sys import os import tempfile from unittest import TestCase import tdb class OpenTdbTests(TestCase): def test_nonexistent_read(self): self.assertRaises(IOError, tdb.Tdb, "/some/nonexistent/file", 0, tdb.DEFAULT, os.O_RDWR) class CloseTdbTests(TestCase): def test_double_close(self): self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) # ensure that double close does not crash python self.tdb.close() self.tdb.close() # Check that further operations do not crash python self.assertRaises(RuntimeError, lambda: self.tdb.transaction_start()) self.assertRaises(RuntimeError, lambda: self.tdb["bar"]) class InternalTdbTests(TestCase): def test_repr(self): self.tdb = tdb.Tdb() # repr used to crash on internal db self.assertEqual(repr(self.tdb), "Tdb()") class CommonTdbTests(TestCase): """Tests common to both the text & bytes interfaces""" use_text = False def setUp(self): super(CommonTdbTests, self).setUp() self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) if self.use_text: self.tdb = self.tdb.text def test_lockall(self): self.tdb.lock_all() def test_max_dead(self): self.tdb.max_dead = 20 def test_unlockall(self): self.tdb.lock_all() self.tdb.unlock_all() def test_lockall_read(self): self.tdb.read_lock_all() self.tdb.read_unlock_all() def test_reopen(self): self.tdb.reopen() def test_hash_size(self): self.tdb.hash_size def test_map_size(self): self.tdb.map_size def test_freelist_size(self): self.tdb.freelist_size def test_name(self): self.tdb.filename def test_add_flags(self): self.tdb.add_flags(tdb.NOMMAP) self.tdb.remove_flags(tdb.NOMMAP) class TextCommonTdbTests(CommonTdbTests): use_text = True class SimpleTdbTests(TestCase): def setUp(self): super(SimpleTdbTests, self).setUp() self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) def test_repr(self): self.assertTrue(repr(self.tdb).startswith("Tdb('")) def test_store(self): self.tdb.store(b"bar", b"bla") self.assertEqual(b"bla", self.tdb.get(b"bar")) def test_getitem(self): self.tdb[b"bar"] = b"foo" self.tdb.reopen() self.assertEqual(b"foo", self.tdb[b"bar"]) def test_delete(self): self.tdb[b"bar"] = b"foo" del self.tdb[b"bar"] self.assertRaises(KeyError, lambda: self.tdb[b"bar"]) def test_contains(self): self.tdb[b"bla"] = b"bloe" self.assertTrue(b"bla" in self.tdb) self.assertFalse(b"qwertyuiop" in self.tdb) if sys.version_info < (3, 0): self.assertTrue(self.tdb.has_key(b"bla")) self.assertFalse(self.tdb.has_key(b"qwertyuiop")) def test_keyerror(self): self.assertRaises(KeyError, lambda: self.tdb[b"bla"]) def test_iterator(self): self.tdb[b"bla"] = b"1" self.tdb[b"brainslug"] = b"2" l = list(self.tdb) l.sort() self.assertEqual([b"bla", b"brainslug"], l) def test_transaction_cancel(self): self.tdb[b"bloe"] = b"2" self.tdb.transaction_start() self.tdb[b"bloe"] = b"1" self.tdb.transaction_cancel() self.assertEqual(b"2", self.tdb[b"bloe"]) def test_transaction_commit(self): self.tdb[b"bloe"] = b"2" self.tdb.transaction_start() self.tdb[b"bloe"] = b"1" self.tdb.transaction_commit() self.assertEqual(b"1", self.tdb[b"bloe"]) def test_transaction_prepare_commit(self): self.tdb[b"bloe"] = b"2" self.tdb.transaction_start() self.tdb[b"bloe"] = b"1" self.tdb.transaction_prepare_commit() self.tdb.transaction_commit() self.assertEqual(b"1", self.tdb[b"bloe"]) def test_iterkeys(self): self.tdb[b"bloe"] = b"2" self.tdb[b"bla"] = b"25" if sys.version_info >= (3, 0): i = self.tdb.keys() else: i = self.tdb.iterkeys() self.assertEqual(set([b"bloe", b"bla"]), set([next(i), next(i)])) def test_clear(self): self.tdb[b"bloe"] = b"2" self.tdb[b"bla"] = b"25" self.assertEqual(2, len(list(self.tdb))) self.tdb.clear() self.assertEqual(0, len(list(self.tdb))) def test_repack(self): self.tdb[b"foo"] = b"abc" self.tdb[b"bar"] = b"def" del self.tdb[b"foo"] self.tdb.repack() def test_seqnum(self): self.tdb.enable_seqnum() seq1 = self.tdb.seqnum self.tdb.increment_seqnum_nonblock() seq2 = self.tdb.seqnum self.assertEqual(seq2-seq1, 1) def test_len(self): self.assertEqual(0, len(list(self.tdb))) self.tdb[b"entry"] = b"value" self.assertEqual(1, len(list(self.tdb))) class TdbTextTests(TestCase): def setUp(self): super(TdbTextTests, self).setUp() self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) def test_repr(self): self.assertTrue(repr(self.tdb).startswith("Tdb('")) def test_store(self): self.tdb.text.store("bar", "bla") self.assertEqual("bla", self.tdb.text.get("bar")) def test_getitem(self): self.tdb.text["bar"] = "foo" self.tdb.reopen() self.assertEqual("foo", self.tdb.text["bar"]) def test_delete(self): self.tdb.text["bar"] = "foo" del self.tdb.text["bar"] self.assertRaises(KeyError, lambda: self.tdb.text["bar"]) def test_contains(self): self.tdb.text["bla"] = "bloe" self.assertTrue("bla" in self.tdb.text) self.assertFalse("qwertyuiop" in self.tdb.text) if sys.version_info < (3, 0): self.assertTrue(self.tdb.text.has_key("bla")) self.assertFalse(self.tdb.text.has_key("qwertyuiop")) def test_keyerror(self): self.assertRaises(KeyError, lambda: self.tdb.text["bla"]) def test_iterator(self): self.tdb.text["bla"] = "1" self.tdb.text["brainslug"] = "2" l = list(self.tdb.text) l.sort() self.assertEqual(["bla", "brainslug"], l) def test_transaction_cancel(self): self.tdb.text["bloe"] = "2" self.tdb.transaction_start() self.tdb.text["bloe"] = "1" self.tdb.transaction_cancel() self.assertEqual("2", self.tdb.text["bloe"]) def test_transaction_commit(self): self.tdb.text["bloe"] = "2" self.tdb.transaction_start() self.tdb.text["bloe"] = "1" self.tdb.transaction_commit() self.assertEqual("1", self.tdb.text["bloe"]) def test_transaction_prepare_commit(self): self.tdb.text["bloe"] = "2" self.tdb.transaction_start() self.tdb.text["bloe"] = "1" self.tdb.transaction_prepare_commit() self.tdb.transaction_commit() self.assertEqual("1", self.tdb.text["bloe"]) def test_iterkeys(self): self.tdb.text["bloe"] = "2" self.tdb.text["bla"] = "25" if sys.version_info >= (3, 0): i = self.tdb.text.keys() else: i = self.tdb.text.iterkeys() self.assertEqual(set(["bloe", "bla"]), set([next(i), next(i)])) def test_clear(self): self.tdb.text["bloe"] = "2" self.tdb.text["bla"] = "25" self.assertEqual(2, len(list(self.tdb))) self.tdb.clear() self.assertEqual(0, len(list(self.tdb))) def test_repack(self): self.tdb.text["foo"] = "abc" self.tdb.text["bar"] = "def" del self.tdb.text["foo"] self.tdb.repack() def test_len(self): self.assertEqual(0, len(list(self.tdb.text))) self.tdb.text["entry"] = "value" self.assertEqual(1, len(list(self.tdb.text))) def test_text_and_binary(self): text = u'\xfa\u0148\xef\xe7\xf8\xf0\xea' bytestr = text.encode('utf-8') self.tdb[b"entry"] = bytestr self.tdb.text[u"entry2"] = text self.assertEqual(self.tdb.text["entry"], text) self.assertEqual(self.tdb[b"entry2"], bytestr) assert self.tdb.text.raw == self.tdb class VersionTests(TestCase): def test_present(self): self.assertTrue(isinstance(tdb.__version__, str)) if __name__ == '__main__': import unittest unittest.TestProgram() ldb-2.0.8/lib/tdb/tdb.pc.in0000660000000000000000000000036012406075657015252 0ustar rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: tdb Description: A trivial database Version: @PACKAGE_VERSION@ Libs: @LIB_RPATH@ -L${libdir} -ltdb Cflags: -I${includedir} URL: http://tdb.samba.org/ ldb-2.0.8/lib/tdb/test/circular_chain.tdb0000660000000000000000000000042013573675413020167 0ustar rootroot00000000000000TDB file m& Ÿ}ö ùþ:ðÐérJ ™&ab °¿׌™&cd Е¬c™&ef ldb-2.0.8/lib/tdb/test/circular_freelist.tdb0000660000000000000000000000062013573675413020724 0ustar rootroot00000000000000TDB file m& Ÿ}ö ùþ:PpérJ ™&aa PTÁKfæþÙbb °¿׌™&cc Ð*^ÎfæþÙdd ð•¬c™&ee û)RfæþÙff 0kIð“™&gg ldb-2.0.8/lib/tdb/test/external-agent.c0000660000000000000000000001167412702766507017623 0ustar rootroot00000000000000#include "external-agent.h" #include "lock-tracking.h" #include "logging.h" #include #include #include #include #include #include #include #include #include "../common/tdb_private.h" #include "tap-interface.h" #include #include static struct tdb_context *tdb; static enum agent_return do_operation(enum operation op, const char *name) { TDB_DATA k; enum agent_return ret; TDB_DATA data; if (op != OPEN && op != OPEN_WITH_CLEAR_IF_FIRST && !tdb) { diag("external: No tdb open!"); return OTHER_FAILURE; } k.dptr = discard_const_p(uint8_t, name); k.dsize = strlen(name); locking_would_block = 0; switch (op) { case OPEN: if (tdb) { diag("Already have tdb %s open", tdb_name(tdb)); return OTHER_FAILURE; } tdb = tdb_open_ex(name, 0, TDB_DEFAULT, O_RDWR, 0, &taplogctx, NULL); if (!tdb) { if (!locking_would_block) diag("Opening tdb gave %s", strerror(errno)); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case OPEN_WITH_CLEAR_IF_FIRST: if (tdb) return OTHER_FAILURE; tdb = tdb_open_ex(name, 0, TDB_CLEAR_IF_FIRST, O_RDWR, 0, &taplogctx, NULL); ret = tdb ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_START: ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE; break; case FETCH: data = tdb_fetch(tdb, k); if (data.dptr == NULL) { if (tdb_error(tdb) == TDB_ERR_NOEXIST) ret = FAILED; else ret = OTHER_FAILURE; } else if (data.dsize != k.dsize || memcmp(data.dptr, k.dptr, k.dsize) != 0) { ret = OTHER_FAILURE; } else { ret = SUCCESS; } free(data.dptr); break; case STORE: ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_COMMIT: ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE; break; case CHECK: ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE; break; case NEEDS_RECOVERY: ret = tdb_needs_recovery(tdb) ? SUCCESS : FAILED; break; case CLOSE: ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE; tdb = NULL; break; case PING: ret = SUCCESS; break; case UNMAP: ret = tdb_munmap(tdb) == 0 ? SUCCESS : OTHER_FAILURE; if (ret == SUCCESS) { tdb->flags |= TDB_NOMMAP; } break; default: ret = OTHER_FAILURE; } if (locking_would_block) ret = WOULD_HAVE_BLOCKED; return ret; } struct agent { int cmdfd, responsefd; pid_t pid; }; /* Do this before doing any tdb stuff. Return handle, or NULL. */ struct agent *prepare_external_agent(void) { int ret; int command[2], response[2]; char name[1+PATH_MAX]; struct agent *agent = malloc(sizeof(*agent)); if (pipe(command) != 0 || pipe(response) != 0) { fprintf(stderr, "pipe failed: %s\n", strerror(errno)); exit(1); } agent->pid = fork(); if (agent->pid < 0) { fprintf(stderr, "fork failed: %s\n", strerror(errno)); exit(1); } if (agent->pid != 0) { close(command[0]); close(response[1]); agent->cmdfd = command[1]; agent->responsefd = response[0]; return agent; } close(command[1]); close(response[0]); /* We want to fail, not block. */ nonblocking_locks = true; log_prefix = "external: "; while ((ret = read(command[0], name, sizeof(name))) > 0) { enum agent_return result; result = do_operation(name[0], name+1); if (write(response[1], &result, sizeof(result)) != sizeof(result)) abort(); } exit(0); } void shutdown_agent(struct agent *agent) { pid_t p; close(agent->cmdfd); close(agent->responsefd); p = waitpid(agent->pid, NULL, WNOHANG); if (p == 0) { kill(agent->pid, SIGKILL); } waitpid(agent->pid, NULL, 0); free(agent); } /* Ask the external agent to try to do an operation. */ enum agent_return external_agent_operation(struct agent *agent, enum operation op, const char *name) { enum agent_return res; unsigned int len; char *string; if (!name) name = ""; len = 1 + strlen(name) + 1; string = malloc(len); string[0] = op; strncpy(string+1, name, len - 1); string[len-1] = '\0'; if (write(agent->cmdfd, string, len) != len || read(agent->responsefd, &res, sizeof(res)) != sizeof(res)) res = AGENT_DIED; free(string); return res; } const char *agent_return_name(enum agent_return ret) { return ret == SUCCESS ? "SUCCESS" : ret == WOULD_HAVE_BLOCKED ? "WOULD_HAVE_BLOCKED" : ret == AGENT_DIED ? "AGENT_DIED" : ret == FAILED ? "FAILED" : ret == OTHER_FAILURE ? "OTHER_FAILURE" : "**INVALID**"; } const char *operation_name(enum operation op) { switch (op) { case OPEN: return "OPEN"; case OPEN_WITH_CLEAR_IF_FIRST: return "OPEN_WITH_CLEAR_IF_FIRST"; case TRANSACTION_START: return "TRANSACTION_START"; case FETCH: return "FETCH"; case STORE: return "STORE"; case TRANSACTION_COMMIT: return "TRANSACTION_COMMIT"; case CHECK: return "CHECK"; case NEEDS_RECOVERY: return "NEEDS_RECOVERY"; case CLOSE: return "CLOSE"; case PING: return "PING"; case UNMAP: return "UNMAP"; } return "**INVALID**"; } ldb-2.0.8/lib/tdb/test/external-agent.h0000660000000000000000000000204712406075657017622 0ustar rootroot00000000000000#ifndef TDB_TEST_EXTERNAL_AGENT_H #define TDB_TEST_EXTERNAL_AGENT_H /* For locking tests, we need a different process to try things at * various times. */ enum operation { OPEN, OPEN_WITH_CLEAR_IF_FIRST, TRANSACTION_START, FETCH, STORE, TRANSACTION_COMMIT, CHECK, NEEDS_RECOVERY, CLOSE, PING, UNMAP, }; /* Do this before doing any tdb stuff. Return handle, or -1. */ struct agent *prepare_external_agent(void); void shutdown_agent(struct agent *agent); enum agent_return { SUCCESS, WOULD_HAVE_BLOCKED, AGENT_DIED, FAILED, /* For fetch, or NEEDS_RECOVERY */ OTHER_FAILURE, }; /* Ask the external agent to try to do an operation. * name == tdb name for OPEN/OPEN_WITH_CLEAR_IF_FIRST, * record name for FETCH/STORE (store stores name as data too) */ enum agent_return external_agent_operation(struct agent *handle, enum operation op, const char *name); /* Mapping enum -> string. */ const char *agent_return_name(enum agent_return ret); const char *operation_name(enum operation op); #endif /* TDB_TEST_EXTERNAL_AGENT_H */ ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb0000660000000000000000000000127012406075657020171 0ustar rootroot00000000000000TDB file &mƒ×¶”å<ƒldb-2.0.8/lib/tdb/test/jenkins-le-hash.tdb0000660000000000000000000000127012406075657020203 0ustar rootroot00000000000000TDB file m&ƒå”¶×D¹vldb-2.0.8/lib/tdb/test/lock-tracking.c0000660000000000000000000000666712406075657017443 0ustar rootroot00000000000000/* We save the locks so we can reaquire them. */ #include "../common/tdb_private.h" #include #include #include #include #include "tap-interface.h" #include "lock-tracking.h" struct testlock { struct testlock *next; unsigned int off; unsigned int len; int type; }; static struct testlock *testlocks; int locking_errors = 0; bool suppress_lockcheck = false; bool nonblocking_locks; int locking_would_block = 0; void (*unlock_callback)(int fd); int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ) { va_list ap; int ret, arg3; struct flock *fl; bool may_block = false; if (cmd != F_SETLK && cmd != F_SETLKW) { /* This may be totally bogus, but we don't know in general. */ va_start(ap, cmd); arg3 = va_arg(ap, int); va_end(ap); return fcntl(fd, cmd, arg3); } va_start(ap, cmd); fl = va_arg(ap, struct flock *); va_end(ap); if (cmd == F_SETLKW && nonblocking_locks) { cmd = F_SETLK; may_block = true; } ret = fcntl(fd, cmd, fl); /* Detect when we failed, but might have been OK if we waited. */ if (may_block && ret == -1 && (errno == EAGAIN || errno == EACCES)) { locking_would_block++; } if (fl->l_type == F_UNLCK) { struct testlock **l; struct testlock *old = NULL; for (l = &testlocks; *l; l = &(*l)->next) { if ((*l)->off == fl->l_start && (*l)->len == fl->l_len) { if (ret == 0) { old = *l; *l = (*l)->next; free(old); } break; } if (((*l)->off == fl->l_start) && ((*l)->len == 0) && (ret == 0)) { /* * Remove a piece from the start of the * allrecord_lock */ old = *l; (*l)->off += fl->l_len; break; } } if (!old && !suppress_lockcheck) { diag("Unknown unlock %u@%u - %i", (int)fl->l_len, (int)fl->l_start, ret); locking_errors++; } } else { struct testlock *new, *i; unsigned int fl_end = fl->l_start + fl->l_len; if (fl->l_len == 0) fl_end = (unsigned int)-1; /* Check for overlaps: we shouldn't do this. */ for (i = testlocks; i; i = i->next) { unsigned int i_end = i->off + i->len; if (i->len == 0) i_end = (unsigned int)-1; if (fl->l_start >= i->off && fl->l_start < i_end) break; if (fl_end >= i->off && fl_end < i_end) break; /* tdb_allrecord_lock does this, handle adjacent: */ if (fl->l_start == i_end && fl->l_type == i->type) { if (ret == 0) { i->len = fl->l_len ? i->len + fl->l_len : 0; } goto done; } } if (i) { /* Special case: upgrade of allrecord lock. */ if (i->type == F_RDLCK && fl->l_type == F_WRLCK && i->off == FREELIST_TOP && fl->l_start == FREELIST_TOP && i->len == 0 && fl->l_len == 0) { if (ret == 0) i->type = F_WRLCK; goto done; } if (!suppress_lockcheck) { diag("%s testlock %u@%u overlaps %u@%u", fl->l_type == F_WRLCK ? "write" : "read", (int)fl->l_len, (int)fl->l_start, i->len, (int)i->off); locking_errors++; } } if (ret == 0) { new = malloc(sizeof *new); new->off = fl->l_start; new->len = fl->l_len; new->type = fl->l_type; new->next = testlocks; testlocks = new; } } done: if (ret == 0 && fl->l_type == F_UNLCK && unlock_callback) unlock_callback(fd); return ret; } unsigned int forget_locking(void) { unsigned int num = 0; while (testlocks) { struct testlock *next = testlocks->next; free(testlocks); testlocks = next; num++; } return num; } ldb-2.0.8/lib/tdb/test/lock-tracking.h0000660000000000000000000000125112406075657017430 0ustar rootroot00000000000000#ifndef LOCK_TRACKING_H #define LOCK_TRACKING_H #include /* Set this if you want a callback after fnctl unlock. */ extern void (*unlock_callback)(int fd); /* Replacement fcntl. */ int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ); /* Discard locking info: returns number of locks outstanding. */ unsigned int forget_locking(void); /* Number of errors in locking. */ extern int locking_errors; /* Suppress lock checking. */ extern bool suppress_lockcheck; /* Make all locks non-blocking. */ extern bool nonblocking_locks; /* Number of times we failed a lock because we made it non-blocking. */ extern int locking_would_block; #endif /* LOCK_TRACKING_H */ ldb-2.0.8/lib/tdb/test/logging.c0000660000000000000000000000131412406075657016321 0ustar rootroot00000000000000#include "logging.h" #include "tap-interface.h" #include #include #include #include bool suppress_logging = false; const char *log_prefix = ""; /* Turn log messages into tap diag messages. */ static void taplog(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; char line[200]; if (suppress_logging) return; va_start(ap, fmt); vsprintf(line, fmt, ap); va_end(ap); /* Strip trailing \n: diag adds it. */ if (line[0] && line[strlen(line)-1] == '\n') diag("%s%.*s", log_prefix, (unsigned)strlen(line)-1, line); else diag("%s%s", log_prefix, line); } struct tdb_logging_context taplogctx = { taplog, NULL }; ldb-2.0.8/lib/tdb/test/logging.h0000660000000000000000000000041012406075657016322 0ustar rootroot00000000000000#ifndef TDB_TEST_LOGGING_H #define TDB_TEST_LOGGING_H #include "replace.h" #include "../include/tdb.h" #include extern bool suppress_logging; extern const char *log_prefix; extern struct tdb_logging_context taplogctx; #endif /* TDB_TEST_LOGGING_H */ ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb0000660000000000000000000000127012406075657017643 0ustar rootroot00000000000000TDB file &mƒldb-2.0.8/lib/tdb/test/old-nohash-le.tdb0000660000000000000000000000127012406075657017655 0ustar rootroot00000000000000TDB file m&ƒldb-2.0.8/lib/tdb/test/run-3G-file.c0000660000000000000000000000740413573675413016673 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static int tdb_expand_file_sparse(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } if (tdb_ftruncate(tdb, size+addition) == -1) { char b = 0; ssize_t written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); if (written == 0) { /* try once more, potentially revealing errno */ written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); } if (written == 0) { /* again - give up, guessing errno */ errno = ENOSPC; } if (written != 1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", size+addition, strerror(errno))); return -1; } } return 0; } static const struct tdb_methods large_io_methods = { tdb_read, tdb_write, tdb_next_hash_chain, tdb_notrans_oob, tdb_expand_file_sparse }; static int test_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *_data) { TDB_DATA *expect = _data; ok1(key.dsize == strlen("hi")); ok1(memcmp(key.dptr, "hi", strlen("hi")) == 0); ok1(data.dsize == expect->dsize); ok1(memcmp(data.dptr, expect->dptr, data.dsize) == 0); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, orig_data, data; uint32_t hashval; tdb_off_t rec_ptr; struct tdb_record rec; int ret; plan_tests(24); tdb = tdb_open_ex("run-36-file.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); tdb->methods = &large_io_methods; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); orig_data.dsize = strlen("world"); orig_data.dptr = discard_const_p(uint8_t, "world"); /* Enlarge the file (internally multiplies by 2). */ ret = tdb_expand(tdb, 1500000000); #ifdef HAVE_INCOHERENT_MMAP /* This can fail due to mmap failure on 32 bit systems. */ if (ret == -1) { /* These should now fail. */ ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == -1); data = tdb_fetch(tdb, key); ok1(data.dptr == NULL); ok1(tdb_traverse(tdb, test_traverse, &orig_data) == -1); ok1(tdb_delete(tdb, key) == -1); ok1(tdb_traverse(tdb, test_traverse, NULL) == -1); /* Skip the rest... */ for (ret = 0; ret < 24 - 6; ret++) ok1(1); tdb_close(tdb); return exit_status(); } #endif ok1(ret == 0); /* Put an entry in, and check it. */ ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); /* That currently fills at the end, make sure that's true. */ hashval = tdb->hash_fn(&key); rec_ptr = tdb_find_lock_hash(tdb, key, hashval, F_RDLCK, &rec); ok1(rec_ptr); ok1(rec_ptr > 2U*1024*1024*1024); tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); /* Traverse must work. */ ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); /* Delete should work. */ ok1(tdb_delete(tdb, key) == 0); ok1(tdb_traverse(tdb, test_traverse, NULL) == 0); /* Transactions should work. */ ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); ok1(tdb_transaction_commit(tdb) == 0); ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c0000660000000000000000000001220512553526140023031 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "logging.h" static void do_allrecord_lock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_lockall(tdb); ok(ret == 0, "tdb_lockall should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); ret = tdb_traverse(tdb, NULL, NULL); ok(ret == -1, "do_allrecord_lock: traverse should fail"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); exit(0); } static void do_traverse(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_traverse(tdb, NULL, NULL); ok(ret == 1, "do_traverse: tdb_traverse should return 1 record"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); exit(0); } /* * Process 1: get the allrecord_lock on a tdb. * Process 2: start a traverse, this will stall waiting for the * first chainlock: That is taken by the allrecord_lock * Process 1: start a traverse: This will get EDEADLK in trying to * get the TRANSACTION_LOCK. It will deadlock for mutexes, * which don't have built-in deadlock detection. */ static int do_tests(const char *name, int tdb_flags) { struct tdb_context *tdb; int ret; pid_t traverse_child, allrecord_child; int traverse_down[2]; int traverse_up[2]; int allrecord_down[2]; int allrecord_up[2]; char c; ssize_t nread, nwritten; TDB_DATA key, data; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store should succeed"); ret = pipe(traverse_down); ok(ret == 0, "pipe should succeed"); ret = pipe(traverse_up); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_down); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_up); ok(ret == 0, "pipe should succeed"); allrecord_child = fork(); ok(allrecord_child != -1, "fork should succeed"); if (allrecord_child == 0) { tdb_close(tdb); close(traverse_up[0]); close(traverse_up[1]); close(traverse_down[0]); close(traverse_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); do_allrecord_lock(name, tdb_flags, allrecord_up[1], allrecord_down[0]); exit(0); } close(allrecord_up[1]); close(allrecord_down[0]); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); traverse_child = fork(); ok(traverse_child != -1, "fork should succeed"); if (traverse_child == 0) { tdb_close(tdb); close(traverse_up[0]); close(traverse_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); do_traverse(name, tdb_flags, traverse_up[1], traverse_down[0]); exit(0); } close(traverse_up[1]); close(traverse_down[0]); poll(NULL, 0, 1000); nwritten = write(allrecord_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(traverse_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); nwritten = write(traverse_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "ret should succeed"); close(traverse_up[0]); close(traverse_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); diag("%s tests done", name); return exit_status(); } int main(int argc, char *argv[]) { int ret; bool mutex_support; mutex_support = tdb_runtime_check_for_robust_mutexes(); ret = do_tests("marklock-deadlock-fcntl.tdb", TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); if (!mutex_support) { skip(1, "No robust mutex support, " "skipping marklock-deadlock-mutex.tdb tests"); return exit_status(); } ret = do_tests("marklock-deadlock-mutex.tdb", TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c0000660000000000000000000000310412406075657020217 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; struct tdb_header hdr; int fd; plan_tests(11); /* Can open fine if complete crap, as long as O_CREAT. */ fd = open("run-bad-tdb-header.tdb", O_RDWR|O_CREAT|O_TRUNC, 0600); ok1(fd >= 0); ok1(write(fd, "hello world", 11) == 11); close(fd); tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(!tdb); tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); tdb_close(tdb); /* Now, with wrong version it should *not* overwrite. */ fd = open("run-bad-tdb-header.tdb", O_RDWR); ok1(fd >= 0); ok1(read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); ok1(hdr.version == TDB_VERSION); hdr.version++; lseek(fd, 0, SEEK_SET); ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); close(fd); tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT, 0600, &taplogctx, NULL); ok1(errno == EIO); ok1(!tdb); /* With truncate, will be fine. */ tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT|O_TRUNC, 0600, &taplogctx, NULL); ok1(tdb); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-check.c0000660000000000000000000000321012406075657016547 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(13); tdb = tdb_open_ex("run-check.tdb", 1, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("run-check.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == -1); ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); tdb_close(tdb); /* Big and little endian should work! */ tdb = tdb_open_ex("test/old-nohash-le.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-be.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-circular-chain.c0000660000000000000000000000150013573675413020360 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key; plan_tests(3); tdb = tdb_open_ex( "test/circular_chain.tdb", 0, TDB_DEFAULT, O_RDONLY, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("x"); key.dptr = discard_const_p(uint8_t, "x"); ok1(tdb_exists(tdb, key) == 0); ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-circular-freelist.c0000660000000000000000000000207713573675413021125 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(3); tdb = tdb_open_ex( "test/circular_freelist.tdb", 0, TDB_DEFAULT, O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); /* * All freelist records are just 1 byte key and value. Insert * something that will walk the whole freelist and hit the * circle. */ key.dsize = strlen("x"); key.dptr = discard_const_p(uint8_t, "x"); data.dsize = strlen("too long"); data.dptr = discard_const_p(uint8_t, "too long"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == -1); ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-corrupt.c0000660000000000000000000000660712406075657017205 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static int check(TDB_DATA key, TDB_DATA data, void *private) { unsigned int *sizes = private; if (key.dsize > strlen("hello")) return -1; if (memcmp(key.dptr, "hello", key.dsize) != 0) return -1; if (data.dsize != strlen("world")) return -1; if (memcmp(data.dptr, "world", data.dsize) != 0) return -1; sizes[0] += key.dsize; sizes[1] += data.dsize; return 0; } static void tdb_flip_bit(struct tdb_context *tdb, unsigned int bit) { unsigned int off = bit / CHAR_BIT; unsigned char mask = (1 << (bit % CHAR_BIT)); if (tdb->map_ptr) ((unsigned char *)tdb->map_ptr)[off] ^= mask; else { unsigned char c; if (pread(tdb->fd, &c, 1, off) != 1) { fprintf(stderr, "pread: %s\n", strerror(errno)); exit(1); } c ^= mask; if (pwrite(tdb->fd, &c, 1, off) != 1) { fprintf(stderr, "pwrite: %s\n", strerror(errno)); exit(1); } } } static void check_test(struct tdb_context *tdb) { TDB_DATA key, data; unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize; ok1(tdb_check(tdb, NULL, NULL) == 0); key.dptr = discard_const_p(uint8_t, "hello"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); /* Key and data size respectively. */ dsize = ksize = 0; /* 5 keys in hash size 2 means we'll have multichains. */ for (key.dsize = 1; key.dsize <= 5; key.dsize++) { ksize += key.dsize; dsize += data.dsize; if (tdb_store(tdb, key, data, TDB_INSERT) != 0) abort(); } /* This is how many bytes we expect to be verifiable. */ /* From the file header. */ verifiable = strlen(TDB_MAGIC_FOOD) + 1 + 2 * sizeof(uint32_t) + 2 * sizeof(tdb_off_t) + 2 * sizeof(uint32_t); /* From the free list chain and hash chains. */ verifiable += 3 * sizeof(tdb_off_t); /* From the record headers & tailer */ verifiable += 5 * (sizeof(struct tdb_record) + sizeof(uint32_t)); /* The free block: we ignore datalen, keylen, full_hash. */ verifiable += sizeof(struct tdb_record) - 3*sizeof(uint32_t) + sizeof(uint32_t); /* Our check function verifies the key and data. */ verifiable += ksize + dsize; /* Flip one bit at a time, make sure it detects verifiable bytes. */ for (i = 0, corrupt = 0; i < tdb->map_size * CHAR_BIT; i++) { tdb_flip_bit(tdb, i); memset(sizes, 0, sizeof(sizes)); if (tdb_check(tdb, check, sizes) != 0) corrupt++; else if (sizes[0] != ksize || sizes[1] != dsize) corrupt++; tdb_flip_bit(tdb, i); } ok(corrupt == verifiable * CHAR_BIT, "corrupt %u should be %u", corrupt, verifiable * CHAR_BIT); } int main(int argc, char *argv[]) { struct tdb_context *tdb; plan_tests(4); /* This should use mmap. */ tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (!tdb) abort(); check_test(tdb); tdb_close(tdb); /* This should not. */ tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST|TDB_NOMMAP, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (!tdb) abort(); check_test(tdb); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c0000660000000000000000000001203112406075657022045 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); static ssize_t write_check(int fd, const void *buf, size_t count); static int ftruncate_check(int fd, off_t length); #define pwrite pwrite_check #define write write_check #define fcntl fcntl_with_lockcheck #define ftruncate ftruncate_check #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "external-agent.h" #include "logging.h" #undef write #undef pwrite #undef fcntl #undef ftruncate static bool in_transaction; static int target, current; static jmp_buf jmpbuf; #define TEST_DBNAME "run-die-during-transaction.tdb" #define KEY_STRING "helloworld" static void maybe_die(int fd) { if (in_transaction && current++ == target) { longjmp(jmpbuf, 1); } } static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset) { ssize_t ret; maybe_die(fd); ret = pwrite(fd, buf, count, offset); if (ret != count) return ret; maybe_die(fd); return ret; } static ssize_t write_check(int fd, const void *buf, size_t count) { ssize_t ret; maybe_die(fd); ret = write(fd, buf, count); if (ret != count) return ret; maybe_die(fd); return ret; } static int ftruncate_check(int fd, off_t length) { int ret; maybe_die(fd); ret = ftruncate(fd, length); maybe_die(fd); return ret; } static bool test_death(enum operation op, struct agent *agent) { struct tdb_context *tdb = NULL; TDB_DATA key; enum agent_return ret; int needed_recovery = 0; current = target = 0; reset: unlink(TEST_DBNAME); tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (setjmp(jmpbuf) != 0) { /* We're partway through. Simulate our death. */ close(tdb->fd); forget_locking(); in_transaction = false; ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); if (ret == SUCCESS) needed_recovery++; else if (ret != FAILED) { diag("Step %u agent NEEDS_RECOVERY = %s", current, agent_return_name(ret)); return false; } ret = external_agent_operation(agent, op, KEY_STRING); if (ret != SUCCESS) { diag("Step %u op %s failed = %s", current, operation_name(op), agent_return_name(ret)); return false; } ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); if (ret != FAILED) { diag("Still needs recovery after step %u = %s", current, agent_return_name(ret)); return false; } ret = external_agent_operation(agent, CHECK, ""); if (ret != SUCCESS) { diag("Step %u check failed = %s", current, agent_return_name(ret)); return false; } ret = external_agent_operation(agent, CLOSE, ""); if (ret != SUCCESS) { diag("Step %u close failed = %s", current, agent_return_name(ret)); return false; } /* Suppress logging as this tries to use closed fd. */ suppress_logging = true; suppress_lockcheck = true; tdb_close(tdb); suppress_logging = false; suppress_lockcheck = false; target++; current = 0; goto reset; } /* Put key for agent to fetch. */ key.dsize = strlen(KEY_STRING); key.dptr = discard_const_p(uint8_t, KEY_STRING); if (tdb_store(tdb, key, key, TDB_INSERT) != 0) return false; /* This is the key we insert in transaction. */ key.dsize--; ret = external_agent_operation(agent, OPEN, TEST_DBNAME); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to open: %s\n", agent_return_name(ret)); exit(1); } ret = external_agent_operation(agent, FETCH, KEY_STRING); if (ret != SUCCESS) { fprintf(stderr, "Agent failed find key: %s\n", agent_return_name(ret)); exit(1); } in_transaction = true; if (tdb_transaction_start(tdb) != 0) return false; if (tdb_store(tdb, key, key, TDB_INSERT) != 0) return false; if (tdb_transaction_commit(tdb) != 0) return false; in_transaction = false; /* We made it! */ diag("Completed %u runs", current); tdb_close(tdb); ret = external_agent_operation(agent, CLOSE, ""); if (ret != SUCCESS) { diag("Step %u close failed = %s", current, agent_return_name(ret)); return false; } #ifdef HAVE_INCOHERENT_MMAP /* This means we always mmap, which makes this test a noop. */ ok1(1); #else ok1(needed_recovery); #endif ok1(locking_errors == 0); ok1(forget_locking() == 0); locking_errors = 0; return true; } int main(int argc, char *argv[]) { enum operation ops[] = { FETCH, STORE, TRANSACTION_START }; struct agent *agent; int i; plan_tests(12); unlock_callback = maybe_die; agent = prepare_external_agent(); for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { diag("Testing %s after death", operation_name(ops[i])); ok1(test_death(ops[i], agent)); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-endian.c0000660000000000000000000000325412406075657016740 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(13); tdb = tdb_open_ex("run-endian.tdb", 1024, TDB_CLEAR_IF_FIRST|TDB_CONVERT, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); ok1(tdb_error(tdb) == TDB_ERR_EXISTS); ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); key.dsize++; data = tdb_fetch(tdb, key); ok1(data.dptr == NULL); tdb_close(tdb); /* Reopen: should read it */ tdb = tdb_open_ex("run-endian.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c0000660000000000000000000001174213120574744020350 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include #include "tap-interface.h" /* * This tests the low level locking requirement * for the allrecord lock/prepare_commit and traverse_read interaction. * * The pattern with the traverse_read and prepare_commit interaction is * the following: * * 1. transaction_start got the allrecord lock with F_RDLCK. * * 2. the traverse_read code walks the database in a sequence like this * (per chain): * 2.1 chainlock(chainX, F_RDLCK) * 2.2 recordlock(chainX.record1, F_RDLCK) * 2.3 chainunlock(chainX, F_RDLCK) * 2.4 callback(chainX.record1) * 2.5 chainlock(chainX, F_RDLCK) * 2.6 recordunlock(chainX.record1, F_RDLCK) * 2.7 recordlock(chainX.record2, F_RDLCK) * 2.8 chainunlock(chainX, F_RDLCK) * 2.9 callback(chainX.record2) * 2.10 chainlock(chainX, F_RDLCK) * 2.11 recordunlock(chainX.record2, F_RDLCK) * 2.12 chainunlock(chainX, F_RDLCK) * 2.13 goto next chain * * So it has always one record locked in F_RDLCK mode and tries to * get the 2nd one before it releases the first one. * * 3. prepare_commit tries to upgrade the allrecord lock to F_RWLCK * If that happens at the time of 2.4, the operation of * 2.5 may deadlock with the allrecord lock upgrade. * On Linux step 2.5 works in order to make some progress with the * locking, but on solaris it might fail because the kernel * wants to satisfy the 1st lock requester before the 2nd one. * * I think the first step is a standalone test that does this: * * process1: F_RDLCK for ofs=0 len=2 * process2: F_RDLCK for ofs=0 len=1 * process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) * process2: F_RDLCK for ofs=1 len=1 * process2: unlock ofs=0 len=2 * process1: should continue at that point * * Such a test follows here... */ static int raw_fcntl_lock(int fd, int rw, off_t off, off_t len, bool waitflag) { struct flock fl; int cmd; fl.l_type = rw; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; cmd = waitflag ? F_SETLKW : F_SETLK; return fcntl(fd, cmd, &fl); } static int raw_fcntl_unlock(int fd, off_t off, off_t len) { struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; return fcntl(fd, F_SETLKW, &fl); } int pipe_r; int pipe_w; char buf[2]; static void expect_char(char c) { read(pipe_r, buf, 1); if (*buf != c) { fail("We were expecting %c, but got %c", c, buf[0]); } } static void send_char(char c) { write(pipe_w, &c, 1); } int main(int argc, char *argv[]) { int process; int fd; const char *filename = "run-fcntl-deadlock.lck"; int pid; int pipes_1_2[2]; int pipes_2_1[2]; int ret; pipe(pipes_1_2); pipe(pipes_2_1); fd = open(filename, O_RDWR | O_CREAT, 0755); pid = fork(); if (pid == 0) { pipe_r = pipes_1_2[0]; pipe_w = pipes_2_1[1]; process = 2; alarm(15); } else { pipe_r = pipes_2_1[0]; pipe_w = pipes_1_2[1]; process = 1; alarm(15); } /* a: process1: F_RDLCK for ofs=0 len=2 */ if (process == 1) { ret = raw_fcntl_lock(fd, F_RDLCK, 0, 2, true); ok(ret == 0, "process 1 lock ofs=0 len=2: %d - %s", ret, strerror(errno)); diag("process 1 took read lock on range 0,2"); send_char('a'); } /* process2: F_RDLCK for ofs=0 len=1 */ if (process == 2) { expect_char('a'); ret = raw_fcntl_lock(fd, F_RDLCK, 0, 1, true); ok(ret == 0, "process 2 lock ofs=0 len=1: %d - %s", ret, strerror(errno));; diag("process 2 took read lock on range 0,1"); send_char('b'); } /* process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) */ if (process == 1) { expect_char('b'); send_char('c'); diag("process 1 starts upgrade on range 0,2"); ret = raw_fcntl_lock(fd, F_WRLCK, 0, 2, true); ok(ret == 0, "process 1 RW lock ofs=0 len=2: %d - %s", ret, strerror(errno)); diag("process 1 got read upgrade done"); /* at this point process 1 is blocked on 2 releasing the read lock */ } /* * process2: F_RDLCK for ofs=1 len=1 * process2: unlock ofs=0 len=2 */ if (process == 2) { expect_char('c'); /* we know process 1 is *about* to lock */ sleep(1); ret = raw_fcntl_lock(fd, F_RDLCK, 1, 1, true); ok(ret == 0, "process 2 lock ofs=1 len=1: %d - %s", ret, strerror(errno)); diag("process 2 got read lock on 1,1\n"); ret = raw_fcntl_unlock(fd, 0, 2); ok(ret == 0, "process 2 unlock ofs=0 len=2: %d - %s", ret, strerror(errno)); diag("process 2 released read lock on 0,2\n"); sleep(1); send_char('d'); } if (process == 1) { expect_char('d'); } diag("process %d has got to the end\n", process); return 0; } ldb-2.0.8/lib/tdb/test/run-incompatible.c0000660000000000000000000001131012520121120020106 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include static unsigned int tdb_dumb_hash(TDB_DATA *key) { return key->dsize; } static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); if (strstr(fmt, "hash")) (*count)++; } static unsigned int hdr_rwlocks(const char *fname) { struct tdb_header hdr; ssize_t nread; int fd = open(fname, O_RDONLY); if (fd == -1) return -1; nread = read(fd, &hdr, sizeof(hdr)); close(fd); if (nread != sizeof(hdr)) { return -1; } return hdr.rwlocks; } int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count, flags; TDB_DATA d, r; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(38 * 2); for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) { unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC; if (flags & TDB_CONVERT) tdb_convert(&rwmagic, sizeof(rwmagic)); /* Create an old-style hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, flags, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Should not have marked rwlocks field. */ ok1(hdr_rwlocks("run-incompatible.tdb") == 0); /* We can still open any old-style with incompat flag. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, TDB_INCOMPATIBLE_HASH, O_RDWR, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* OK, now create with incompatible flag, default hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, flags|TDB_INCOMPATIBLE_HASH, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Should have marked rwlocks field. */ ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); /* Cannot open with old hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0600, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); /* Can open with jenkins hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0600, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* Can open by letting it figure it out itself. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* We can also use incompatible hash with other hashes. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, flags|TDB_INCOMPATIBLE_HASH, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, tdb_dumb_hash); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Should have marked rwlocks field. */ ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); /* It should not open if we don't specify. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(!tdb); ok1(log_count == 1); /* Should reopen with correct hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_dumb_hash); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c0000660000000000000000000001634313573675413021056 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "logging.h" static TDB_DATA key, data; static void do_chainlock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); exit(0); } static void do_allrecord_lock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); exit(0); } /* The code should barf on TDBs created with rwlocks. */ static int do_tests(const char *name, int tdb_flags) { struct tdb_context *tdb; int ret; pid_t chainlock_child, allrecord_child; int chainlock_down[2]; int chainlock_up[2]; int allrecord_down[2]; int allrecord_up[2]; char c; ssize_t nread, nwritten; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ret = pipe(chainlock_down); ok(ret == 0, "pipe should succeed"); ret = pipe(chainlock_up); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_down); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_up); ok(ret == 0, "pipe should succeed"); chainlock_child = fork(); ok(chainlock_child != -1, "fork should succeed"); if (chainlock_child == 0) { close(chainlock_up[0]); close(chainlock_down[1]); close(allrecord_up[0]); close(allrecord_up[1]); close(allrecord_down[0]); close(allrecord_down[1]); do_chainlock(name, tdb_flags, chainlock_up[1], chainlock_down[0]); exit(0); } close(chainlock_up[1]); close(chainlock_down[0]); nread = read(chainlock_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); /* * Now we have a process holding a chainlock. Start another process * trying the allrecord lock. This will block. */ allrecord_child = fork(); ok(allrecord_child != -1, "fork should succeed"); if (allrecord_child == 0) { close(chainlock_up[0]); close(chainlock_up[1]); close(chainlock_down[0]); close(chainlock_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); do_allrecord_lock(name, tdb_flags, allrecord_up[1], allrecord_down[0]); exit(0); } close(allrecord_up[1]); close(allrecord_down[0]); poll(NULL, 0, 500); tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); /* * Someone already holds a chainlock, but we're able to get the * freelist lock. * * The freelist lock/mutex is independent from the allrecord lock/mutex. */ ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); /* * We have someone else having done the lock for us. Just mark it. */ ret = tdb_chainlock_mark(tdb, key); ok(ret == 0, "tdb_chainlock_mark should succeed"); /* * The tdb_store below will block the freelist. In one version of the * mutex patches, the freelist was already blocked here by the * allrecord child, which was waiting for the chainlock child to give * up its chainlock. Make sure that we don't run into this * deadlock. To exercise the deadlock, just comment out the "ok" * line. * * The freelist lock/mutex is independent from the allrecord lock/mutex. */ ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store should succeed"); ret = tdb_chainlock_unmark(tdb, key); ok(ret == 0, "tdb_chainlock_unmark should succeed"); nwritten = write(chainlock_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(chainlock_up[0], &c, sizeof(c)); ok(nread == 0, "read should succeed"); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); /* * Someone already holds the allrecord lock, but we're able to get the * freelist lock. * * The freelist lock/mutex is independent from the allrecord lock/mutex. */ ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); ret = tdb_lockall_nonblock(tdb); ok(ret == -1, "tdb_lockall_nonblock should not succeed"); ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); /* * We have someone else having done the lock for us. Just mark it. */ ret = tdb_lockall_mark(tdb); ok(ret == 0, "tdb_lockall_mark should succeed"); ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); ret = tdb_store(tdb, key, data, TDB_REPLACE); ok(ret == 0, "tdb_store should succeed"); ret = tdb_lockall_unmark(tdb); ok(ret == 0, "tdb_lockall_unmark should succeed"); nwritten = write(allrecord_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == 0, "read should succeed"); close(chainlock_up[0]); close(chainlock_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); diag("%s tests done", name); return exit_status(); } int main(int argc, char *argv[]) { int ret; bool mutex_support; mutex_support = tdb_runtime_check_for_robust_mutexes(); ret = do_tests("marklock-deadlock-fcntl.tdb", TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); if (!mutex_support) { skip(1, "No robust mutex support, " "skipping marklock-deadlock-mutex.tdb tests"); return exit_status(); } ret = do_tests("marklock-deadlock-mutex.tdb", TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c0000660000000000000000000000400612406075657021662 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2) { return (tv2->tv_sec - tv1->tv_sec) + (tv2->tv_usec - tv1->tv_usec)*1.0e-6; } static double timeval_elapsed(const struct timeval *tv) { struct timeval tv2; gettimeofday(&tv2, NULL); return timeval_elapsed2(tv, &tv2); } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; struct timeval start; double elapsed; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); tdb = tdb_open_ex("mutex-allrecord-bench.tdb", 1000000, TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); gettimeofday(&start, NULL); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); elapsed = timeval_elapsed(&start); ok(ret == 0, "tdb_allrecord_lock should succeed"); diag("allrecord_lock took %f seconds", elapsed); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c0000660000000000000000000000546112406075657021703 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-allrecord-block.tdb", 3, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); ok(ret == 0, "tdb_allrecord_unlock should succeed"); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-allrecord-block.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); write(tochild[1], &c, sizeof(c)); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should not succeed"); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c0000660000000000000000000000515412406075657022277 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 3, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); ok(ret == -1, "tdb_allrecord_lock (nowait) should not succeed"); write(tochild[1], &c, sizeof(c)); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-die.c0000660000000000000000000001160612406075657017403 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); static ssize_t write_check(int fd, const void *buf, size_t count); static int ftruncate_check(int fd, off_t length); #define pwrite pwrite_check #define write write_check #define fcntl fcntl_with_lockcheck #define ftruncate ftruncate_check #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include "external-agent.h" #include "logging.h" #undef write #undef pwrite #undef fcntl #undef ftruncate static int target, current; #define TEST_DBNAME "run-mutex-die.tdb" #define KEY_STRING "helloworld" static void maybe_die(int fd) { if (target == 0) { return; } current += 1; if (current == target) { _exit(1); } } static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset) { ssize_t ret; maybe_die(fd); ret = pwrite(fd, buf, count, offset); if (ret != count) return ret; maybe_die(fd); return ret; } static ssize_t write_check(int fd, const void *buf, size_t count) { ssize_t ret; maybe_die(fd); ret = write(fd, buf, count); if (ret != count) return ret; maybe_die(fd); return ret; } static int ftruncate_check(int fd, off_t length) { int ret; maybe_die(fd); ret = ftruncate(fd, length); maybe_die(fd); return ret; } static enum agent_return flakey_ops(struct agent *a) { enum agent_return ret; /* * Run in the external agent child */ ret = external_agent_operation(a, OPEN_WITH_CLEAR_IF_FIRST, TEST_DBNAME); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to open: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, UNMAP, ""); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to unmap: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, STORE, "xyz"); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to store: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, STORE, KEY_STRING); if (ret != SUCCESS) { fprintf(stderr, "Agent failed store: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, FETCH, KEY_STRING); if (ret != SUCCESS) { fprintf(stderr, "Agent failed find key: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, PING, ""); if (ret != SUCCESS) { fprintf(stderr, "Agent failed ping: %s\n", agent_return_name(ret)); return ret; } return ret; } static bool prep_db(void) { struct tdb_context *tdb; TDB_DATA key; TDB_DATA data; key.dptr = discard_const_p(uint8_t, KEY_STRING); key.dsize = strlen((char *)key.dptr); data.dptr = discard_const_p(uint8_t, "foo"); data.dsize = strlen((char *)data.dptr); unlink(TEST_DBNAME); tdb = tdb_open_ex( TEST_DBNAME, 2, TDB_INCOMPATIBLE_HASH|TDB_MUTEX_LOCKING|TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (tdb == NULL) { return false; } if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { return false; } tdb_close(tdb); tdb = NULL; forget_locking(); return true; } static bool test_db(void) { struct tdb_context *tdb; int ret; tdb = tdb_open_ex( TEST_DBNAME, 1024, TDB_INCOMPATIBLE_HASH, O_RDWR, 0600, &taplogctx, NULL); if (tdb == NULL) { perror("tdb_open_ex failed"); return false; } ret = tdb_traverse(tdb, NULL, NULL); if (ret == -1) { perror("traverse failed"); goto fail; } tdb_close(tdb); forget_locking(); return true; fail: tdb_close(tdb); return false; } static bool test_one(void) { enum agent_return ret; ret = AGENT_DIED; target = 19; while (ret != SUCCESS) { struct agent *agent; { int child_target = target; bool pret; target = 0; pret = prep_db(); ok1(pret); target = child_target; } agent = prepare_external_agent(); ret = flakey_ops(agent); diag("Agent (target=%d) returns %s", target, agent_return_name(ret)); if (ret == SUCCESS) { ok((target > 19), "At least one AGENT_DIED expected"); } else { ok(ret == AGENT_DIED, "AGENT_DIED expected"); } shutdown_agent(agent); { int child_target = target; bool tret; target = 0; tret = test_db(); ok1(tret); target = child_target; } target += 1; } return true; } int main(int argc, char *argv[]) { bool ret; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } plan_tests(12); unlock_callback = maybe_die; ret = test_one(); ok1(ret); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c0000660000000000000000000000766413573675413020715 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include static TDB_DATA key, data; static void log_void(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { } static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int fd) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; struct tdb_logging_context nolog_ctx = { log_void, NULL }; char c; read(fd, &c, 1); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_DEFAULT without " "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_CLEAR_IF_FIRST without " "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_INTERNAL, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " "TDB_INTERNAL should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_NOMMAP, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " "TDB_NOMMAP should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING, O_RDONLY, 0755, &nolog_ctx, NULL); ok((tdb != NULL), "TDB_MUTEX_LOCKING with " "O_RDONLY should work - %d", errno); tdb_close(tdb); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok((tdb != NULL), "TDB_MUTEX_LOCKING with TDB_CLEAR_IF_FIRST" "TDB_NOMMAP should work - %d", errno); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; struct tdb_logging_context nolog_ctx = { log_void, NULL }; int ret, status; pid_t child, wait_ret; int pipefd[2]; char c = 0; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); ret = pipe(pipefd); ok1(ret == 0); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); if (!runtime_support) { tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST| TDB_MUTEX_LOCKING, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == ENOSYS), "TDB_MUTEX_LOCKING without " "runtime support should fail with ENOSYS - %d", errno); skip(1, "No robust mutex support"); return exit_status(); } child = fork(); if (child == 0) { return do_child(pipefd[0]); } tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST| TDB_MUTEX_LOCKING, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok((tdb != NULL), "tdb_open_ex with mutexes should succeed"); write(pipefd[1], &c, 1); wait_ret = wait(&status); ok((wait_ret == child) && (status == 0), "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c0000660000000000000000000001416512445751350021245 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-transaction1.tdb", 3, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_cancel(tdb); ok(ret == 0, "tdb_transaction_cancel should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_commit(tdb); ok(ret == 0, "tdb_transaction_commit should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); ret = tdb_store(tdb, key, key, TDB_REPLACE); ok(ret == 0, "tdb_store(tdb, key, data, TDB_REPLACE) should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_commit(tdb); ok(ret == 0, "tdb_transaction_commit should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; TDB_DATA val; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-transaction1.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); /* * The child has the transaction running */ ret = tdb_transaction_start_nonblock(tdb); ok(ret == -1, "tdb_transaction_start_nonblock not succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); /* * We can still read */ ret = tdb_exists(tdb, key); ok(ret == 0, "tdb_exists(tdb, key) should return 0"); val = tdb_fetch(tdb, key); ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); write(tochild[1], &c, sizeof(c)); /* * When the child canceled we can start... */ ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); read(fromchild[0], &c, sizeof(c)); write(tochild[1], &c, sizeof(c)); ret = tdb_transaction_cancel(tdb); ok(ret == 0, "tdb_transaction_cancel should succeed"); /* * When we canceled the child can start and store... */ read(fromchild[0], &c, sizeof(c)); /* * We still see the old values before the child commits... */ ret = tdb_exists(tdb, key); ok(ret == 0, "tdb_exists(tdb, key) should return 0"); val = tdb_fetch(tdb, key); ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); /* * We see the new values after the commit... */ ret = tdb_exists(tdb, key); ok(ret == 1, "tdb_exists(tdb, key) should return 1"); val = tdb_fetch(tdb, key); ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); /* * The child started a new transaction and replaces the value, * but we still see the old values before the child commits... */ ret = tdb_exists(tdb, key); ok(ret == 1, "tdb_exists(tdb, key) should return 1"); val = tdb_fetch(tdb, key); ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); /* * We see the new values after the commit... */ ret = tdb_exists(tdb, key); ok(ret == 1, "tdb_exists(tdb, key) should return 1"); val = tdb_fetch(tdb, key); ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); ok(val.dsize == key.dsize, "tdb_fetch(tdb, key) should return a value"); ok(memcmp(val.dptr, key.dptr, key.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); write(tochild[1], &c, sizeof(c)); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c0000660000000000000000000000546112406075657020333 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); write(to, &c, sizeof(c)); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == 0, "tdb_chainlock_nonblock should succeed"); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex1.c0000660000000000000000000000642712406075657016732 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); ret = tdb_store(tdb, key, data, 0); ok(ret == 0, "tdb_store should succeed"); ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); ok(ret == 0, "tdb_allrecord_unlock should succeed"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); write(tochild[1], &c, sizeof(c)); ret = tdb_delete(tdb, key); ok(ret == 0, "tdb_delete should succeed"); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-nested-transactions.c0000660000000000000000000000435712406075657021477 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(27); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); tdb = tdb_open_ex("run-nested-transactions.tdb", 1024, TDB_CLEAR_IF_FIRST|TDB_DISALLOW_NESTING, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); /* Nesting disallowed. */ ok1(tdb_transaction_start(tdb) == 0); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); ok1(tdb_transaction_start(tdb) != 0); ok1(tdb_error(tdb) == TDB_ERR_NESTING); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); ok1(tdb_transaction_commit(tdb) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); tdb_close(tdb); /* Nesting allowed by default */ tdb = tdb_open_ex("run-nested-transactions.tdb", 1024, TDB_DEFAULT, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_delete(tdb, key) == 0); ok1(tdb_transaction_commit(tdb) == 0); ok1(!tdb_exists(tdb, key)); ok1(tdb_transaction_cancel(tdb) == 0); /* Surprise! Kills inner "committed" transaction. */ ok1(tdb_exists(tdb, key)); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_delete(tdb, key) == 0); ok1(tdb_transaction_commit(tdb) == 0); ok1(!tdb_exists(tdb, key)); ok1(tdb_transaction_commit(tdb) == 0); ok1(!tdb_exists(tdb, key)); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-nested-traverse.c0000660000000000000000000000600613126252766020611 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" #define fcntl fcntl_with_lockcheck #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #undef fcntl #include #include #include "external-agent.h" #include "logging.h" static struct agent *agent; static bool correct_key(TDB_DATA key) { return key.dsize == strlen("hi") && memcmp(key.dptr, "hi", key.dsize) == 0; } static bool correct_data(TDB_DATA data) { return data.dsize == strlen("world") && memcmp(data.dptr, "world", data.dsize) == 0; } static int traverse2(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); return 0; } static int traverse1r(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse(tdb, traverse2, NULL); /* That should *not* release the all-records lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); return 0; } static int traverse1w(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse(tdb, traverse2, NULL); /* That should *not* release the all-records lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(17); agent = prepare_external_agent(); tdb = tdb_open_ex("run-nested-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) == SUCCESS); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); tdb_traverse(tdb, traverse1w, NULL); tdb_traverse_read(tdb, traverse1r, NULL); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c0000660000000000000000000000467112406075657022167 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" #define fcntl fcntl_with_lockcheck #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" #undef fcntl #define NUM_ENTRIES 10 static bool prepare_entries(struct tdb_context *tdb) { unsigned int i; TDB_DATA key, data; for (i = 0; i < NUM_ENTRIES; i++) { key.dsize = sizeof(i); key.dptr = (void *)&i; data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); if (tdb_store(tdb, key, data, 0) != 0) return false; } return true; } static void delete_entries(struct tdb_context *tdb) { unsigned int i; TDB_DATA key; for (i = 0; i < NUM_ENTRIES; i++) { key.dsize = sizeof(i); key.dptr = (void *)&i; ok1(tdb_delete(tdb, key) == 0); } } /* We don't know how many times this will run. */ static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { unsigned int i; memcpy(&i, key.dptr, 4); i = (i + 1) % NUM_ENTRIES; key.dptr = (void *)&i; if (tdb_delete(tdb, key) != 0) (*(int *)private_data)++; return 0; } static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { ok1(tdb_delete(tdb, key) == 0); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; int errors = 0; plan_tests(41); tdb = tdb_open_ex("run-no-lock-during-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); ok1(prepare_entries(tdb)); ok1(locking_errors == 0); ok1(tdb_lockall(tdb) == 0); ok1(locking_errors == 0); tdb_traverse(tdb, delete_other, &errors); ok1(errors == 0); ok1(locking_errors == 0); ok1(tdb_unlockall(tdb) == 0); ok1(prepare_entries(tdb)); ok1(locking_errors == 0); ok1(tdb_lockall(tdb) == 0); ok1(locking_errors == 0); tdb_traverse(tdb, delete_self, NULL); ok1(locking_errors == 0); ok1(tdb_unlockall(tdb) == 0); ok1(prepare_entries(tdb)); ok1(locking_errors == 0); ok1(tdb_lockall(tdb) == 0); ok1(locking_errors == 0); delete_entries(tdb); ok1(locking_errors == 0); ok1(tdb_unlockall(tdb) == 0); ok1(tdb_close(tdb) == 0); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-oldhash.c0000660000000000000000000000242512406075657017123 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; plan_tests(8); /* Old format (with zeroes in the hash magic fields) should * open with any hash (since we don't know what hash they used). */ tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, &taplogctx, tdb_jenkins_hash); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, &taplogctx, tdb_jenkins_hash); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c0000660000000000000000000001012412520121120022214 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); static ssize_t write_check(int fd, const void *buf, size_t count); static int ftruncate_check(int fd, off_t length); #define pwrite pwrite_check #define write write_check #define fcntl fcntl_with_lockcheck #define ftruncate ftruncate_check #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include "external-agent.h" #include "logging.h" static struct agent *agent; static bool opened; static int errors = 0; static bool clear_if_first; #define TEST_DBNAME "run-open-during-transaction.tdb" #undef write #undef pwrite #undef fcntl #undef ftruncate static bool is_same(const char *snapshot, const char *latest, off_t len) { unsigned i; for (i = 0; i < len; i++) { if (snapshot[i] != latest[i]) return false; } return true; } static bool compare_file(int fd, const char *snapshot, off_t snapshot_len) { char *contents; bool same; /* over-length read serves as length check. */ contents = malloc(snapshot_len+1); same = pread(fd, contents, snapshot_len+1, 0) == snapshot_len && is_same(snapshot, contents, snapshot_len); free(contents); return same; } static void check_file_intact(int fd) { enum agent_return ret; struct stat st; char *contents; fstat(fd, &st); contents = malloc(st.st_size); if (pread(fd, contents, st.st_size, 0) != st.st_size) { diag("Read fail"); errors++; free(contents); return; } /* Ask agent to open file. */ ret = external_agent_operation(agent, clear_if_first ? OPEN_WITH_CLEAR_IF_FIRST : OPEN, TEST_DBNAME); /* It's OK to open it, but it must not have changed! */ if (!compare_file(fd, contents, st.st_size)) { diag("Agent changed file after opening %s", agent_return_name(ret)); errors++; } if (ret == SUCCESS) { ret = external_agent_operation(agent, CLOSE, NULL); if (ret != SUCCESS) { diag("Agent failed to close tdb: %s", agent_return_name(ret)); errors++; } } else if (ret != WOULD_HAVE_BLOCKED) { diag("Agent opening file gave %s", agent_return_name(ret)); errors++; } free(contents); } static void after_unlock(int fd) { if (opened) check_file_intact(fd); } static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset) { if (opened) check_file_intact(fd); return pwrite(fd, buf, count, offset); } static ssize_t write_check(int fd, const void *buf, size_t count) { if (opened) check_file_intact(fd); return write(fd, buf, count); } static int ftruncate_check(int fd, off_t length) { if (opened) check_file_intact(fd); return ftruncate(fd, length); } int main(int argc, char *argv[]) { const int flags[] = { TDB_DEFAULT, TDB_CLEAR_IF_FIRST, TDB_NOMMAP, TDB_CLEAR_IF_FIRST | TDB_NOMMAP }; int i; struct tdb_context *tdb; TDB_DATA key, data; plan_tests(20); agent = prepare_external_agent(); unlock_callback = after_unlock; for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) { clear_if_first = (flags[i] & TDB_CLEAR_IF_FIRST); diag("Test with %s and %s", clear_if_first ? "CLEAR" : "DEFAULT", (flags[i] & TDB_NOMMAP) ? "no mmap" : "mmap"); unlink(TEST_DBNAME); tdb = tdb_open_ex(TEST_DBNAME, 1024, flags[i], O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); opened = true; ok1(tdb_transaction_start(tdb) == 0); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_transaction_commit(tdb) == 0); ok(!errors, "We had %u open errors", errors); opened = false; tdb_close(tdb); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c0000660000000000000000000000760413100601766020374 0ustar rootroot00000000000000#include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "logging.h" static TDB_DATA key, data; static void do_chainlock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock_read(tdb, key); ok(ret == 0, "tdb_chainlock_read should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == 0, "read should succeed"); exit(0); } static void do_trylock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); /* * tdb used to have a bug where with fcntl locks an upgrade * from a readlock to writelock did not check for the * underlying fcntl lock. Mutexes don't distinguish between * readlocks and writelocks, so that bug does not apply here. */ ret = tdb_chainlock_read(tdb, key); ok(ret == 0, "tdb_chainlock_read should succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should fail"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == 0, "read should succeed"); exit(0); } static int do_tests(const char *name, int tdb_flags) { int ret; pid_t chainlock_child, store_child; int chainlock_down[2]; int chainlock_up[2]; int store_down[2]; int store_up[2]; char c; ssize_t nread; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ret = pipe(chainlock_down); ok(ret == 0, "pipe should succeed"); ret = pipe(chainlock_up); ok(ret == 0, "pipe should succeed"); ret = pipe(store_down); ok(ret == 0, "pipe should succeed"); ret = pipe(store_up); ok(ret == 0, "pipe should succeed"); chainlock_child = fork(); ok(chainlock_child != -1, "fork should succeed"); if (chainlock_child == 0) { close(chainlock_up[0]); close(chainlock_down[1]); close(store_up[0]); close(store_up[1]); close(store_down[0]); close(store_down[1]); do_chainlock(name, tdb_flags, chainlock_up[1], chainlock_down[0]); exit(0); } close(chainlock_up[1]); close(chainlock_down[0]); nread = read(chainlock_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); /* * Now we have a process holding a chain read lock. Start * another process trying to write lock. This should fail. */ store_child = fork(); ok(store_child != -1, "fork should succeed"); if (store_child == 0) { close(chainlock_up[0]); close(chainlock_down[1]); close(store_up[0]); close(store_down[1]); do_trylock(name, tdb_flags, store_up[1], store_down[0]); exit(0); } close(store_up[1]); close(store_down[0]); nread = read(store_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); close(chainlock_up[0]); close(chainlock_down[1]); close(store_up[0]); close(store_down[1]); diag("%s tests done", name); return exit_status(); } int main(int argc, char *argv[]) { int ret; ret = do_tests("rdlock-upgrade.tdb", TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "rdlock-upgrade.tdb tests should succeed"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-readonly-check.c0000660000000000000000000000275612406075657020400 0ustar rootroot00000000000000/* We should be able to tdb_check a O_RDONLY tdb, and we were previously allowed * to tdb_check() inside a transaction (though that's paranoia!). */ #include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(11); tdb = tdb_open_ex("run-readonly-check.tdb", 1024, TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); /* We are also allowed to do a check inside a transaction. */ ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_close(tdb) == 0); tdb = tdb_open_ex("run-readonly-check.tdb", 1024, TDB_DEFAULT, O_RDONLY, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_store(tdb, key, data, TDB_MODIFY) == -1); ok1(tdb_error(tdb) == TDB_ERR_RDONLY); ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_close(tdb) == 0); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c0000660000000000000000000000215012406075657021121 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/rescue.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" #define NUM 20 /* Binary searches are deceptively simple: easy to screw up! */ int main(int argc, char *argv[]) { unsigned int i, j, n; struct found f[NUM+1]; struct found_table table; /* Set up array for searching. */ for (i = 0; i < NUM+1; i++) { f[i].head = i * 3; } table.arr = f; for (i = 0; i < NUM; i++) { table.num = i; for (j = 0; j < (i + 2) * 3; j++) { n = find_entry(&table, j); ok1(n <= i); /* If we were searching for something too large... */ if (j > i*3) ok1(n == i); else { /* It must give us something after j */ ok1(f[n].head >= j); ok1(n == 0 || f[n-1].head < j); } } } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rescue.c0000660000000000000000000000566012406075657016773 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/rescue.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" struct walk_data { TDB_DATA key; TDB_DATA data; bool fail; unsigned count; }; static inline bool tdb_deq(TDB_DATA a, TDB_DATA b) { return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; } static inline TDB_DATA tdb_mkdata(const void *p, size_t len) { TDB_DATA d; d.dptr = discard_const_p(uint8_t, p); d.dsize = len; return d; } static void walk(TDB_DATA key, TDB_DATA data, void *_wd) { struct walk_data *wd = _wd; if (!tdb_deq(key, wd->key)) { wd->fail = true; } if (!tdb_deq(data, wd->data)) { wd->fail = true; } wd->count++; } static void count_records(TDB_DATA key, TDB_DATA data, void *_wd) { struct walk_data *wd = _wd; if (!tdb_deq(key, wd->key) || !tdb_deq(data, wd->data)) diag("%.*s::%.*s", (int)key.dsize, key.dptr, (int)data.dsize, data.dptr); wd->count++; } static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); (*count)++; } int main(int argc, char *argv[]) { struct tdb_context *tdb; struct walk_data wd; unsigned int i, size, log_count = 0; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(8); tdb = tdb_open_ex("run-rescue.tdb", 1, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &log_ctx, NULL); wd.key.dsize = strlen("hi"); wd.key.dptr = discard_const_p(uint8_t, "hi"); wd.data.dsize = strlen("world"); wd.data.dptr = discard_const_p(uint8_t, "world"); wd.count = 0; wd.fail = false; ok1(tdb_store(tdb, wd.key, wd.data, TDB_INSERT) == 0); ok1(tdb_rescue(tdb, walk, &wd) == 0); ok1(!wd.fail); ok1(wd.count == 1); /* Corrupt the database, walk should either get it or not. */ size = tdb->map_size; for (i = sizeof(struct tdb_header); i < size; i++) { char c; if (tdb->methods->tdb_read(tdb, i, &c, 1, false) != 0) fail("Reading offset %i", i); if (tdb->methods->tdb_write(tdb, i, "X", 1) != 0) fail("Writing X at offset %i", i); wd.count = 0; if (tdb_rescue(tdb, count_records, &wd) != 0) { wd.fail = true; break; } /* Could be 0 or 1. */ if (wd.count > 1) { wd.fail = true; break; } if (tdb->methods->tdb_write(tdb, i, &c, 1) != 0) fail("Restoring offset %i", i); } ok1(log_count == 0); ok1(!wd.fail); tdb_close(tdb); /* Now try our known-corrupt db. */ tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, &taplogctx, NULL); wd.count = 0; ok1(tdb_rescue(tdb, count_records, &wd) == 0); ok1(wd.count == 1627); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rwlock-check.c0000660000000000000000000000223312406075657020052 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); if (strstr(fmt, "spinlocks")) (*count)++; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(4); /* We should fail to open rwlock-using tdbs of either endian. */ log_count = 0; tdb = tdb_open_ex("test/rwlock-le.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb_open_ex("test/rwlock-be.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(!tdb); ok1(log_count == 1); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-summary.c0000660000000000000000000000421612406075657017176 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/summary.c" #include "../common/mutex.c" #include "tap-interface.h" #include int main(int argc, char *argv[]) { unsigned int i, j; struct tdb_context *tdb; int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP, TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; TDB_DATA key = { (unsigned char *)&j, sizeof(j) }; TDB_DATA data = { (unsigned char *)&j, sizeof(j) }; char *summary; plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { tdb = tdb_open("run-summary.tdb", 131, flags[i], O_RDWR|O_CREAT|O_TRUNC, 0600); ok1(tdb); if (!tdb) continue; /* Put some stuff in there. */ for (j = 0; j < 500; j++) { /* Make sure padding varies to we get some graphs! */ data.dsize = j % (sizeof(j) + 1); if (tdb_store(tdb, key, data, TDB_REPLACE) != 0) fail("Storing in tdb"); } summary = tdb_summary(tdb); diag("%s", summary); ok1(strstr(summary, "Size of file/data: ")); ok1(strstr(summary, "Number of records: 500\n")); ok1(strstr(summary, "Smallest/average/largest keys: 4/4/4\n")); ok1(strstr(summary, "Smallest/average/largest data: 0/2/4\n")); ok1(strstr(summary, "Smallest/average/largest padding: ")); ok1(strstr(summary, "Number of dead records: 0\n")); ok1(strstr(summary, "Number of free records: 1\n")); ok1(strstr(summary, "Smallest/average/largest free records: ")); ok1(strstr(summary, "Number of hash chains: 131\n")); ok1(strstr(summary, "Smallest/average/largest hash chains: ")); ok1(strstr(summary, "Number of uncoalesced records: 0\n")); ok1(strstr(summary, "Smallest/average/largest uncoalesced runs: 0/0/0\n")); ok1(strstr(summary, "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: ")); free(summary); tdb_close(tdb); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-transaction-expand.c0000660000000000000000000000605112406075657021302 0ustar rootroot00000000000000#include "../common/tdb_private.h" /* Speed up the tests, but do the actual sync tests. */ static unsigned int sync_counts = 0; static inline int fake_fsync(int fd) { sync_counts++; return 0; } #define fsync fake_fsync #ifdef MS_SYNC static inline int fake_msync(void *addr, size_t length, int flags) { sync_counts++; return 0; } #define msync fake_msync #endif #ifdef HAVE_FDATASYNC static inline int fake_fdatasync(int fd) { sync_counts++; return 0; } #define fdatasync fake_fdatasync #endif #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static void write_record(struct tdb_context *tdb, size_t extra_len, TDB_DATA *data) { TDB_DATA key; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data->dsize += extra_len; tdb_transaction_start(tdb); tdb_store(tdb, key, *data, TDB_REPLACE); tdb_transaction_commit(tdb); } int main(int argc, char *argv[]) { struct tdb_context *tdb; size_t i; TDB_DATA data; struct tdb_record rec; tdb_off_t off; /* Do *not* suppress sync for this test; we do it ourselves. */ unsetenv("TDB_NO_FSYNC"); plan_tests(5); tdb = tdb_open_ex("run-transaction-expand.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); data.dsize = 0; data.dptr = calloc(1000, getpagesize()); if (data.dptr == NULL) { diag("Unable to allocate memory for data.dptr"); tdb_close(tdb); exit(1); } /* Simulate a slowly growing record. */ for (i = 0; i < 1000; i++) write_record(tdb, getpagesize(), &data); tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); diag("TDB size = %zu, recovery = %llu-%llu", (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); /* We should only be about 5 times larger than largest record. */ ok1(tdb->map_size < 6 * i * getpagesize()); tdb_close(tdb); tdb = tdb_open_ex("run-transaction-expand.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); data.dsize = 0; /* Simulate a slowly growing record, repacking to keep * recovery area at end. */ for (i = 0; i < 1000; i++) { write_record(tdb, getpagesize(), &data); if (i % 10 == 0) tdb_repack(tdb); } tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); diag("TDB size = %zu, recovery = %llu-%llu", (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); /* We should only be about 4 times larger than largest record. */ ok1(tdb->map_size < 5 * i * getpagesize()); /* We should have synchronized multiple times. */ ok1(sync_counts); tdb_close(tdb); free(data.dptr); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-traverse-chain.c0000660000000000000000000000421313573675413020413 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static char keystr0[] = "x"; static TDB_DATA key0 = { .dptr = (uint8_t *)keystr0, .dsize = sizeof(keystr0) }; static char valuestr0[] = "y"; static TDB_DATA value0 = { .dptr = (uint8_t *)valuestr0, .dsize = sizeof(valuestr0) }; static char keystr1[] = "aaa"; static TDB_DATA key1 = { .dptr = (uint8_t *)keystr1, .dsize = sizeof(keystr1) }; static char valuestr1[] = "bbbbb"; static TDB_DATA value1 = { .dptr = (uint8_t *)valuestr1, .dsize = sizeof(valuestr1) }; static TDB_DATA *keys[] = { &key0, &key1 }; static TDB_DATA *values[] = { &value0, &value1 }; static bool tdb_data_same(TDB_DATA d1, TDB_DATA d2) { if (d1.dsize != d2.dsize) { return false; } return (memcmp(d1.dptr, d2.dptr, d1.dsize) == 0); } struct traverse_chain_state { size_t idx; bool ok; }; static int traverse_chain_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { struct traverse_chain_state *state = private_data; state->ok &= tdb_data_same(key, *keys[state->idx]); state->ok &= tdb_data_same(data, *values[state->idx]); state->idx += 1; return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; struct traverse_chain_state state = { .ok = true }; int ret; plan_tests(4); tdb = tdb_open_ex( "traverse_chain.tdb", 1, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600, &taplogctx, NULL); ok1(tdb); /* add in reverse order, tdb_store adds to the front of the list */ ret = tdb_store(tdb, key1, value1, TDB_INSERT); ok1(ret == 0); ret = tdb_store(tdb, key0, value0, TDB_INSERT); ok1(ret == 0); ret = tdb_traverse_key_chain(tdb, key0, traverse_chain_fn, &state); ok1(ret == 2); ok1(state.ok); unlink(tdb_name(tdb)); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c0000660000000000000000000000456213126252766022265 0ustar rootroot00000000000000#include "lock-tracking.h" #include "../common/tdb_private.h" #define fcntl fcntl_with_lockcheck #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #undef fcntl_with_lockcheck #include #include #include "external-agent.h" #include "logging.h" static struct agent *agent; static bool correct_key(TDB_DATA key) { return key.dsize == strlen("hi") && memcmp(key.dptr, "hi", key.dsize) == 0; } static bool correct_data(TDB_DATA data) { return data.dsize == strlen("world") && memcmp(data.dptr, "world", data.dsize) == 0; } static int traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(13); agent = prepare_external_agent(); tdb = tdb_open_ex("run-traverse-in-transaction.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); ok1(tdb_transaction_active(tdb) == 0); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_transaction_active(tdb) == 1); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse(tdb, traverse, NULL); /* That should *not* release the transaction lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse_read(tdb, traverse, NULL); /* That should *not* release the transaction lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); ok1(tdb_transaction_commit(tdb) == 0); ok1(tdb_transaction_active(tdb) == 0); /* Now we should be fine. */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c0000660000000000000000000000577212406075657020422 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); if (strstr(fmt, "hash")) (*count)++; } int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; TDB_DATA d; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(28); /* Create with default hash. */ log_count = 0; tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Fail to open with different hash. */ tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_jenkins_hash); ok1(!tdb); ok1(log_count == 1); /* Create with different hash. */ log_count = 0; tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); tdb_close(tdb); /* Endian should be no problem. */ log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; /* Fail to open with old default hash. */ tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* It should open with jenkins hash if we don't specify. */ log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDONLY, 0, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-zero-append.c0000660000000000000000000000201612406075657017721 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(4); tdb = tdb_open_ex(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); /* Tickle bug on appending zero length buffer to zero length buffer. */ key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = 0; ok1(tdb_append(tdb, key, data) == 0); ok1(tdb_append(tdb, key, data) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == 0); tdb_close(tdb); free(data.dptr); return exit_status(); } ldb-2.0.8/lib/tdb/test/run.c0000660000000000000000000000246412406075657015506 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(10); tdb = tdb_open_ex("run.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); ok1(tdb_error(tdb) == TDB_ERR_EXISTS); ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); key.dsize++; data = tdb_fetch(tdb, key); ok1(data.dptr == NULL); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/rwlock-be.tdb0000660000000000000000000000127012406075657017110 0ustar rootroot00000000000000TDB file m&ƒgÅ/ldb-2.0.8/lib/tdb/test/rwlock-le.tdb0000660000000000000000000000127012406075657017122 0ustar rootroot00000000000000TDB file m&ƒgÅ/ldb-2.0.8/lib/tdb/test/sample_tdb.tdb0000660000000000000000000002000013573675413017327 0ustar rootroot00000000000000TDB file m&ƒQ­ å”¶×D¹v¸ÀthfæþÙ|ì #nY„¨™&rpc_server972.2147483647/1085706313786795392972.100/1085706313786795392972.106/1085706313786795392972.95/1085706313786795392972.101/1085706313786795392972.113/1085706313786795392972.113/1085706313786795392€d #a¡]5fæþÙldap_server972.2147483650/1085706313786795392972.108/1085706313786795392|¨ ’nY„¨fæþÙrpc_server972.2147483647/1085706313786795392972.100/1085706313786795392972.106/1085706313786795392972.95/1085706313786795392972.101/1085706313786795392À4òoý™¬ify-daemon992/6389638235474936598L8ß%È™&winbind_server977/12826542715097898407P´à#h¬·cfæþÙdnssrv972.2147483658/1085706313786795392P< #{Ö­•™&dnsupdate972.2147483657/1085706313786795392¤8#E0]™&kccsrv972.2147483656/1085706313786795392ô< #ùcX™&dreplsrv972.2147483653/1085706313786795392H@ #Zž„8™&kdc_server972.2147483652/1085706313786795392 @ #>s™&cldap_server972.2147483651/1085706313786795392øh˜ #a¡]5fæþÙldap_server972.2147483650/1085706313786795392X@ #\yÀ™&wrepl_server972.2147483649/1085706313786795392°@ #^¬Â™&nbt_server972.2147483648/1085706313786795392X8@ #2óáÀfæþÙwins_server972.2147483648/1085706313786795392X¸€ #nY„¨fæþÙrpc_server972.2147483647/1085706313786795392X(B:0R™&samba0/1085706313786795392˜ldb-2.0.8/lib/tdb/test/tap-interface.h0000660000000000000000000000334612406075657017431 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Simplistic implementation of tap interface. Copyright (C) Rusty Russell 2012 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include #ifndef __location__ #define __TAP_STRING_LINE1__(s) #s #define __TAP_STRING_LINE2__(s) __TAP_STRING_LINE1__(s) #define __TAP_STRING_LINE3__ __TAP_STRING_LINE2__(__LINE__) #define __location__ __FILE__ ":" __TAP_STRING_LINE3__ #endif #define plan_tests(num) #define fail(...) do { \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ fflush(stderr); \ exit(1); \ } while(0) #define diag(...) do { \ fprintf(stdout, __VA_ARGS__); \ fprintf(stdout, "\n"); \ fflush(stdout); \ } while(0) #define pass(...) do { \ fprintf(stdout, "."); \ fflush(stdout); \ } while(0) #define ok(e, ...) do { \ if (e) { \ pass(); \ } else { \ fail(__VA_ARGS__); \ } \ } while(0) #define ok1(e) ok((e), "%s:%s", __location__, #e) #define skip(n, ...) diag(__VA_ARGS__) #define exit_status() 0 ldb-2.0.8/lib/tdb/test/tap-to-subunit.h0000660000000000000000000001226612406075657017603 0ustar rootroot00000000000000#ifndef TAP_TO_SUBUNIT_H #define TAP_TO_SUBUNIT_H /* * tap-style wrapper for subunit. * * Copyright (c) 2011 Rusty Russell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "replace.h" /** * plan_tests - announce the number of tests you plan to run * @tests: the number of tests * * This should be the first call in your test program: it allows tracing * of failures which mean that not all tests are run. * * If you don't know how many tests will actually be run, assume all of them * and use skip() if you don't actually run some tests. * * Example: * plan_tests(13); */ void plan_tests(unsigned int tests); /** * ok1 - Simple conditional test * @e: the expression which we expect to be true. * * This is the simplest kind of test: if the expression is true, the * test passes. The name of the test which is printed will simply be * file name, line number, and the expression itself. * * Example: * ok1(somefunc() == 1); */ # define ok1(e) ((e) ? \ _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) /** * ok - Conditional test with a name * @e: the expression which we expect to be true. * @...: the printf-style name of the test. * * If the expression is true, the test passes. The name of the test will be * the filename, line number, and the printf-style string. This can be clearer * than simply the expression itself. * * Example: * ok1(somefunc() == 1); * ok(somefunc() == 0, "Second somefunc() should fail"); */ # define ok(e, ...) ((e) ? \ _gen_result(1, __func__, __FILE__, __LINE__, \ __VA_ARGS__) : \ _gen_result(0, __func__, __FILE__, __LINE__, \ __VA_ARGS__)) /** * pass - Note that a test passed * @...: the printf-style name of the test. * * For complicated code paths, it can be easiest to simply call pass() in one * branch and fail() in another. * * Example: * int x = somefunc(); * if (x > 0) * pass("somefunc() returned a valid value"); * else * fail("somefunc() returned an invalid value"); */ # define pass(...) ok(1, __VA_ARGS__) /** * fail - Note that a test failed * @...: the printf-style name of the test. * * For complicated code paths, it can be easiest to simply call pass() in one * branch and fail() in another. */ # define fail(...) ok(0, __VA_ARGS__) unsigned int _gen_result(int, const char *, const char *, unsigned int, const char *, ...) PRINTF_ATTRIBUTE(5, 6); /** * diag - print a diagnostic message (use instead of printf/fprintf) * @fmt: the format of the printf-style message * * diag ensures that the output will not be considered to be a test * result by the TAP test harness. It will append '\n' for you. * * Example: * diag("Now running complex tests"); */ void diag(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); /** * skip - print a diagnostic message (use instead of printf/fprintf) * @n: number of tests you're skipping. * @fmt: the format of the reason you're skipping the tests. * * Sometimes tests cannot be run because the test system lacks some feature: * you should explicitly document that you're skipping tests using skip(). * * From the Test::More documentation: * If it's something the user might not be able to do, use SKIP. This * includes optional modules that aren't installed, running under an OS that * doesn't have some feature (like fork() or symlinks), or maybe you need an * Internet connection and one isn't available. * * Example: * #ifdef HAVE_SOME_FEATURE * ok1(somefunc()); * #else * skip(1, "Don't have SOME_FEATURE"); * #endif */ void skip(unsigned int n, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); /** * exit_status - the value that main should return. * * For maximum compatibility your test program should return a particular exit * code (ie. 0 if all tests were run, and every test which was expected to * succeed succeeded). * * Example: * exit(exit_status()); */ int exit_status(void); #endif /* CCAN_TAP_H */ ldb-2.0.8/lib/tdb/test/tdb.corrupt0000660000000000000000000057000012406075657016723 0ustar rootroot00000000000000TDB file m&ƒ„~‚Xd¸ø`}pŽÄI Hàâp€°P†À ðÍt} ´`Ã0g˜w€Ð ¸ƒ Ð'€ƒ`8(…{Ðü/ˆ’„Æ€|`Øà¾@ŒÁ\IÈ ’Ðp8Ü Å¸‹H(•DÈÀˆ€ŠH›0‚TË (€)äÊx¾€®à€ Ax_¬Ì;za@~ЀïüJ`’«Ði £¨,PL¬<Ø‘°^`„øöü%@·°~€ÍPܰŒ ñ$ɬótK\-è.Ä|¼‘4L&°j\„`Ñð‘(XÆP /4 Úp‡0n,G¼‚ð|€‘`ΰ…ÀÎÀº(iÈD0-¸ °Ë‡T,L?à¤ÌÎðƒà¹fæþÙBBBBBBBBBBBBBBBB,X<JìÄ™&IDMAP/GID2SID/10000045 1251822591/S-1-5-21-1834383793-1770918451-929701000-63064Bp¨LX=fJw¯™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63064 1251822591/10000045BpX=tO8™&IDMAP/GID2SID/10000044 1251824032/S-1-5-21-1834383793-1770918451-929701000-143659pt X> „lá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143659 1251824032/10000044pX=ž²«™&IDMAP/GID2SID/10000043 1243613530/S-1-5-21-1834383793-1770918451-929701000-112509pX>ß>î±™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112509 1243613530/10000043pX;È™&IDMAP/GID2SID/10000042 1251822591/S-1-5-21-1834383793-1770918451-929701000-1390BBpˆºX<9Îá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-1390 1251822591/10000042BBp5X<òx’™&IDMAP/GID2SID/10000041 1251258541/S-1-5-21-1834383793-1770918451-929701000-42600Bp`®X=^j1™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42600 1251258541/10000041Bp°&X<Ü™&IDMAP/GID2SID/10000040 1251822591/S-1-5-21-1834383793-1770918451-929701000-68419BpðvX=Š5T¹™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68419 1251822591/10000040BpX;í»úÚ™&IDMAP/GID2SID/10000039 1251822591/S-1-5-21-1834383793-1770918451-929701000-1406BBp€ÉX<A(„À™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-1406 1251822591/10000039BBpX=íå]N™&IDMAP/GID2SID/10000038 1251824032/S-1-5-21-1834383793-1770918451-929701000-154049p€¼X>ƒôxï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-154049 1251824032/10000038pÜX=íÁÁ™&IDMAP/GID2SID/10000037 1250795400/S-1-5-21-1834383793-1770918451-929701000-119283p¨ X>Ûö™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119283 1250795400/10000037pX<í9$5™&IDMAP/GID2SID/10000036 1251246539/S-1-5-21-1834383793-1770918451-929701000-42610Bp|$X= ¤J™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42610 1251246539/10000036BpX<íc‡¨™&IDMAP/GID2SID/10000035 1251822591/S-1-5-21-1834383793-1770918451-929701000-22077Bp¨X=’ÄÍG™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-22077 1251822591/10000035Bp\ X<íê™&IDMAP/GID2SID/10000034 1251823756/S-1-5-21-1834383793-1770918451-929701000-25222Bp°“X=¶˜Œ:™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-25222 1251823756/10000034BpX<í·M™&IDMAP/GID2SID/10000033 1251822591/S-1-5-21-1834383793-1770918451-929701000-65941BpèX=Ž6Í™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-65941 1251822591/10000033BpX=íá°™&IDMAP/GID2SID/10000032 1250723401/S-1-5-21-1834383793-1770918451-929701000-107777pð»X>·ÈÚà™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107777 1250723401/10000032pX<í v™&IDMAP/GID2SID/10000031 1251824032/S-1-5-21-1834383793-1770918451-929701000-79185Bpô X=>K&w™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79185 1251824032/10000031BpX<í5wé™&IDMAP/GID2SID/10000030 1251331835/S-1-5-21-1834383793-1770918451-929701000-22078Bp ”X=úô*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-22078 1251331835/10000030BpÐMX:=Õ•¾™&IDMAP/GID2SID/10000029 1251246539/S-1-5-21-1834383793-1770918451-929701000-513BBBp(ÒX;ÔÑ·j™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-513 1251246539/10000029BBBpømX<ÍySX™&IDMAP/UID2SID/10000050 1251258541/S-1-5-21-1834383793-1770918451-929701000-36003Bp OX=FÚY™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-36003 1251258541/10000050Bpü"X<=S¿™&IDMAP/GID2SID/10000026 1251246553/S-1-5-21-1834383793-1770918451-929701000-89152Bp©X=ºUØê™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-89152 1251246553/10000026Bp4=}"Œ™&IDMAP/GID2SID/10000025 1251246539/S-1-5-11BBBL%4u¼±†™&IDMAP/SID2GID/S-1-5-11 1251246539/10000025BBBLX:=§…ÿ™&IDMAP/GID2SID/10000024 1251246553/S-1-5-21-1834383793-1770918451-929701000-515BBBpìX;ÔÑw™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-515 1251246553/10000024BBBpX=CÕ ™&IDMAP/UID2SID/10000048 1250712333/S-1-5-21-1834383793-1770918451-929701000-119484pì:X>›hŽÌ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119484 1250712333/10000048pX=m8™&IDMAP/UID2SID/10000047 1250643921/S-1-5-21-1834383793-1770918451-929701000-119489p(X>›ØÅ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119489 1250643921/10000047pX=Áþú™&IDMAP/UID2SID/10000045 1250618989/S-1-5-21-1834383793-1770918451-929701000-119367pàÔX>ïÓÚ-™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119367 1250618989/10000045pX=?(U™&IDMAP/UID2SID/10000042 1250643920/S-1-5-21-1834383793-1770918451-929701000-119322pøTX>H™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119322 1250643920/10000042pX=m†Ó÷™&IDMAP/UID2SID/10000037 1250618989/S-1-5-21-1834383793-1770918451-929701000-119366pà±X>ï#ôÈ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119366 1251224062/10000037pX=mýQ™&IDMAP/UID2SID/10000034 1251224061/S-1-5-21-1834383793-1770918451-929701000-119469pHôX>›mÁþ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119469 1251224061/10000034pX=m‚&¬™&IDMAP/UID2SID/10000031 1250618998/S-1-5-21-1834383793-1770918451-929701000-119472p0ºX>Ó™™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119472 1250618998/10000031pX=½u h™&IDMAP/UID2SID/10000028 1245435540/S-1-5-21-1834383793-1770918451-929701000-143691p¼?X>s5ª™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143691 1245435540/10000028pX=½ó4™&IDMAP/UID2SID/10000025 1250643920/S-1-5-21-1834383793-1770918451-929701000-119332pÜàX>oÃã‹™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119332 1250643920/10000025pX=½q^™&IDMAP/UID2SID/10000022 1250714212/S-1-5-21-1834383793-1770918451-929701000-119305p0ÈX>ï2"™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119305 1250714212/10000022pX= eCØ™&IDMAP/UID2SID/10000019 1250884333/S-1-5-21-1834383793-1770918451-929701000-119473p8ÀX>ƒ€„™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119473 1250884333/10000019pX= ãl2™&IDMAP/UID2SID/10000016 1250815021/S-1-5-21-1834383793-1770918451-929701000-119397p :X>otP×™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119397 1250815021/10000016pX= a–Œ™&IDMAP/UID2SID/10000013 1250726048/S-1-5-21-1834383793-1770918451-929701000-119404pÉX>›¼T³™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119404 1250726048/10000013pX= ß¿æ™&IDMAP/UID2SID/10000010 1250717566/S-1-5-21-1834383793-1770918451-929701000-119329pŒ6X>ï] k™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119329 1250717566/10000010pX=]¨A/™&IDMAP/UID2SID/10000008 1250705448/S-1-5-21-1834383793-1770918451-929701000-119310pX>oøÇû™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119310 1250705448/10000008pX=]PÎü™&IDMAP/UID2SID/10000004 1250714212/S-1-5-21-1834383793-1770918451-929701000-119334pà‰X>o#±U™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119334 1250714212/10000004pX=]¤”ã™&IDMAP/UID2SID/10000002 1250886708/S-1-5-21-1834383793-1770918451-929701000-119303pT X>ïÒTG™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119303 1250886708/10000002p8Ý[’l™&IDMAP/GID2SID/10000007 1251246513/S-1-5-32-545BBBP8ݯXS™&IDMAP/GID2SID/10000005 1251246513/S-1-5-32-544BBBP(Ä8¥õcy™&IDMAP/SID2GID/S-1-5-32-544 1251246513/10000005BBBP8êƒV™&IDMAP/GID2SID/10000013 1243558577/S-1-5-32-546BBBP@“8Ã-²™&IDMAP/SID2GID/S-1-5-32-545 1251246513/10000007BBBP0h­°™&IDMAP/GID2SID/10000010 1251246513/S-1-5-2HЧ0!ë›™&IDMAP/SID2GID/S-1-5-2 1251246513/10000010HÐb8 ïÿ’™&NBT/AD.VIACOM.COM#1C 1251229040/166.77.86.17:3891PPL+´jaµ™&NBT/BUBBLEBUDDY.PARAMOUNT.AD.VIACOM.COM#20 1251229216/166.77.172.94:0d0ÝÌ…™&IDMAP/GID2SID/10000009 1251246513/S-1-1-0HÈ0 Sq|™&IDMAP/SID2GID/S-1-1-0 1251246513/10000009H0Ý1/ù™&IDMAP/GID2SID/10000008 1251819747/S-1-0-0H4 0 SÅB™&IDMAP/SID2GID/S-1-0-0 1251819747/10000008HHæ$Z›;ö™&IDMAP/GID2SID/0 1251227602/-<¸}l>ïÞ[*™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119385 1250812305/10000029ch.ad.viacom.com-B„”$ÚN,™&IDMAP/UID2SID/0 1251228589/-B<¸ (™÷ ofæþÙSAF/DOMA$$—Lpã™&IDMAP/UID2SID/99 1251227602/-<Ê<(S¢f™&SAF/DOMAIN/IPT 1251229423/unitynyad02.ipt.viacom.comBT D"0(;™&NBT/UNITYNYAD02.IPT.VIACOM.COM#20 1251229040/172.21.200.28:0B\@"‘i_A™&AD_SITENAME/DOMAIN/IPT.VIACOM.COM 4294967295/IPT-US-NYCBBXH!#"ï¤ï™&AD_SITENAME/DOMAIN/AD.VIACOM.COM 4294967295/US-California-Burbank`@#þr²™&AD_SITENAME/DOMAIN/AD 4294967295/US-California-BurbankBBBX@cXó™&AD_SITENAME/DOMAIN/IPT 4294967295/IPT-US-NYC6:389,166.77.XLÍ-xÄ¡fæþÙSAF/DOMAIN/MTVN 1208ˆX=ræL™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-66812 1251824050/100000837px.X=¦r' ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79085 1251148458/10000066p /<ÆHÕ1™&NBT/VAD01.TAGWORLD.LOCAL#20 1251234381/10.64.0.101:0BThD!¯¸Ù™&NBT/MUSSELBEACH.AD.VIACOM.COM#20 1251229040/166.77.86.17:0BBB\Є@ Þ¼R™&NBT/NETDEV.VIACOM.COM#1C 1251229222/166.77.173.156:389m.cX_T".±Àv`™&SAF/DOMAIN/MTVNASIA.AD.VIACOM.COM 1251229469/SQUILLIAM.mtvnasia.ad.viacom.comlP&#hK™&AD_SITENAME/DOMAIN/MTVN.AD.VIACOM.COM 4294967295/US-California-BurbankBBBh@#HZrj™&AD_SITENAME/DOMAIN/MTVN 4294967295/US-California-BurbankBXè.H#Wo™&NBT/BILLYBOB.MTVN.AD.VIACOM.COM#20 1251217243/172.23.128.101:0BBB`tD!½týŸ™&NBT/MRSTAR.MTVN.AD.VIACOM.COM#20 1251217243/166.77.86.16:0BBB\(ÙD!yOé™&NBT/ALPUSS.MTVN.AD.VIACOM.COM#20 1251217243/166.77.80.155:0BB\XôD ‘ePó™&NBT/HOSTING.AD.VIACOM.COM#1C 1251229244/166.77.173.152:3893.1\²X3RÖl™™&NBT/PLAYASUR.AD.VIACOM.COM#1C 1251229229/166.77.172.111:389,166.77.172.128:389BBp|X>Ã_g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119272 1243615575/10000056pX=]Î÷V™&IDMAP/UID2SID/10000001 1250618991/S-1-5-21-1834383793-1770918451-929701000-119378p¨êX>o¹èu™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119378 1250618991/10000001p¤ X=½Å$™&IDMAP/UID2SID/10000020 1250712333/S-1-5-21-1834383793-1770918451-929701000-119389pÈÆX>ïžö½™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119389 1250712333/10000020p\;X=m\p„™&IDMAP/UID2SID/10000038 1250705447/S-1-5-21-1834383793-1770918451-929701000-119479pÐÃX>£èá™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119479 1250705447/10000038pX=½›Á™&IDMAP/UID2SID/10000021 1250643921/S-1-5-21-1834383793-1770918451-929701000-119357p%X>ož³J™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119357 1250643921/10000021pX=m2 ™&IDMAP/UID2SID/10000039 1250891274/S-1-5-21-1834383793-1770918451-929701000-119324pÅX>ïí‰r™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119324 1250891274/10000039pàRX= 73™&IDMAP/UID2SID/10000014 1250886708/S-1-5-21-1834383793-1770918451-929701000-119313p@¡X>o|*™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119313 1250886708/10000014pX=r-™&IDMAP/UID2SID/10000049 1250643921/S-1-5-21-1834383793-1770918451-929701000-119381pØX>ïÁ–™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119381 1250643921/10000049päX=m¬‰™&IDMAP/UID2SID/10000030 1250717565/S-1-5-21-1834383793-1770918451-929701000-119327p¸HX>ïý=¡™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119327 1250717565/10000030pX=i‹È™&IDMAP/UID2SID/10000041 1250624364/S-1-5-21-1834383793-1770918451-929701000-119307p¨SX>ï’ïÚ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119307 1250624364/10000041p@WX=]~Þ»™&IDMAP/UID2SID/10000009 1250898946/S-1-5-21-1834383793-1770918451-929701000-119314pp¸X>o¸b™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119314 1250898946/10000009pX=m.`Å™&IDMAP/UID2SID/10000033 1250643921/S-1-5-21-1834383793-1770918451-929701000-119490pˆÝX>Þ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119490 1250643921/10000033pX=ëan™&IDMAP/UID2SID/10000044 1250705447/S-1-5-21-1834383793-1770918451-929701000-119319p|ñX>o(䇙&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119319 1250705447/10000044pX<]ã©™&IDMAP/GID2SID/10000084 1251822594/S-1-5-21-1834383793-1770918451-929701000-58035BpŒ=X=âzöÒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-58035 1251822594/10000084BpX=]9F™&IDMAP/GID2SID/10000083 1251823992/S-1-5-21-1834383793-1770918451-929701000-113650p,@X> Tj™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113650 1251823992/10000083pX=]c©™&IDMAP/GID2SID/10000082 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25493p ­X>b2?ã™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25493 1251822594/10000082pX=] ™&IDMAP/GID2SID/10000081 1251823992/S-1-5-21-2140803266-1626024873-1299147156-29643pø&X>:š-·™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-29643 1251823992/10000081p€\X=]·ow™&IDMAP/GID2SID/10000080 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25491p ¿X>bÒq™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25491 1251822594/10000080pX<­VŽL™&IDMAP/GID2SID/10000079 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1158BpŒDX=O­á<™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1158 1251822594/10000079BpX=­€ñ¿™&IDMAP/GID2SID/10000078 1251822594/S-1-5-21-2140803266-1626024873-1299147156-24252pÌX> 9)™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24252 1251822594/10000078pX=­ªT3™&IDMAP/GID2SID/10000077 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31647pè<X=Šœß1™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56613 1251332444/10000092pX=­Ô·¦™&IDMAP/GID2SID/10000076 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25443pˆ.X>:Z3.™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31647 1251822594/10000077pX=­þ™&IDMAP/GID2SID/10000075 1251822594/S-1-5-21-2140803266-1626024873-1299147156-24253pkX> é{™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24253 1251822594/10000075pX=­(~™&IDMAP/GID2SID/10000074 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31834p•X>ˆŠ*™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31834 1251822594/10000074pX=­Rá™&IDMAP/GID2SID/10000073 1251822594/S-1-5-21-2140803266-1626024873-1299147156-21662p˜X>:U•­™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-21662 1251822594/10000073pX<­|Dt™&IDMAP/GID2SID/10000072 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7612Bp˜~X=Ÿ…ó¦™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7612 1251822594/10000072BpüX=­¦§ç™&IDMAP/GID2SID/10000071 1251823992/S-1-5-21-2140803266-1626024873-1299147156-29588ph­X>ަ25™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-29588 1251823992/10000071p$X=­Ð [™&IDMAP/GID2SID/10000070 1251822593/S-1-5-21-2140803266-1626024873-1299147156-18854p$ÂX>ó¢ñ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-18854 1251822593/10000070p¼X=ýo)0™&IDMAP/GID2SID/10000069 1248309549/S-1-5-21-2140803266-1626024873-1299147156-33933pXÛX>¾}g™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-33933 1248309549/10000069pâP. -™&SAF/DOMAIN/HOSTING 1251229484/misstuftsy.hosting.ad.viacom.com.77.172.128h †T3áS«™&NBT/MTVNE.AD.VIACOM.COM#1C 1251229229/166.77.172.124:389,166.77.172.123:389BBlðUT-#°ømâ™&AD_SITENAME/DOMAIN/VIACOM_CORP.AD.VIACOM.COM 4294967295/US-California-Burbankl@PH#jËÂ&™&AD_SITENAME/DOMAIN/VIACOM_CORP 4294967295/US-California-BurbankBB`°W`1)¨™ ™&SAF/DOMAIN/PARAMOUNT 1251229469/bubblebuddy.paramount.ad.viacom.com.COM#20 1247397223/1x0‰T!.ÒrX?™&SAF/DOMAIN/HOSTING.AD.VIACOM.COM 1251229484/misstuftsy.hosting.ad.viacom.comBlHÃX<ý™Œ£™&IDMAP/GID2SID/10000068 1251822591/S-1-5-21-1834383793-1770918451-929701000-75573Bp0[X=’¦’¥™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-75573 1251822591/10000068BpX<ýÃï™&IDMAP/GID2SID/10000067 1251822591/S-1-5-21-1834383793-1770918451-929701000-85165BpX=æ/»a™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-85165 1251822591/10000067BpX=ýíRŠ™&IDMAP/GID2SID/10000066 1251246539/S-1-5-21-1834383793-1770918451-929701000-119942p0—X>+A6™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119942 1251246539/10000066p¼X=ý¶ý™&IDMAP/GID2SID/10000065 1251822591/S-1-5-21-1834383793-1770918451-929701000-100732p X>·‚¾™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-100732 1251822591/10000065pX<ýAq™&IDMAP/GID2SID/10000064 1251823775/S-1-5-21-1834383793-1770918451-929701000-43457BpØ|X=:m"™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43457 1251823775/10000064BpX<ýk|ä™&IDMAP/GID2SID/10000063 1251822591/S-1-5-21-1834383793-1770918451-929701000-64119Bp ÁX=Š5ˆ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64119 1251822591/10000063BpœX<ý•ßW™&IDMAP/GID2SID/10000062 1251822591/S-1-5-21-1834383793-1770918451-929701000-64117Bp(&X=ŠÊ9Q™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64117 1251822591/10000062BpX<ý¿BË™&IDMAP/GID2SID/10000061 1251822591/S-1-5-21-1834383793-1770918451-929701000-43582Bp_X=¾¢T•™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43582 1251822591/10000061BpX=ýé¥>™&IDMAP/GID2SID/10000060 1251823334/S-1-5-21-1834383793-1770918451-929701000-136294pè'X>[Ør™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136294 1251823334/10000060pX=M‰Ä™&IDMAP/GID2SID/10000059 1251822591/S-1-5-21-1834383793-1770918451-929701000-103603pè©X>‹X”Ú™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-103603 1251822591/10000059pX=M³'‡™&IDMAP/GID2SID/10000058 1251822591/S-1-5-21-1834383793-1770918451-929701000-133857ph×X>c—f×™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-133857 1251822591/10000058pœX=MÝŠú™&IDMAP/GID2SID/10000057 1243613530/S-1-5-21-1834383793-1770918451-929701000-112480pX>3ò7™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112480 1243613530/10000057pì*X=Mîm™&IDMAP/GID2SID/10000056 1251824032/S-1-5-21-1834383793-1770918451-929701000-141499p0MX>³æÅ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-141499 1251824032/10000056pX=M1Qá™&IDMAP/GID2SID/10000055 1251824032/S-1-5-21-1834383793-1770918451-929701000-140543p(^X>ßô£1™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140543 1251824032/10000055pß~S™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112505 1243613530/10000053pX=M¯z;™&IDMAP/GID2SID/10000052 1251822591/S-1-5-21-1834383793-1770918451-929701000-129742pXœX>7¸yv™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129742 1251822591/10000052pX<MÙÝ®™&IDMAP/GID2SID/10000051 1251822591/S-1-5-21-1834383793-1770918451-929701000-68189Bp·X=>Éä‚™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68189 1251822591/10000051BpX=MA"™&IDMAP/GID2SID/10000050 1251823334/S-1-5-21-1834383793-1770918451-929701000-136393p¬CX> ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136393 1251823334/10000050p\X<¢_÷™&IDMAP/GID2SID/10000049 1251822591/S-1-5-21-1834383793-1770918451-929701000-63066Bp£X=fµÅu™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63066 1251822591/10000049BpX<ÌÂj™&IDMAP/GID2SID/10000048 1251822591/S-1-5-21-1834383793-1770918451-929701000-63067Bp X=æêìX™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63067 1251822591/10000048BpX=ö%Þ™&IDMAP/GID2SID/10000047 1251824032/S-1-5-21-1834383793-1770918451-929701000-101189päÃX>/ø’™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-101189 1251824032/10000047pX= ‰Q™&IDMAP/GID2SID/10000046 1251823334/S-1-5-21-1834383793-1770918451-929701000-120736p8X>·Bî™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-120736 1251823334/10000046pÌ(fæþÙBBBBBBBBBBBBBBBBBBBB0ÄÄX=Ò1 ª™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-56596 1251823756/10000415BpX==O’™&IDMAP/GID2SID/10000120 1251822591/S-1-5-21-1834383793-1770918451-929701000-139639p´%X> óœ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-139639 1251822591/10000120p|X=î°×™&IDMAP/GID2SID/10000119 1251822591/S-1-5-21-1834383793-1770918451-929701000-126385p”X>‡·E­™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126385 1251822591/10000119pX=K™&IDMAP/GID2SID/10000118 1251822591/S-1-5-21-1834383793-1770918451-929701000-116156pÀ X>¯S ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116156 1251822591/10000118pp‰X=Bw¾™&IDMAP/GID2SID/10000117 1251822591/S-1-5-21-1834383793-1770918451-929701000-117588pÈYX>ß:!i™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-117588 1251822591/10000117p„X=lÚ1™&IDMAP/GID2SID/10000116 1251822591/S-1-5-21-1834383793-1770918451-929701000-126396pžX>Sõ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126396 1251822591/10000116pX=–=¥™&IDMAP/GID2SID/10000115 1251822591/S-1-5-21-1834383793-1770918451-929701000-159265p —X>Û?3™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-159265 1251822591/10000115pX<À ™&IDMAP/GID2SID/10000114 1251822591/S-1-5-21-1834383793-1770918451-929701000-90602BphšX=^ê:™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90602 1251822591/10000114BpX=ꌙ&IDMAP/GID2SID/10000113 1251822591/S-1-5-21-1834383793-1770918451-929701000-126429phgX>3põ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126429 1251822591/10000113pX=gÿ™&IDMAP/GID2SID/10000112 1251822591/S-1-5-21-1834383793-1770918451-929701000-122069pèÓX>ƒ_Æ/™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122069 1251822591/10000112pX=>Êr™&IDMAP/GID2SID/10000111 1251822591/S-1-5-21-1834383793-1770918451-929701000-122067px›X>ƒÿøe™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122067 1251822591/10000111pX<h-æ™&IDMAP/GID2SID/10000110 1251822591/S-1-5-21-1834383793-1770918451-929701000-43400Bp¨ÎX=^jÜÈ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43400 1251822591/10000110BpsX<ÝL»™&IDMAP/GID2SID/10000109 1251822591/S-1-5-21-1834383793-1770918451-929701000-64115Bp`ÊX=Š_늙&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64115 1251822591/10000109BpX=Ý1¯.™&IDMAP/GID2SID/10000108 1251822591/S-1-5-21-1834383793-1770918451-929701000-116427p˜ÒX>3ÖÜ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116427 1251822591/10000108pÜ0X<Ý[¢™&IDMAP/GID2SID/10000107 1251822591/S-1-5-21-1834383793-1770918451-929701000-64114BpÈX= *ħ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64114 1251822591/10000107BpX<Ý…u™&IDMAP/GID2SID/10000106 1251822591/S-1-5-21-1834383793-1770918451-929701000-93011Bp0X=Š‘Ýy™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-93011 1251822591/10000106BpX<ݯ؈™&IDMAP/GID2SID/10000105 1251822591/S-1-5-21-1834383793-1770918451-929701000-64116BppªX= •n™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64116 1251822591/10000105BpX=ÝÙ;ü™&IDMAP/GID2SID/10000104 1251822591/S-1-5-21-1834383793-1770918451-929701000-114928p ÈX>àzÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-114928 1251822591/10000104p”*X<ÝŸo™&IDMAP/GID2SID/10000103 1251822591/S-1-5-21-1834383793-1770918451-929701000-31602BpðÂX=^}¡Z™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-31602 1251822591/10000103BpX=Ý-ã™&IDMAP/GID2SID/10000102 1251822591/S-1-5-21-1834383793-1770918451-929701000-157066pˆ8X>ƒO3ï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-157066 1251822591/10000102pX<Í):½™&IDMAP/UID2SID/10000058 1251822591/S-1-5-21-1834383793-1770918451-929701000-48064Bph+X=ÎÁ6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-48064 1251822591/10000058Bp=X=m°6k™&IDMAP/UID2SID/10000036 1250712333/S-1-5-21-1834383793-1770918451-929701000-119393p,X>o´µC™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119393 1250712333/10000036pX=]z1p™&IDMAP/UID2SID/10000003 1250705447/S-1-5-21-1834383793-1770918451-929701000-119309p ÌX>ïò¼¤™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119309 1250705447/10000003pÜEX=½ÉÑN™&IDMAP/UID2SID/10000026 1250705448/S-1-5-21-1834383793-1770918451-929701000-119488pèýX>›()`™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119488 1250705448/10000026p4*X=—›‡™&IDMAP/UID2SID/10000046 1250878940/S-1-5-21-1834383793-1770918451-929701000-129585pø{X>GRù†™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129585 1250878940/10000046pX=ÝÈÉ™&IDMAP/GID2SID/10000100 1251822591/S-1-5-21-1834383793-1770918451-929701000-112481pTX>31Ùœ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112481 1251822591/10000100pRX= Ð¥™&IDMAP/UID2SID/10000015 1250712334/S-1-5-21-1834383793-1770918451-929701000-119386p@@X>ïŽB™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119386 1250712334/10000015p`OX= ¦K™&IDMAP/UID2SID/10000018 1250718766/S-1-5-21-1834383793-1770918451-929701000-119388pÐX>ïîY™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119388 1250718766/10000018p@^X=mXÃ8™&IDMAP/UID2SID/10000032 1245283320/S-1-5-21-1834383793-1770918451-929701000-119485p`iX>›u1™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119485 1245283320/10000032pÀSX=mÚ™Þ™&IDMAP/UID2SID/10000035 1250643921/S-1-5-21-1834383793-1770918451-929701000-119304pX>ï‚;¬™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119304 1250643921/10000035pÌBX<؂ϙ&NBT/TAGWORLD.LOCAL#1C 1251233900/10.64.99.4:389,10.64.0.101:389,10.64.0.102:389BBp<<8"¹],™&AD_SITENAME/DOMAIN/DMZ.VIACOM.COM 4294967295/DMZBP$,SWVÞ™&AD_SITENAME/DOMAIN/DMZ 4294967295/DMZD@à4£®™&TDOMCACHE/TIMESTAMP 1250653195/1250652595.netLÚX=¢Ÿ91™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95251 1250615979/10000348p€hH%åµT™&NBT/NETQAROOTDC1.NETQA.VIACOM.COM#20 1249211682/166.77.173.159:0B`@$´·†™&AD_SITENAME/DOMAIN/NETQA.VIACOM.COM 4294967295/NETQA-NYCBX4öþ™&AD_SITENAME/DOMAIN/NETQA 4294967295/NETQA-NYCL¤<'.*¯þ™&SAF/DOMAIN/AD 1251229419/musselbeach.ad.viacom.com89Tx–Dévu ™&NBT/BEAVIS.DMZ.VIACOM.COM#20 1245379451/166.77.8.196:0m.comB\ªL'Ī1Ê™&NBT/NETDEVROOTDC1.NETDEV.VIACOM.COM#20 1251229217/166.77.173.156:0BBBd°ŽD%áwœ3™&AD_SITENAME/DOMAIN/NETDEV.VIACOM.COM 4294967295/NETDEV-NYCBBB\Ð84g‚™&AD_SITENAME/DOMAIN/NETDEV 4294967295/NETDEV-NYCBBPP@ÆHÕ1fæþÙNBT/VAD01.TAGWORLD.LOCAL#20 1251228864/10.64.0.101:09BBBXð T)#‡ß‘™&AD_SITENAME/DOMAIN/HOSTING.AD.VIACOM.COM 4294967295/US-California-BurbankomBl,)L)f¬*™&NBT/MRSSTAR.VIACOM_CORP.AD.VIACOM.COM#20 1251229216/166.77.86.15:0dÀH.dO´Ž™&SAF/DOMAIN/MTVNASIA 1251229469/SQUILLIAM.mtvnasia.ad.viacom.comBB`›<ÆH@€™&NBT/VAD02.TAGWORLD.LOCAL#20 1250525385/10.64.0.102:0BTX#í¼K÷™&AD_SITENAME/DOMAIN/PLAYASUR 4294967295/US-California-Burbankmount.ad.viacom.comBpL‘L'hØb™&NBT/PERCHPERKINS.MTVN.AD.VIACOM.COM#20 1251234357/166.77.123.16:04:0dÌëL*ãH7y™&NBT/HASSELHOFF.PARAMOUNT.AD.VIACOM.COM#20 1249211622/166.77.172.108:0dDP#U³¦™&AD_SITENAME/DOMAIN/HOSTING 4294967295/US-California-Burbankd.viacom.comBhxjD,äï²#™&SAF/DOMAIN/PLAYASUR 1251229469/pancton.playasur.ad.viacom.com\ yH&û¯ÈÍ™&NBT/NEW-BRDC02.MTVNE.AD.VIACOM.COM#20 1244242447/166.77.172.124:0`±T&;Œ™&NBT/PANCTON.PLAYASUR.AD.VIACOM.COM#20 1251229216/166.77.172.128:0om.com.comlòH" —ÐÆ™&NBT/LOU.MTVNASIA.AD.VIACOM.COM#20 1249211618/166.77.172.115:0mBB` L(™÷ o™&SAF/DOMAIN/IPT.VIACOM.COM 1251229423/unitynyad02.ipt.viacom.com0:0BBdDX*#÷¿(™&AD_SITENAME/DOMAIN/PLAYASUR.AD.VIACOM.COM 4294967295/US-California-Burbankom.comp €L1åpT™&NBT/IPT.VIACOM.COM#1C 1251229043/172.21.200.28:389,172.21.200.27:389BdàBP,LÙÏØ™&NBT/KANGREBURGUER.PLAYASUR.AD.VIACOM.COM#20 1249211617/166.77.172.111:0BBhXr@‰à%Y™&NBT/BUTTHEAD.DMZ.VIACOM.COM#20 1251234328/166.77.8.197:0BXœJX= ¹ ¿™&IDMAP/UID2SID/10000017 1250712327/S-1-5-21-1834383793-1770918451-929701000-119365p X>ïs d™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119365 1250712327/10000017p¼8X=“î;™&IDMAP/UID2SID/10000040 1250878940/S-1-5-21-1834383793-1770918451-929701000-119391pð…X>oTèy™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119391 1250878940/10000040pœGX=½˜5™&IDMAP/UID2SID/10000024 1250705447/S-1-5-21-1834383793-1770918451-929701000-119377pˆùX>o ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119377 1250705447/10000024pX=]øZÊ™&IDMAP/UID2SID/10000000 1250714213/S-1-5-21-1834383793-1770918451-929701000-119487pðåX>›xBû™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119487 1250714213/10000000pX=½K¨ô™&IDMAP/UID2SID/10000029 1250812305/S-1-5-21-1834383793-1770918451-929701000-119385pX= µ\s™&IDMAP/UID2SID/10000011 1250643921/S-1-5-21-1834383793-1770918451-929701000-119308pÄX>ïBÖ?™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119308 1250643921/10000011pàYX=]ü™&IDMAP/UID2SID/10000006 1250712334/S-1-5-21-1834383793-1770918451-929701000-129609pè5X>óŸs™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129609 1250712334/10000006pÀLX=Åá™&IDMAP/UID2SID/10000043 1250809544/S-1-5-21-1834383793-1770918451-929701000-119470p0žX>sÌU™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119470 1250809544/10000043pÀZX=]&k‰™&IDMAP/UID2SID/10000005 1250900348/S-1-5-21-1834383793-1770918451-929701000-119371pH3X>o陳™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119371 1250900348/10000005pÄ X= ‹ùÿ™&IDMAP/UID2SID/10000012 1250715320/S-1-5-21-1834383793-1770918451-929701000-119480pmX>›¨ó8™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119480 1250715320/10000012pð(X=½Gû¨™&IDMAP/UID2SID/10000023 1250712327/S-1-5-21-1834383793-1770918451-929701000-119475pdX>ãMN™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119475 1250712327/10000023pYX=]Ò¤¢™&IDMAP/UID2SID/10000007 1250712327/S-1-5-21-1834383793-1770918451-929701000-119368p(X>ïƒÁ’™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119368 1250712327/10000007pX=Í}¤™&IDMAP/UID2SID/10000056 1243615575/S-1-5-21-1834383793-1770918451-929701000-119272pȸt",1auõ™&SAF/DOMAIN/PLAYASUR.AD.VIACOM.COM 1251229469/pancton.playasur.ad.viacom.com 1251222444/166.77.173.152:3892.1Œ\4P'#;6\A™&AD_SITENAME/DOMAIN/MTVNE.AD.VIACOM.COM 4294967295/US-California-Burbank89h˜œ@#mæPž™&AD_SITENAME/DOMAIN/MTVNE 4294967295/US-California-BurbankXÐ}X/ƒ€™&SAF/DOMAIN/VIACOM_CORP 1251229458/mrsstar.viacom_corp.ad.viacom.com123:3898989p\L/ãÐÏñ™&NBT/DMZ.VIACOM.COM#1C 1251234328/166.77.8.196:389,166.77.8.197:389hd‘P-›Ph ™&SAF/DOMAIN/NETDEV.VIACOM.COM 1251229765/NETDEVROOTDC1.netdev.viacom.commhHÐX-í2àŒ™&SAF/DOMAIN/MTVN.AD.VIACOM.COM 1251234708/perchperkins.mtvn.ad.viacom.com01:389BBpüX= öGÆ™&IDMAP/GID2SID/10000094 1251309681/S-1-5-21-1834383793-1770918451-929701000-128556pˆ™X>_:©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128556 1251309681/10000094pÀtX< J­™&IDMAP/GID2SID/10000092 1251332444/S-1-5-21-1834383793-1770918451-929701000-56613Bp¨0X>â&{s™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25443 1251822594/10000076pxX=ýA™¦™&IDMAP/GID2SID/10000164 1251824032/S-1-5-21-1834383793-1770918451-929701000-129541pðaX>ß”`™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129541 1251824032/10000164pàsX<ýkü™&IDMAP/GID2SID/10000163 1250878940/S-1-5-21-1834383793-1770918451-929701000-79173BpX=’¦¾©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79173 1250878940/10000163Bp|:X< žÔ“™&IDMAP/GID2SID/10000090 1250872206/S-1-5-21-1834383793-1770918451-929701000-48068Bp X=fpD_™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-48068 1250872206/10000090Bp¼FX<ý•_™&IDMAP/GID2SID/10000162 1250868523/S-1-5-21-1834383793-1770918451-929701000-52245BpàªX=Ž´Mž™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-52245 1250868523/10000162BpX=]=óh™&IDMAP/GID2SID/10000089 1251309681/S-1-5-21-1834383793-1770918451-929701000-107847p`MX>ãa~>™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107847 1251309681/10000089pX=]‘¹O™&IDMAP/GID2SID/10000087 1251309681/S-1-5-21-1834383793-1770918451-929701000-129709pHØX>7²+¬™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129709 1251309681/10000087pX=]»Ù&IDMAP/GID2SID/10000086 1251309681/S-1-5-21-1834383793-1770918451-929701000-119269p`X>ÛÒ-™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119269 1251309681/10000086p@‡X<ý¿Â™&IDMAP/GID2SID/10000161 1250878940/S-1-5-21-1834383793-1770918451-929701000-48092BpÈKX=jܤ!™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-48092 1250878940/10000161BpX<ÍÿÖI™&IDMAP/UID2SID/10000059 1250878940/S-1-5-21-1834383793-1770918451-929701000-95300BpHûX=ÆIô÷™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95300 1250878940/10000059BpX=ÍS0™&IDMAP/UID2SID/10000057 1250784019/S-1-5-21-1834383793-1770918451-929701000-148285p°X>C¥#A™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148285 1250784019/10000057pX=½ŸnÛ™&IDMAP/UID2SID/10000027 1250705448/S-1-5-21-1834383793-1770918451-929701000-119380pöX>ïnÚ1™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119380 1250705448/10000027pX<M‰DI™&IDMAP/GID2SID/10000159 1250616246/S-1-5-21-1834383793-1770918451-929701000-66299BpÀ'X=ꈺ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-66299 1250616246/10000159Bp0JT8M³§¼™&IDMAP/GID2SID/10000158 1250616246/S-1-5-21-59184239-814559844-636688714-6119BlhcT9'v³Î™&IDMAP/SID2GID/S-1-5-21-59184239-814559844-636688714-6119 1250616246/10000158Bl MX<MÝ 0™&IDMAP/GID2SID/10000157 1250616246/S-1-5-21-1834383793-1770918451-929701000-66402Bpø—X=^…Rß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-66402 1250616246/10000157Bp€NX=Mn£™&IDMAP/GID2SID/10000156 1251822594/S-1-5-21-1834383793-1770918451-929701000-113647pPmX>‹î6I™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113647 1251822594/10000156p`wX<M1Ñ™&IDMAP/GID2SID/10000155 1251822594/S-1-5-21-1834383793-1770918451-929701000-90580BpX=¾ïà™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90580 1251822594/10000155Bp€…X=M[4Š™&IDMAP/GID2SID/10000154 1251822594/S-1-5-21-2140803266-1626024873-1299147156-15724pvX>æôØ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-15724 1251822594/10000154pX=M…—ý™&IDMAP/GID2SID/10000153 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20642pð\X>:êæ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20642 1251822594/10000153p€vX=M¯úp™&IDMAP/GID2SID/10000152 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20643pÔ X>:šÍ~™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20643 1251822594/10000152p X<MÙ]ä™&IDMAP/GID2SID/10000151 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1212BpôX=Ÿ…ñš™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1212 1251822594/10000151Bp€aX<MÁW™&IDMAP/GID2SID/10000150 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1677Bpˆ#X='ëÌj™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1677 1251822594/10000150Bp TX=¢ß,™&IDMAP/GID2SID/10000149 1251822594/S-1-5-21-2140803266-1626024873-1299147156-23995pÌX>¾²Ê5™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-23995 1251822594/10000149p€UX=ÌB ™&IDMAP/GID2SID/10000148 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25492p€ÂX>b‚X~™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25492 1251822594/10000148p`VX=ö¥™&IDMAP/GID2SID/10000147 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31602pÖX>:©™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31602 1251822594/10000147p`†X< ‡™&IDMAP/GID2SID/10000146 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7613BpX=»Š™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7613 1251822594/10000146BppYX=Jlú™&IDMAP/GID2SID/10000145 1251822594/S-1-5-21-2140803266-1626024873-1299147156-34646p¸’X>:ªl1™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34646 1251822594/10000145pØ}X<tÏm™&IDMAP/GID2SID/10000144 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1209Bp°X=sÂêÉ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1209 1251822594/10000144BpX=ž2á™&IDMAP/GID2SID/10000143 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31603p`¯X>:Äû ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31603 1251822594/10000143pŒX<È•T™&IDMAP/GID2SID/10000142 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7654Bph“X=Oצ‰™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7654 1251822594/10000142Bp"X<òøÇ™&IDMAP/GID2SID/10000141 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7615Bp@¾X=&iP™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7615 1251822594/10000141Bp@jX=\;™&IDMAP/GID2SID/10000140 1251822594/S-1-5-21-2140803266-1626024873-1299147156-23175p`*X>^z²6™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-23175 1251822594/10000140p`]X=í»z™&IDMAP/GID2SID/10000139 1251822594/S-1-5-21-2106152344-1726899929-2013803672-40569pÐX>ª›=¼™&IDMAP/SID2GID/S-1-5-21-2106152344-1726899929-2013803672-40569 1251822594/10000139p@xX<íå݃™&IDMAP/GID2SID/10000138 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7653BpìAX=Ï¡¦™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7653 1251822594/10000138Bp<X=íA÷™&IDMAP/GID2SID/10000137 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20644p X>:J´ã™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20644 1251822594/10000137pü6X=í9¤j™&IDMAP/GID2SID/10000136 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31606pH]X>:Ô¯<™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31606 1251822594/10000136pX=ícÞ™&IDMAP/GID2SID/10000135 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20641pˆ?X>::µ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20641 1251822594/10000135p¤X=íjQ™&IDMAP/GID2SID/10000134 1251822594/S-1-5-21-2106152344-1726899929-2013803672-12000p‚X>N 7i™&IDMAP/SID2GID/S-1-5-21-2106152344-1726899929-2013803672-12000 1251822594/10000134pÈ-X<í·ÍÄ™&IDMAP/GID2SID/10000133 1251822591/S-1-5-21-4186143834-2626045635-1021053583-1683Bp(X=ÓNIå™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1683 1251822591/10000133BpX=íá08™&IDMAP/GID2SID/10000132 1251822591/S-1-5-21-1834383793-1770918451-929701000-129472pðoX>³«£ ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129472 1251822591/10000132pX=í ”«™&IDMAP/GID2SID/10000131 1251822591/S-1-5-21-1834383793-1770918451-929701000-116153p`½X>¯CeÝ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116153 1251822591/10000131p@'X=í5÷™&IDMAP/GID2SID/10000130 1251822591/S-1-5-21-1834383793-1770918451-929701000-111062pJX>ƒ¬Q™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-111062 1251822591/10000130p4~X<=Õô™&IDMAP/GID2SID/10000129 1251822591/S-1-5-21-1834383793-1770918451-929701000-75607Bp X=ÞèÞÍ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-75607 1251822591/10000129Bpä X<=ÿxg™&IDMAP/GID2SID/10000128 1251822591/S-1-5-21-1834383793-1770918451-929701000-64118Bph¦X= a4™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64118 1251822591/10000128Bp|3X==)ÜÚ™&IDMAP/GID2SID/10000127 1251822591/S-1-5-21-1834383793-1770918451-929701000-122070pXX>eц™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122070 1251822591/10000127p¼1X==S?N™&IDMAP/GID2SID/10000126 1251822591/S-1-5-21-1834383793-1770918451-929701000-122076pplX>…9ä™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122076 1251822591/10000126pX==}¢Á™&IDMAP/GID2SID/10000125 1251822591/S-1-5-21-1834383793-1770918451-929701000-126386pð¦X>‡g,™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126386 1251822591/10000125pd X<=§5™&IDMAP/GID2SID/10000124 1251822591/S-1-5-21-1834383793-1770918451-929701000-63065BpP¤X=æž’™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63065 1251822591/10000124BpX==Ñh¨™&IDMAP/GID2SID/10000123 1251822591/S-1-5-21-1834383793-1770918451-929701000-126395pqX>íl™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126395 1251822591/10000123pÀzX<=ûË™&IDMAP/GID2SID/10000122 1251822591/S-1-5-21-1834383793-1770918451-929701000-52079Bp¨EX=’7v¥™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-52079 1251822591/10000122BpX<=%/™&IDMAP/GID2SID/10000121 1251822591/S-1-5-21-1834383793-1770918451-929701000-36648Bp` fæþÙBBBBBBBBBBBBBBBBBBBBBBBBBBBB8Œ"X>Çqˆ9™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107559 1250873479/10000288ph|X=ÝÌð™&IDMAP/UID2SID/10000287 1250873530/S-1-5-21-1834383793-1770918451-929701000-107728pX>Ÿ”^9™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107728 1250873530/10000287pØúX ‰K™&NBT/NETQA.VIACOM.COM#1C 1249211677/166.77.173.159:3890.101:389,10.64.0.102:389BBpxXX=Ý[’×™&IDMAP/UID2SID/10000285 1250521814/S-1-5-21-1834383793-1770918451-929701000-148213p˜PX>ÃÎCA™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148213 1250521814/10000285pèÅX=Ý…õJ™&IDMAP/UID2SID/10000284 1250521814/S-1-5-21-1834383793-1770918451-929701000-148250pÈôX>Ô,Ÿ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148250 1250521814/10000284p¬úX<ÍÿÖ´™&IDMAP/UID2SID/10000259 1251218400/S-1-5-21-1834383793-1770918451-929701000-79240BpHX=v€¾™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79240 1251218400/10000259BpX= a–÷™&IDMAP/UID2SID/10000213 1250606578/S-1-5-21-1834383793-1770918451-929701000-129760p@+X>Ÿê[Ö™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129760 1250606578/10000213pˆbX<Ý¥™&IDMAP/UID2SID/10000281 1247866677/S-1-5-21-1834383793-1770918451-929701000-14857Bp¸X=¢ _r™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-14857 1247866677/10000281Bp X;Ý-‚™&IDMAP/UID2SID/10000280 1251824050/S-1-5-21-1834383793-1770918451-929701000-1442BBp°½X<ùh=™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1442 1251824050/10000280BBphƒX=-Í í™&IDMAP/UID2SID/10000279 1247866321/S-1-5-21-1834383793-1770918451-929701000-163142p(…X>—…¯™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-163142 1247866321/10000279pˆäX=-!gÔ™&IDMAP/UID2SID/10000277 1250193793/S-1-5-21-1834383793-1770918451-929701000-129310pð>X>oø2J™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129310 1250193793/10000277p¸X=i þ™&IDMAP/UID2SID/10000141 1251215817/S-1-5-21-1834383793-1770918451-929701000-148074pè·X>kLãê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148074 1251215817/10000141p˜;X=}de+™&IDMAP/UID2SID/10000266 1250703920/S-1-5-21-1834383793-1770918451-929701000-107875pðìX>Ëɇ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107875 1250703920/10000266p¸]X=-Ésl™&IDMAP/UID2SID/10000173 1250875191/S-1-5-21-1834383793-1770918451-929701000-143675p°îX>sVw™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143675 1250875191/10000173pøÖX=}6Ul™&IDMAP/UID2SID/10000261 1251131452/S-1-5-21-1834383793-1770918451-929701000-107925p˜ŒX>÷÷Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107925 1251131452/10000261pø³X=}`¸ß™&IDMAP/UID2SID/10000260 1251131452/S-1-5-21-1834383793-1770918451-929701000-148486p€LX>›È<´™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148486 1251131452/10000260pºX=-:S™&IDMAP/UID2SID/10000171 1251132005/S-1-5-21-1834383793-1770918451-929701000-143717pQX>¯|õ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143717 1251132005/10000171pØÞX=r˜™&IDMAP/UID2SID/10000249 1251150711/S-1-5-21-1834383793-1770918451-929701000-148466pˆ¥X>›]îí™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148466 1251150711/10000249plX=Ý[¢™&IDMAP/UID2SID/10000185 1251218700/S-1-5-21-1834383793-1770918451-929701000-119280pp±X>C5Á*™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119280 1251218700/10000185p8ÕX=CÕ ™&IDMAP/UID2SID/10000248 1250611448/S-1-5-21-1834383793-1770918451-929701000-119202pP{X>CéTÛ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119202 1250611448/10000248p8˜X=m8™&IDMAP/UID2SID/10000247 1250611448/S-1-5-21-1834383793-1770918451-929701000-143665p0 X>ó Z”™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143665 1250611448/10000247p XX=½›AÅ™&IDMAP/UID2SID/10000121 1251215911/S-1-5-21-1834383793-1770918451-929701000-143824p¨eX>K ±™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143824 1251215911/10000121pP–X=½qÞQ™&IDMAP/UID2SID/10000122 1251149659/S-1-5-21-1834383793-1770918451-929701000-141231p`íX>ÃÙ$ ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141231 1251149659/10000122pØ9X=­€q`™&IDMAP/GID2SID/10000378 1251132374/S-1-5-21-1834383793-1770918451-929701000-129606p,9X>‹h^v™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129606 1251132374/10000378pØ2X=-ºˆ™&IDMAP/UID2SID/10000271 1251132374/S-1-5-21-1834383793-1770918451-929701000-148082pÈ!X>ë!=™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148082 1251132374/10000271pX=-Gü™&IDMAP/UID2SID/10000270 1250180739/S-1-5-21-1834383793-1770918451-929701000-148493pÌòX>î¯h™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148493 1250180739/10000270pHX=}`8ª™&IDMAP/UID2SID/10000160 1251246539/S-1-5-21-1834383793-1770918451-929701000-141061pðX>kœh™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119073 1251826461/10000269px¢X=-GÆ™&IDMAP/UID2SID/10000170 1250871957/S-1-5-21-1834383793-1770918451-929701000-141230p` X>Ã)>;™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141230 1250871957/10000170ph$X=}ŽÈž™&IDMAP/UID2SID/10000265 1251153462/S-1-5-21-1834383793-1770918451-929701000-107874p@GX>Ë¡™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107874 1251153462/10000265p8sX<­(þ-™&IDMAP/GID2SID/10000374 1250872602/S-1-5-21-1834383793-1770918451-929701000-43583BppœX=>Ø{x™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43583 1250872602/10000374Bp˜½X=­Ra¡™&IDMAP/GID2SID/10000373 1250872602/S-1-5-21-1834383793-1770918451-929701000-148143pˆX>/?€™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148143 1250872602/10000373p¸æX=­|Ä™&IDMAP/GID2SID/10000372 1250872602/S-1-5-21-1834383793-1770918451-929701000-129731pHVX>·Òk.™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129731 1250872602/10000372pØóX=­¦'ˆ™&IDMAP/GID2SID/10000371 1250872602/S-1-5-21-1834383793-1770918451-929701000-129603p8X>‹XªG™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129603 1250872602/10000371p`ßX<}⎅™&IDMAP/UID2SID/10000263 1251824050/S-1-5-21-1834383793-1770918451-929701000-17010BpÐÊX=rÃ( ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-17010 1251824050/10000263Bp8²X=} òø™&IDMAP/UID2SID/10000262 1250617401/S-1-5-21-1834383793-1770918451-929701000-129555p-X>DZƒÝ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129555 1250617401/10000262pX=ÍS›™&IDMAP/UID2SID/10000257 1250110556/S-1-5-21-1834383793-1770918451-929701000-107873pœÛX>Ëiº·™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107873 1250110556/10000257p¬X=Í)ºò™&IDMAP/UID2SID/10000158 1250268910/S-1-5-21-1834383793-1770918451-929701000-143724p¿X>ŸÔï©™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143724 1250268910/10000158pøX=ÍOðO™&IDMAP/UID2SID/10000251 1250611094/S-1-5-21-1834383793-1770918451-929701000-107839pøùX>˳…ˆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107839 1250611094/10000251p˜IX=ÍySÙ&IDMAP/UID2SID/10000250 1251132373/S-1-5-21-1834383793-1770918451-929701000-143670pèQX>sæÿ~™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143670 1251132373/10000250pø1X=]PÎg™&IDMAP/UID2SID/10000204 1251313187/S-1-5-21-1834383793-1770918451-929701000-148158phX>ÛH¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148158 1251313187/10000204p0ÁX=½ó4-™&IDMAP/UID2SID/10000225 1251145639/S-1-5-21-1834383793-1770918451-929701000-148423pÈðX>›w2™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148423 1251145639/10000225pXKX=½˜ ™&IDMAP/UID2SID/10000224 1251152545/S-1-5-21-1834383793-1770918451-929701000-107735p¨>X>ºÑí™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107735 1251152545/10000224pXªX=ꌙ&IDMAP/UID2SID/10000191 1250010769/S-1-5-21-1834383793-1770918451-929701000-148314pèïX>o¸C­™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148314 1250010769/10000191pàeX=À ™&IDMAP/UID2SID/10000192 1248710990/S-1-5-21-1834383793-1770918451-929701000-148248p,X>Cß:ã™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148248 1248710990/10000192p(¡X=Á~0™&IDMAP/UID2SID/10000145 1251154820/S-1-5-21-1834383793-1770918451-929701000-119278pX>ÃÏn™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119278 1251154820/10000145p¸ôX=ëᣙ&IDMAP/UID2SID/10000144 1250188501/S-1-5-21-1834383793-1770918451-929701000-143890p@ÿX>ËÄ€S™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143890 1250188501/10000144p˜WX=½›Áú™&IDMAP/UID2SID/10000221 1247760644/S-1-5-21-1834383793-1770918451-929701000-148450px5X>_­™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148450 1247760644/10000221p QX=½Å$n™&IDMAP/UID2SID/10000220 1247760644/S-1-5-21-1834383793-1770918451-929701000-119105pxïX>—¿ï™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119105 1247760644/10000220pdX=]Ò¤ ™&IDMAP/UID2SID/10000207 1250699869/S-1-5-21-1834383793-1770918451-929701000-119263pLX>CÚ&“™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119263 1250699869/10000207pxQX=]¨Aš™&IDMAP/UID2SID/10000208 1250612201/S-1-5-21-1834383793-1770918451-929701000-119265pðýX>C:ô\™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119265 1250612201/10000208pœÔX=—›ò™&IDMAP/UID2SID/10000246 1250695746/S-1-5-21-1834383793-1770918451-929701000-129641pt+X>óõÚm™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129641 1250695746/10000246p˜BX=Áþe™&IDMAP/UID2SID/10000245 1250695770/S-1-5-21-1834383793-1770918451-929701000-129706p X>ŸÉØà™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129706 1250695770/10000245pX=“nq™&IDMAP/UID2SID/10000140 1250814800/S-1-5-21-1834383793-1770918451-929701000-148148pxX>—¥!Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148148 1250814800/10000140pH™X=ÍÿV™&IDMAP/UID2SID/10000159 1250797242/S-1-5-21-1834383793-1770918451-929701000-143699p °X>sjÑ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143699 1250797242/10000159pX£X=½Å¤8™&IDMAP/UID2SID/10000120 1251141205/S-1-5-21-1834383793-1770918451-929701000-119191p X>áµk™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119191 1251141205/10000120pxýX<ݯ؈™&IDMAP/UID2SID/10000183 1249573430/S-1-5-21-1834383793-1770918451-929701000-95346Bp¨ÇX=vqDg™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95346 1249573430/10000183BpÀãX=ëaÙ™&IDMAP/UID2SID/10000244 1251129712/S-1-5-21-1834383793-1770918451-929701000-143856pð×X>ËL$™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143856 1251129712/10000244pPCX=ÅL™&IDMAP/UID2SID/10000243 1250535879/S-1-5-21-1834383793-1770918451-929701000-143869pXâX>KT'6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143869 1250535879/10000243pìÕX= ¹ *™&IDMAP/UID2SID/10000217 1251143308/S-1-5-21-1834383793-1770918451-929701000-129309p¾X>ïò'ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129309 1251143308/10000217p¸hX= ãl™&IDMAP/UID2SID/10000216 1251143308/S-1-5-21-1834383793-1770918451-929701000-148406p`¼X>››™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148406 1251143308/10000216pØ\X=mý¼™&IDMAP/UID2SID/10000234 1251136486/S-1-5-21-1834383793-1770918451-929701000-119217pxCX>ÃŽý¶™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119217 1251136486/10000234pøbX=mÚ™I™&IDMAP/UID2SID/10000235 1251136486/S-1-5-21-1834383793-1770918451-929701000-119209pp£X>C¹£™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119209 1251136486/10000235p´ÁX=½K(*™&IDMAP/UID2SID/10000129 1250698952/S-1-5-21-1834383793-1770918451-929701000-148344p€EX>ïX¹V™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148344 1250698952/10000129pôÆX=} ò™&IDMAP/UID2SID/10000062 1249775312/S-1-5-21-1834383793-1770918451-929701000-129552pˆfX>ǡϮ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129552 1249775312/10000062p˜õX=?(À™&IDMAP/UID2SID/10000242 1250796340/S-1-5-21-1834383793-1770918451-929701000-143683pàKX>ó+Û™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143683 1250796340/10000242ppzX=i‹3™&IDMAP/UID2SID/10000241 1250796340/S-1-5-21-1834383793-1770918451-929701000-143684p°ËX>óÛÁõ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143684 1250796340/10000241pØX=“&IDMAP/UID2SID/10000240 1250632584/S-1-5-21-1834383793-1770918451-929701000-108010pÐØX>kK±Ê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-108010 1250632584/10000240pØX=m2 |™&IDMAP/UID2SID/10000239 1250810300/S-1-5-21-1834383793-1770918451-929701000-141234pеX>ÃéØÎ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141234 1250810300/10000239p¨–X=m\pï™&IDMAP/UID2SID/10000238 1250810300/S-1-5-21-1834383793-1770918451-929701000-143812p°‡X>Ëx™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143812 1250810300/10000238pX<B÷ˆ™&IDMAP/UID2SID/10000095 1250561251/S-1-5-21-1834383793-1770918451-929701000-64587Bpp¿X=¦…Ë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-64587 1250561251/10000095Bp¸®X<–½o™&IDMAP/UID2SID/10000093 1250727725/S-1-5-21-1834383793-1770918451-929701000-25489Bp0ÝX=¦W™™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-25489 1250727725/10000093BpÀmX=À ã™&IDMAP/UID2SID/10000092 1250606578/S-1-5-21-1834383793-1770918451-929701000-119082p€»X>ë!\æ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119082 1250606578/10000092pCX<êƒV™&IDMAP/UID2SID/10000091 1251822639/S-1-5-21-1834383793-1770918451-929701000-38137BpoX=J]e™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-38137 1251822639/10000091Bp@¨X=gÿ™&IDMAP/UID2SID/10000190 1250813974/S-1-5-21-1834383793-1770918451-929701000-141236p|ÕX>ÃI¦˜™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141236 1250813974/10000190p0­X=ݳ…Ô™&IDMAP/UID2SID/10000189 1250006981/S-1-5-21-1834383793-1770918451-929701000-143811phŠX>ËÈ-Ÿ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143811 1250006981/10000189pÈœX<MÝ ›™&IDMAP/GID2SID/10000357 1251140486/S-1-5-21-1834383793-1770918451-929701000-86083BpxX=>8ª*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-86083 1251140486/10000357BpØX<m.`0™&IDMAP/UID2SID/10000233 1251140486/S-1-5-21-1834383793-1770918451-929701000-26839Bp(¨X=JpÄù™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-26839 1251140486/10000233BpX X=mXã™&IDMAP/UID2SID/10000232 1250529960/S-1-5-21-1834383793-1770918451-929701000-129691pèöX>sŸÝ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129691 1250529960/10000232p€ÞX=m‚&™&IDMAP/UID2SID/10000231 1251822074/S-1-5-21-1834383793-1770918451-929701000-119352p(BX>o.2R™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119352 1251822074/10000231pTX=m¬‰Š™&IDMAP/UID2SID/10000230 1251822074/S-1-5-21-1834383793-1770918451-929701000-119383pˆòX>ï~Ž`™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119383 1251822074/10000230pÈrX=}âP™&IDMAP/UID2SID/10000163 1251148046/S-1-5-21-1834383793-1770918451-929701000-129581p X>G’^ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129581 1251148046/10000163px X=Bw¾™&IDMAP/UID2SID/10000195 1250805658/S-1-5-21-1834383793-1770918451-929701000-143716pÂX>ÿ•™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143716 1250805658/10000195p˜pX=½K¨_™&IDMAP/UID2SID/10000229 1251824350/S-1-5-21-1834383793-1770918451-929701000-141229p`?X>C$3ä™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141229 1251824350/10000229p¢X=½u Ó™&IDMAP/UID2SID/10000228 1250548473/S-1-5-21-1834383793-1770918451-929701000-107737pà4X>Ÿ·™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107737 1250548473/10000228phuX=í»z{™&IDMAP/GID2SID/10000339 1250813825/S-1-5-21-1834383793-1770918451-929701000-143889pP¹X>ã—™™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143889 1250813825/10000339pð"X=lZü™&IDMAP/UID2SID/10000094 1250889449/S-1-5-21-1834383793-1770918451-929701000-107553p X>ÇQ Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107553 1250889449/10000094pX`X=m2F™&IDMAP/UID2SID/10000139 1250813825/S-1-5-21-1834383793-1770918451-929701000-143893p¸vX>ËÔ4‚™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143893 1250813825/10000139p¸ûX=Ý1¯.™&IDMAP/UID2SID/10000186 1250614472/S-1-5-21-1834383793-1770918451-929701000-119277phX>ÃÏè ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119277 1250614472/10000186p”ÉX=íåÝî™&IDMAP/GID2SID/10000338 1250784823/S-1-5-21-1834383793-1770918451-929701000-143937pX>fœf™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143937 1250784823/10000338pX(X=½ŸnF™&IDMAP/UID2SID/10000227 1250525522/S-1-5-21-1834383793-1770918451-929701000-107554pÐßX>ÇA™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107554 1250525522/10000227p¸™X=½Éѹ™&IDMAP/UID2SID/10000226 1250805470/S-1-5-21-1834383793-1770918451-929701000-143668páX>ó0Ù&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143668 1250805470/10000226p ÌX=½u‹™&IDMAP/UID2SID/10000128 1250804339/S-1-5-21-1834383793-1770918451-929701000-141233pXkX>Ã9òi™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141233 1250804339/10000128p”ÂX=½Ÿî™&IDMAP/UID2SID/10000127 1250804339/S-1-5-21-1834383793-1770918451-929701000-143828ph\X>KΣD™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143828 1250804339/10000127p˜¨X=–=¥™&IDMAP/UID2SID/10000193 1251160436/S-1-5-21-1834383793-1770918451-929701000-148369phúX>ï3‰™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148369 1251160436/10000193pØuX=lÚ1™&IDMAP/UID2SID/10000194 1251132851/S-1-5-21-1834383793-1770918451-929701000-148249p¨sX>C!H™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148249 1251132851/10000194pð®X=ÝL»™&IDMAP/UID2SID/10000187 1250816421/S-1-5-21-1834383793-1770918451-929701000-148238p°¨X>é™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148238 1250816421/10000187p8LX=½Gû™&IDMAP/UID2SID/10000223 1251310037/S-1-5-21-1834383793-1770918451-929701000-129610pØŸX>s¥~_™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129610 1251310037/10000223pMX<½q^‡™&IDMAP/UID2SID/10000222 1248878179/S-1-5-21-1834383793-1770918451-929701000-67570Bp@X=zÕàÉ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-67570 1248878179/10000222Bp,ÔX= eCC™&IDMAP/UID2SID/10000219 1249921474/S-1-5-21-1834383793-1770918451-929701000-148161phåX>—@!à™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148161 1249921474/10000219p¨X= ¦¶™&IDMAP/UID2SID/10000218 1249942550/S-1-5-21-1834383793-1770918451-929701000-148212ppûX>Ã]Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148212 1249942550/10000218p³X=CUÖ™&IDMAP/UID2SID/10000148 1250871721/S-1-5-21-1834383793-1770918451-929701000-143685pÀCX>ó‹¨Z™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143685 1250871721/10000148ppsX=òb™&IDMAP/UID2SID/10000149 1250787383/S-1-5-21-1834383793-1770918451-929701000-119376pˆX>oY¬™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119376 1250787383/10000149p°àX= ‹ùj™&IDMAP/UID2SID/10000212 1250871163/S-1-5-21-1834383793-1770918451-929701000-143855p¨X>Ë^e¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143855 1250871163/10000212pÈ€X= µ\Þ™&IDMAP/UID2SID/10000211 1250871163/S-1-5-21-1834383793-1770918451-929701000-143863p°¡X>K4¿Ø™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143863 1250871163/10000211p€×X= ß¿Q™&IDMAP/UID2SID/10000210 1251131203/S-1-5-21-1834383793-1770918451-929701000-107752p(àX>l…™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107752 1251131203/10000210pˆmX=]~Þ&™&IDMAP/UID2SID/10000209 1250795680/S-1-5-21-1834383793-1770918451-929701000-148117pà¸X>UÅÍ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148117 1250795680/10000209pLX<ÍOp™&IDMAP/UID2SID/10000151 1250873129/S-1-5-21-1834383793-1770918451-929701000-95184Bpè–X=&íš"™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95184 1250873129/10000151Bpˆ‚X=ÄMd™&IDMAP/UID2SID/10000198 1250702675/S-1-5-21-1834383793-1770918451-929701000-143723pìêX>Ÿ$ E™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143723 1250702675/10000198pØ´X=—½™&IDMAP/UID2SID/10000146 1250810717/S-1-5-21-1834383793-1770918451-929701000-143721pP²X>ŸÄ;{™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143721 1250810717/10000146p ‹X=½ÉQ„™&IDMAP/UID2SID/10000126 1251147612/S-1-5-21-1834383793-1770918451-929701000-129575pX>ÇÒ£™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129575 1251147612/10000126p¬ìX=]z±¥™&IDMAP/UID2SID/10000103 1251143308/S-1-5-21-1834383793-1770918451-929701000-143710pœX>ß-3™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143710 1251143308/10000103p@cX=]¤™&IDMAP/UID2SID/10000102 1251150089/S-1-5-21-1834383793-1770918451-929701000-143781pH X>Ÿ'Ι&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143781 1251150089/10000102pxÌX=m¸I™&IDMAP/UID2SID/10000147 1250810717/S-1-5-21-1834383793-1770918451-929701000-141060pø‚X>ëVÖ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141060 1250810717/10000147p°·X=-!çž™&IDMAP/UID2SID/10000177 1250873609/S-1-5-21-1834383793-1770918451-929701000-143660pàÍX>ó°Ø›™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143660 1250873609/10000177pD/X<ýÕ%Å™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-9105 1251825058/100004191pð˜X>ëh;™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141061 1251246539/10000160pöX=]Ò$Ø™&IDMAP/UID2SID/10000107 1250729750/S-1-5-21-1834383793-1770918451-929701000-119177p˜¯X>–Ï™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119177 1250729750/10000107p*X=]ü‡K™&IDMAP/UID2SID/10000106 1250698977/S-1-5-21-1834383793-1770918451-929701000-148446pø*X>›òŸ'™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148446 1250698977/10000106pøFX=]ü™&IDMAP/UID2SID/10000206 1250180781/S-1-5-21-1834383793-1770918451-929701000-107869p(;X>KTû1™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107869 1250180781/10000206pbX=-÷ƒ+™&IDMAP/UID2SID/10000178 1250873574/S-1-5-21-1834383793-1770918451-929701000-129756p(WX>ÕœP™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129756 1250873574/10000178p†X=]&kô™&IDMAP/UID2SID/10000205 1251313168/S-1-5-21-1834383793-1770918451-929701000-148135pNX>`FÊ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148135 1251313168/10000205p|HX=m°¶ ™&IDMAP/UID2SID/10000136 1251141206/S-1-5-21-1834383793-1770918451-929701000-119190p@2X>1Ï™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119190 1251141206/10000136pؘX=mÚ™&IDMAP/UID2SID/10000135 1251147048/S-1-5-21-1834383793-1770918451-929701000-143897p°¯X>˔ϙ&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143897 1251147048/10000135pÈyX=šêð™&IDMAP/UID2SID/10000199 1251143920/S-1-5-21-1834383793-1770918451-929701000-143708p8X>Ÿ)e±$™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143751 1251142437/10000203pðLX=}¸«Ü™&IDMAP/UID2SID/10000164 1250831042/S-1-5-21-1834383793-1770918451-929701000-129576pøÏX>Ç̸™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129576 1250831042/10000164p@ÒX=Ý…u™&IDMAP/UID2SID/10000184 1250790279/S-1-5-21-1834383793-1770918451-929701000-107671pX!X>s–ºß™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107671 1250790279/10000184p¨øX=-Ÿù™&IDMAP/UID2SID/10000174 1250807756/S-1-5-21-1834383793-1770918451-929701000-143676pðÞX>shÜ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143676 1250807756/10000174ppÔX=-óÖß™&IDMAP/UID2SID/10000172 1251823492/S-1-5-21-1834383793-1770918451-929701000-141064pdX>ëj™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141064 1251823492/10000172p°ÄX=m¬ U™&IDMAP/UID2SID/10000130 1250726375/S-1-5-21-1834383793-1770918451-929701000-129567pPX>GGxŠ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129567 1250726375/10000130p(šX= 7³N™&IDMAP/UID2SID/10000114 1251138273/S-1-5-21-1834383793-1770918451-929701000-107670p¸„X>sæÓz™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107670 1251138273/10000114p0ÏX=K™&IDMAP/UID2SID/10000196 1251146640/S-1-5-21-1834383793-1770918451-929701000-141320pÀÇX>ï-0_™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141320 1251146640/10000196pÈ£X= a™&IDMAP/UID2SID/10000113 1251138927/S-1-5-21-1834383793-1770918451-929701000-148100p  X>—OO(™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148100 1251138927/10000113pè¢X=Ý-ã™&IDMAP/UID2SID/10000180 1250898780/S-1-5-21-1834383793-1770918451-929701000-129755px†X>%¶ë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129755 1250898780/10000180pÀX=ÝÝèG™&IDMAP/UID2SID/10000188 1251824050/S-1-5-21-1834383793-1770918451-929701000-107606p0KX>ó)¢™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107606 1251824050/10000188p0´X=]Î÷Á™&IDMAP/UID2SID/10000201 1250267973/S-1-5-21-1834383793-1770918451-929701000-143730ppÛX>J|ù™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143730 1250267973/10000201pø[X=]øZ5™&IDMAP/UID2SID/10000200 1250267973/S-1-5-21-1834383793-1770918451-929701000-143732p¸AX>ªIÙ&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143732 1250267973/10000200pÜçX=ÍSf™&IDMAP/UID2SID/10000157 1250630625/S-1-5-21-1834383793-1770918451-929701000-119178p¨ˆX>F¶g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119178 1250630625/10000157p8X=î°×™&IDMAP/UID2SID/10000197 1248394430/S-1-5-21-1834383793-1770918451-929701000-107832pP.X>Ëã6Æ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107832 1248394430/10000197p0¦X=]PN2™&IDMAP/UID2SID/10000104 1251149659/S-1-5-21-1834383793-1770918451-929701000-107712p@ÄX>?Ïø™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107712 1251149659/10000104p nX=ÝÙ;ü™&IDMAP/UID2SID/10000182 1250527870/S-1-5-21-1834383793-1770918451-929701000-143707p¸ X>ŸyU™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143707 1250527870/10000182p[X=ÝŸo™&IDMAP/UID2SID/10000181 1250527870/S-1-5-21-1834383793-1770918451-929701000-143712pXX>?ûü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143712 1250527870/10000181p0ÖX=-KJ™&IDMAP/UID2SID/10000176 1250644308/S-1-5-21-1834383793-1770918451-929701000-107782pLïX>Ÿµá.™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107782 1250644308/10000176pØgX=-u­…™&IDMAP/UID2SID/10000175 1251158093/S-1-5-21-1834383793-1770918451-929701000-107828pˆ1X>KÎw@™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107828 1251158093/10000175pP<X=}™&IDMAP/UID2SID/10000168 1250816033/S-1-5-21-1834383793-1770918451-929701000-107751pØìX>e… ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107751 1250816033/10000168p8eX=}:‚‚™&IDMAP/UID2SID/10000167 1250700661/S-1-5-21-1834383793-1770918451-929701000-107750pŒæX>µž»™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107750 1250700661/10000167p06X<}dåõ™&IDMAP/UID2SID/10000166 1251146665/S-1-5-21-1834383793-1770918451-929701000-95305BphX=FU¸g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95305 1251146665/10000166BpèqX=}ŽHi™&IDMAP/UID2SID/10000165 1251147272/S-1-5-21-1834383793-1770918451-929701000-107702pàÆX>Ÿ ¨™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107702 1251147272/10000165pH X=} rÙ&IDMAP/UID2SID/10000162 1250698610/S-1-5-21-1834383793-1770918451-929701000-107771p KX>ÐÓæ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107771 1250698610/10000162pÔÀX=}6Õ6™&IDMAP/UID2SID/10000161 1250698668/S-1-5-21-1834383793-1770918451-929701000-107785p ÝX>ŸÅ•]™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107785 1250698668/10000161p¼ÚX<ͧãL™&IDMAP/UID2SID/10000155 1251149160/S-1-5-21-1834383793-1770918451-929701000-95370BpXyX=zݤ)™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95370 1251149160/10000155Bp™X=ÍÑFÀ™&IDMAP/UID2SID/10000154 1250796526/S-1-5-21-1834383793-1770918451-929701000-129547p,2X>GÜ)Ä™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129547 1250796526/10000154p¤ŸX=Íû©3™&IDMAP/UID2SID/10000153 1250715849/S-1-5-21-1834383793-1770918451-929701000-141242pÞX>C¿2è™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141242 1250715849/10000153p˜šX=Í% §™&IDMAP/UID2SID/10000152 1250787006/S-1-5-21-1834383793-1770918451-929701000-143835pèX>Ëóù™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143835 1250787006/10000152p¸VX=íAb™&IDMAP/GID2SID/10000337 1251157458/S-1-5-21-1834383793-1770918451-929701000-129692pÆX> Š$ß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129692 1251157458/10000337pLáX= ãìg™&IDMAP/UID2SID/10000116 1250270826/S-1-5-21-1834383793-1770918451-929701000-143752pÈ6X>˜‰™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143752 1250270826/10000116ph˜X= PÛ™&IDMAP/UID2SID/10000115 1250696220/S-1-5-21-1834383793-1770918451-929701000-143785phÂX>ŸÅÁa™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143785 1250696220/10000115pŽX=šj»™&IDMAP/UID2SID/10000099 1251824050/S-1-5-21-1834383793-1770918451-929701000-148092p !X>kWdç™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148092 1251824050/10000099ppéX=m\ð¹™&IDMAP/UID2SID/10000138 1250642977/S-1-5-21-1834383793-1770918451-929701000-143880pH„X>KYp™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143880 1250642977/10000138p¸¼X=m†S-™&IDMAP/UID2SID/10000137 1251143370/S-1-5-21-1834383793-1770918451-929701000-119216pXŽX>ÃÞR™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119216 1251143370/10000137p¨ñX=m}‡™&IDMAP/UID2SID/10000134 1250703805/S-1-5-21-1834383793-1770918451-929701000-119291pˆÈX>ÃÏr™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119291 1250703805/10000134p X=m.àú™&IDMAP/UID2SID/10000133 1250870800/S-1-5-21-1834383793-1770918451-929701000-119282p°ÙX>C•Žô™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119282 1250870800/10000133p(~X=mXCn™&IDMAP/UID2SID/10000132 1251133406/S-1-5-21-1834383793-1770918451-929701000-107781p€˜X>ŸûÉ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107781 1251133406/10000132pСX=m‚¦á™&IDMAP/UID2SID/10000131 1251133406/S-1-5-21-1834383793-1770918451-929701000-129711p€ŸX>~Ë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129711 1251133406/10000131p0uX<]&ë¾™&IDMAP/UID2SID/10000105 1250880279/S-1-5-21-1834383793-1770918451-929701000-95165Bp˜ÄX=N¯÷™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95165 1250880279/10000105Bp˜iX=½k™&IDMAP/UID2SID/10000124 1250698821/S-1-5-21-1834383793-1770918451-929701000-119208p˜X>C ½8™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119208 1250698821/10000124pèjX=½G{Þ™&IDMAP/UID2SID/10000123 1250698821/S-1-5-21-1834383793-1770918451-929701000-143882p.X>Kï&:™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143882 1250698821/10000123p¬ÞX< &™&IDMAP/UID2SID/10000118 1250790522/S-1-5-21-1834383793-1770918451-929701000-95343BpPtX=öÐν™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95343 1250790522/10000118BphnX= ¹‰ô™&IDMAP/UID2SID/10000117 1250874996/S-1-5-21-1834383793-1770918451-929701000-148463pæX>›M:¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148463 1250874996/10000117p¨X= ‹y5™&IDMAP/UID2SID/10000112 1250713299/S-1-5-21-1834383793-1770918451-929701000-143892p¨7X>Ë$N™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143892 1250713299/10000112pˆX= µÜ¨™&IDMAP/UID2SID/10000111 1248831893/S-1-5-21-1834383793-1770918451-929701000-107738p =X>Ê…™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107738 1248831893/10000111p˜•X<í9¤Õ™&IDMAP/GID2SID/10000336 1250868523/S-1-5-21-1834383793-1770918451-929701000-38184BpüÑX=¾µÆ{™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38184 1250868523/10000336Bp(ŒX<”™&IDMAP/UID2SID/10000096 1251825509/S-1-5-21-1834383793-1770918451-929701000-79416Bp€­X=rô™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79416 1251825509/10000096Bph‘X= ß?™&IDMAP/UID2SID/10000110 1250868523/S-1-5-21-1834383793-1770918451-929701000-129710pø‰X>ß—f™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129710 1250868523/10000110p(wX=]~^ñ™&IDMAP/UID2SID/10000109 1250785574/S-1-5-21-1834383793-1770918451-929701000-119192p(üX>‘œÐ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119192 1250785574/10000109pxX=]¨Ád™&IDMAP/UID2SID/10000108 1250785574/S-1-5-21-1834383793-1770918451-929701000-119198p`µX>±.™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119198 1250785574/10000108p¸§X=]ÎwŒ™&IDMAP/UID2SID/10000101 1251131675/S-1-5-21-1834383793-1770918451-929701000-141243pèÚX>CoM™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141243 1251131675/10000101pð¼X=]øÚÿ™&IDMAP/UID2SID/10000100 1251131674/S-1-5-21-1834383793-1770918451-929701000-143819pȪX>ËHcÆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143819 1251131674/10000100p [X=î0¢™&IDMAP/UID2SID/10000097 1250536200/S-1-5-21-1834383793-1770918451-929701000-148128pˆùX>—:Ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148128 1250536200/10000097p€oX=çÉ™&IDMAP/UID2SID/10000090 1249923102/S-1-5-21-1834383793-1770918451-929701000-119181p@îX>—«Žˆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119181 1249923102/10000090pH’X=ݳŸ™&IDMAP/UID2SID/10000089 1250611094/S-1-5-21-1834383793-1770918451-929701000-148421p1X>›Ðh™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148421 1250611094/10000089pô¿X=]·oâ™&IDMAP/GID2SID/10000280 1250538396/S-1-5-21-1834383793-1770918451-929701000-101680p°qX>lô–™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128970 1251822591/10000281pX=­VŽ·™&IDMAP/GID2SID/10000279 1250538396/S-1-5-21-1834383793-1770918451-929701000-101669pèX=] o™&IDMAP/GID2SID/10000281 1251822591/S-1-5-21-1834383793-1770918451-929701000-128970pè›X<­€ñ*™&IDMAP/GID2SID/10000278 1251246560/S-1-5-21-1834383793-1770918451-929701000-25224BpÈâX=¶Û™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-25224 1251246560/10000278Bp`X<ÝÝh™&IDMAP/UID2SID/10000088 1251824050/S-1-5-21-1834383793-1770918451-929701000-66635Bp@çX=Jú4œ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-66635 1251824050/10000088BpøºX<­Ô·™&IDMAP/GID2SID/10000276 1246951403/S-1-5-21-1834383793-1770918451-929701000-39695Bpˆ{X=ê$R·™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-39695 1246951403/10000276BpØ»X<­þ…™&IDMAP/GID2SID/10000275 1246951403/S-1-5-21-1834383793-1770918451-929701000-39694BptÃX=jï*Ô™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-39694 1246951403/10000275Bp”X<ÝÌ…™&IDMAP/UID2SID/10000087 1246951403/S-1-5-21-1834383793-1770918451-929701000-87059Bp8«X=¢ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87059 1246951403/10000087Bp˜¶X=Íû)þ™&IDMAP/UID2SID/10000053 1250286053/S-1-5-21-1834383793-1770918451-929701000-119356pxöX>oîÌå™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119356 1250286053/10000053pø¬(îò“º™&IDMAP/UID2SID/10000 1246297471/-B@X—(îò?ô™&IDMAP/UID2SID/10001 1246297471/-B@À¬X=-!gi™&IDMAP/UID2SID/10000077 1251824050/S-1-5-21-1834383793-1770918451-929701000-107858p(4X>Ëníé™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107858 1251824050/10000077p `X=-KÊÜ™&IDMAP/UID2SID/10000076 1251143169/S-1-5-21-1834383793-1770918451-929701000-129686pXþX>ó;ùò™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129686 1251143169/10000076pÐ]X<Ý1/ù™&IDMAP/UID2SID/10000086 1251824050/S-1-5-21-1834383793-1770918451-929701000-95888Bp˜&X=&Ã×L™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95888 1251824050/10000086BpÜ#X=Ý[’l™&IDMAP/UID2SID/10000085 1251310325/S-1-5-21-1834383793-1770918451-929701000-107683p»X>ó+¯Œ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107683 1251310325/10000085pÜ)X=Ý…õß™&IDMAP/UID2SID/10000084 1250642961/S-1-5-21-1834383793-1770918451-929701000-107767pàéX>Ÿºa™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107767 1250642961/10000084p§X=ý•ß™&IDMAP/GID2SID/10000262 1251824032/S-1-5-21-1834383793-1770918451-929701000-113648pà•X>‹ž®™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113648 1251824032/10000262p4ÅX=ý¿B6™&IDMAP/GID2SID/10000261 1250642960/S-1-5-21-1834383793-1770918451-929701000-148342p0=X>‡ÑŠ)™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148342 1250642960/10000261p˜“X<ݯXS™&IDMAP/UID2SID/10000083 1251824050/S-1-5-21-1834383793-1770918451-929701000-66812BpШX=ý饩™&IDMAP/GID2SID/10000260 1250802575/S-1-5-21-1834383793-1770918451-929701000-119218pЮX>[ƒ¸™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119218 1250802575/10000260pà&X<Ý-‚­™&IDMAP/UID2SID/10000080 1251824050/S-1-5-21-1834383793-1770918451-929701000-79421BpPX=žBs‹™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79421 1251824050/10000080Bpx©X=-Í ‚™&IDMAP/UID2SID/10000079 1250267446/S-1-5-21-1834383793-1770918451-929701000-119274pp&X>ÿ4Û™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119274 1250267446/10000079p¸”X=M1QL™&IDMAP/GID2SID/10000255 1250632584/S-1-5-21-1834383793-1770918451-929701000-129739pÐæX>·R¡U™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129739 1250632584/10000255pü=X=M[´¿™&IDMAP/GID2SID/10000254 1251822639/S-1-5-21-1834383793-1770918451-929701000-119284p@¶X>ÛÍúZ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119284 1251822639/10000254pëX<-Éó6™&IDMAP/UID2SID/10000073 1251130186/S-1-5-21-1834383793-1770918451-929701000-55147Bph´X=öFÞå™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-55147 1251130186/10000073Bp°¾X=-÷ö™&IDMAP/UID2SID/10000078 1250871873/S-1-5-21-1834383793-1770918451-929701000-143901pl7X>÷ÌÙ&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143901 1250871873/10000078p'X<-u-P™&IDMAP/UID2SID/10000075 1250893808/S-1-5-21-1834383793-1770918451-929701000-66597Bp0(X=R¿º¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-66597 1250893808/10000075BpØ­X=-ŸÃ™&IDMAP/UID2SID/10000074 1251310813/S-1-5-21-1834383793-1770918451-929701000-148455pH®X>xख़&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148455 1251310813/10000074p`€X=-óVª™&IDMAP/UID2SID/10000072 1247681305/S-1-5-21-1834383793-1770918451-929701000-148484pØX>›hoê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148484 1247681305/10000072pXðX=-º™&IDMAP/UID2SID/10000071 1250274070/S-1-5-21-1834383793-1770918451-929701000-148482p¨lX>›¢ ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148482 1250274070/10000071p@°X=-G‘™&IDMAP/UID2SID/10000070 1251822623/S-1-5-21-1834383793-1770918451-929701000-148479p8øX>£Éÿ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148479 1251822623/10000070p7m)Ú™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143728 1251132054/10000248pÜ~X=ö%I™&IDMAP/GID2SID/10000247 1250805470/S-1-5-21-1834383793-1770918451-929701000-136387pjX>‡~Å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136387 1250805470/10000247püDX= ‰¼™&IDMAP/GID2SID/10000246 1250805470/S-1-5-21-1834383793-1770918451-929701000-136388p˜¡X>‡Çd*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136388 1250805470/10000246p°¢X=Jì/™&IDMAP/GID2SID/10000245 1250793789/S-1-5-21-1834383793-1770918451-929701000-143907pHoX>Å&½™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143907 1250793789/10000245p£X=tO£™&IDMAP/GID2SID/10000244 1250971642/S-1-5-21-1834383793-1770918451-929701000-129618p`§X> þR#™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129618 1250971642/10000244pp¤X=ž²™&IDMAP/GID2SID/10000243 1250805470/S-1-5-21-1834383793-1770918451-929701000-129662p­X>‹é®5™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129662 1250805470/10000243pP¥X=ÈŠ™&IDMAP/GID2SID/10000242 1250805470/S-1-5-21-1834383793-1770918451-929701000-107844p´X>ãQÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107844 1250805470/10000242pÈŽX<òxý™&IDMAP/GID2SID/10000241 1250805470/S-1-5-21-1834383793-1770918451-929701000-42608BphX=^k.™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42608 1250805470/10000241Bpø¥X=Üp™&IDMAP/GID2SID/10000240 1251822639/S-1-5-21-1834383793-1770918451-929701000-107746pÈþX>7x~Ò™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107746 1251822639/10000240pð§X=í»úE™&IDMAP/GID2SID/10000239 1250805470/S-1-5-21-1834383793-1770918451-929701000-143774pàÛX>·¸R¶™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143774 1250805470/10000239pÜ7X=íå]¹™&IDMAP/GID2SID/10000238 1250805470/S-1-5-21-1834383793-1770918451-929701000-129747pØŠX>7(ûn™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129747 1250805470/10000238pdÀX=íÁ,™&IDMAP/GID2SID/10000237 1250906407/S-1-5-21-1834383793-1770918451-929701000-129198pÀÀX>¯‰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129198 1250906407/10000237pªX=í9$ ™&IDMAP/GID2SID/10000236 1250971642/S-1-5-21-1834383793-1770918451-929701000-143687ph9X>‹ÄÁ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143687 1250971642/10000236pp«X<íc‡™&IDMAP/GID2SID/10000235 1251135589/S-1-5-21-1834383793-1770918451-929701000-42572Bp@šX=iÐ?™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42572 1251135589/10000235BpP¬X=íꆙ&IDMAP/GID2SID/10000234 1251157458/S-1-5-21-1834383793-1770918451-929701000-148353pøX>·˜q™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148353 1251157458/10000234p<5X=í·Mú™&IDMAP/GID2SID/10000233 1250805470/S-1-5-21-1834383793-1770918451-929701000-129661p ÓX>‹9ÈЙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129661 1250805470/10000233p®X=íá°m™&IDMAP/GID2SID/10000232 1251822639/S-1-5-21-1834383793-1770918451-929701000-107691pH”X> Ú§B™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107691 1251822639/10000232p`bX=í á™&IDMAP/GID2SID/10000231 1250805470/S-1-5-21-1834383793-1770918451-929701000-107778pèX>·xÁE™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107778 1250805470/10000231p¤X=í5wT™&IDMAP/GID2SID/10000230 1250805470/S-1-5-21-1834383793-1770918451-929701000-108018pè X>¤…Ž™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-108018 1250805470/10000230p¤ÏX==Õ•)™&IDMAP/GID2SID/10000229 1250805470/S-1-5-21-1834383793-1770918451-929701000-129663p´X>‹™•š™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129663 1250805470/10000229p±X<=ÿøœ™&IDMAP/GID2SID/10000228 1251135589/S-1-5-21-1834383793-1770918451-929701000-42573BpˆX=’ž÷"™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42573 1251135589/10000228Bpp²X<=)\™&IDMAP/GID2SID/10000227 1250630963/S-1-5-21-1834383793-1770918451-929701000-42595BpH:X=ê|x÷™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42595 1250630963/10000227BpP³X==S¿ƒ™&IDMAP/GID2SID/10000226 1250805470/S-1-5-21-1834383793-1770918451-929701000-129721phX>7DK™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129721 1250805470/10000226pPŠX==}"÷™&IDMAP/GID2SID/10000225 1250805470/S-1-5-21-1834383793-1770918451-929701000-129664p×X>‹I|ÿ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129664 1250805470/10000225pµX==§…j™&IDMAP/GID2SID/10000224 1250805470/S-1-5-21-1834383793-1770918451-929701000-129660p¢X>‹‰ák™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129660 1250805470/10000224pHhX==ÑèÝ™&IDMAP/GID2SID/10000223 1251826514/S-1-5-21-1834383793-1770918451-929701000-148396pÀ³X>é,™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148396 1251826514/10000223pжX==ûKQ™&IDMAP/GID2SID/10000222 1250805470/S-1-5-21-1834383793-1770918451-929701000-107766ph@X>7ã̘™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107766 1250805470/10000222p kX<=%¯Ä™&IDMAP/GID2SID/10000221 1250805470/S-1-5-21-1834383793-1770918451-929701000-79444BpÀ„X=/ºß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79444 1250805470/10000221BpX<=O8™&IDMAP/GID2SID/10000220 1250805470/S-1-5-21-1834383793-1770918451-929701000-79394BpÌ X=jOØ5™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79394 1250805470/10000220Bpp¹X<î0 ™&IDMAP/GID2SID/10000219 1250805470/S-1-5-21-1834383793-1770918451-929701000-95350Bp žX=ºB¸™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-95350 1250805470/10000219BpPºX=”€™&IDMAP/GID2SID/10000218 1251822639/S-1-5-21-1834383793-1770918451-929701000-141420p@½X>3@è™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-141420 1251822639/10000218pÄX<B÷ó™&IDMAP/GID2SID/10000217 1251132054/S-1-5-21-1834383793-1770918451-929701000-42589Bpˆ³X=>ü|™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42589 1251132054/10000217Bp¼X<lZg™&IDMAP/GID2SID/10000216 1251824032/S-1-5-21-1834383793-1770918451-929701000-42591Bp 3X=ê¦Ûj™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42591 1251824032/10000216Bp„X=–½Ú™&IDMAP/GID2SID/10000215 1250538396/S-1-5-21-1834383793-1770918451-929701000-148315pTX=¥R™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-36648 1251822591/10000121pнX=À N™&IDMAP/GID2SID/10000214 1251822639/S-1-5-21-1834383793-1770918451-929701000-113149pèáX>/.†ï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113149 1251822639/10000214pìƒX=êƒÁ™&IDMAP/GID2SID/10000213 1250805470/S-1-5-21-1834383793-1770918451-929701000-107779pÀ«X>·(¨ª™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107779 1250805470/10000213p¿X=ç4™&IDMAP/GID2SID/10000212 1251135589/S-1-5-21-1834383793-1770918451-929701000-129587ph»X>ߊeí™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129587 1251135589/10000212p ¬X<}¸+§™&IDMAP/UID2SID/10000064 1251824050/S-1-5-21-1834383793-1770918451-929701000-75911BpXX=òŽM™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-75911 1251824050/10000064Bp uX=}ŽÈ3™&IDMAP/UID2SID/10000065 1249586553/S-1-5-21-1834383793-1770918451-929701000-143853p`X>Ëþ—õ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143853 1249586553/10000065p€´X=M…3™&IDMAP/GID2SID/10000253 1250729595/S-1-5-21-1834383793-1770918451-929701000-148477p¼èX>³›Ò™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148477 1250729595/10000253p„ÌX<M¯z¦™&IDMAP/GID2SID/10000252 1246408046/S-1-5-21-1834383793-1770918451-929701000-36764Bp}X=fBþ ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-36764 1246408046/10000252Bpx|X=}ŸÙ™&IDMAP/UID2SID/10000068 1246408046/S-1-5-21-1834383793-1770918451-929701000-148476pXžX>“Ñ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148476 1246408046/10000068p¸X:MÙÝ™&IDMAP/GID2SID/10000251 1246407434/S-1-5-21-1834383793-1770918451-929701000-512BBBphŸX;ÔÑW™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-512 1246407434/10000251BBBpX= xl™&IDMAP/GID2SID/10000097 1251309681/S-1-5-21-1834383793-1770918451-929701000-126402p`X>35ql™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126402 1251309681/10000097p8¹X= ¢ß™&IDMAP/GID2SID/10000096 1251309681/S-1-5-21-1834383793-1770918451-929701000-126401p¨¹X>3…Š™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126401 1251309681/10000096pÜX= «9™&IDMAP/GID2SID/10000093 1251309681/S-1-5-21-1834383793-1770918451-929701000-126399pX‡X>­$™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126399 1251309681/10000093pX= tq ™&IDMAP/GID2SID/10000091 1251822074/S-1-5-21-1834383793-1770918451-929701000-119075pÔX>ՇΙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119075 1251822074/10000091pX=]gVÜ™&IDMAP/GID2SID/10000088 1250731374/S-1-5-21-1834383793-1770918451-929701000-107716pPÎX>·×)™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107716 1250731374/10000088pŒX=]å6™&IDMAP/GID2SID/10000085 1251309681/S-1-5-21-1834383793-1770918451-929701000-119293pIX>[S;Ù™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119293 1251309681/10000085p6X= ÌäR™&IDMAP/GID2SID/10000095 1251822639/S-1-5-21-1834383793-1770918451-929701000-143843pPfX>㡯™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143843 1251822639/10000095p¸µX=ÍÑÆŠ™&IDMAP/UID2SID/10000054 1250785101/S-1-5-21-1834383793-1770918451-929701000-148281pøžX>C刭™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148281 1250785101/10000054pX=ͧc™&IDMAP/UID2SID/10000055 1246406429/S-1-5-21-1834383793-1770918451-929701000-107798pôX> qo™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107798 1246406429/10000055p`pX=}:M™&IDMAP/UID2SID/10000067 1250012412/S-1-5-21-1834383793-1770918451-929701000-143891p ÜX>Ëtg¸™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143891 1250012412/10000067p _X<MA™&IDMAP/GID2SID/10000250 1251825058/S-1-5-21-1834383793-1770918451-929701000-46573BpˆtX=’ž£\™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-46573 1251825058/10000250Bp8ŸX<¢_b™&IDMAP/GID2SID/10000249 1251153193/S-1-5-21-1834383793-1770918451-929701000-38052Op¨)X=ºÌÒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38052 1251153193/100002496pX6X<}deÀ™&IDMAP/UID2SID/10000066 1251148458/S-1-5-21-1834383793-1770918451-929701000-79085BpðŒX=ÝÌð™&IDMAP/GID2SID/10000209 1250949070/S-1-5-21-1834383793-1770918451-929701000-137093p¸X>àÍ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-137093 1250949070/10000209pÀ<X=Ý1/d™&IDMAP/GID2SID/10000208 1250949070/S-1-5-21-1834383793-1770918451-929701000-127288pxX>Û@¢™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127288 1250949070/10000208p„ X=Ý[’×™&IDMAP/GID2SID/10000207 1250949070/S-1-5-21-1834383793-1770918451-929701000-137092pÜÙX>08h™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-137092 1250949070/10000207peX=Ý…õJ™&IDMAP/GID2SID/10000206 1250949070/S-1-5-21-1834383793-1770918451-929701000-127289pH¼X>Û='™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127289 1250949070/10000206p˜X<ݯX¾™&IDMAP/GID2SID/10000205 1250949070/S-1-5-21-1834383793-1770918451-929701000-91520BpЙX=¶•Ù™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-91520 1250949070/10000205BpÀfX<ÝÙ»1™&IDMAP/GID2SID/10000204 1250949070/S-1-5-21-1834383793-1770918451-929701000-88064BpHµX=fútœ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-88064 1250949070/10000204Bp gX<Ý¥™&IDMAP/GID2SID/10000203 1250949070/S-1-5-21-1834383793-1770918451-929701000-70905BpÈ X=Þ}™ç™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-70905 1250949070/10000203BpÀ{X=Ý-‚™&IDMAP/GID2SID/10000202 1250949070/S-1-5-21-2140803266-1626024873-1299147156-24034p( X>²ºu ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24034 1250949070/10000202p°xX=ÝWå‹™&IDMAP/GID2SID/10000201 1250949070/S-1-5-21-2106152344-1726899929-2013803672-44720pø#X> 7ç™&IDMAP/SID2GID/S-1-5-21-2106152344-1726899929-2013803672-44720 1250949070/10000201pX=ÝHÿ™&IDMAP/GID2SID/10000200 1250949070/S-1-5-21-2140803266-1626024873-1299147156-34812p0!X>½Ž™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34812 1250949070/10000200pàlX= $غ™&IDMAP/GID2SID/10000199 1250949070/S-1-5-21-2140803266-1626024873-1299147156-25445p ¢X>â†H=™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25445 1250949070/10000199pX= N;.™&IDMAP/GID2SID/10000198 1250949070/S-1-5-21-1834383793-1770918451-929701000-153031p`™X>?¼™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-153031 1250949070/10000198pÌ$X= xž¡™&IDMAP/GID2SID/10000197 1250949070/S-1-5-21-2140803266-1626024873-1299147156-37994pð´X>¾ÏT™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-37994 1250949070/10000197pðÌX= ¢™&IDMAP/GID2SID/10000196 1250949070/S-1-5-21-2140803266-1626024873-1299147156-34810p¨"X>]Á8™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34810 1250949070/10000196p@qX= Ìdˆ™&IDMAP/GID2SID/10000195 1250949070/S-1-5-21-1834383793-1770918451-929701000-127557pøMX>_ê/©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127557 1250949070/10000195pl%X= öÇû™&IDMAP/GID2SID/10000194 1250949070/S-1-5-21-2140803266-1626024873-1299147156-21488p¸,X>âlÙ&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-21488 1250949070/10000194pX< +o™&IDMAP/GID2SID/10000193 1250949070/S-1-5-21-1834383793-1770918451-929701000-68182BpðŸX=¾RÒL™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68182 1250949070/10000193BpŒX< JŽâ™&IDMAP/GID2SID/10000192 1250949070/S-1-5-21-1834383793-1770918451-929701000-70902BpÀŠX=^Ý#>™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-70902 1250949070/10000192BpX= tñU™&IDMAP/GID2SID/10000191 1250949070/S-1-5-21-1834383793-1770918451-929701000-123200pÅX>ÛaQ,™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-123200 1250949070/10000191p|AX< žTÉ™&IDMAP/GID2SID/10000190 1250949070/S-1-5-21-1834383793-1770918451-929701000-45011BpßX=ŠÙr™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-45011 1250949070/10000190Bp,$X<]=sž™&IDMAP/GID2SID/10000189 1250949070/S-1-5-21-1834383793-1770918451-929701000-90536BpÀX=bs™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90536 1250949070/10000189Bpð7X=]gÖ™&IDMAP/GID2SID/10000188 1250949070/S-1-5-21-1834383793-1770918451-929701000-122058p8õX>z¸ç™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122058 1250949070/10000188pX=]‘9…™&IDMAP/GID2SID/10000187 1250949070/S-1-5-21-2140803266-1626024873-1299147156-23996pÈÛX>¾b±š™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-23996 1250949070/10000187pX;]»œø™&IDMAP/GID2SID/10000186 1250949070/S-1-5-21-4186143834-2626045635-1021053583-519BBpx”X<ÚS8Å™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-519 1250949070/10000186BBpø’X<]åÿk™&IDMAP/GID2SID/10000185 1250949070/S-1-5-21-4186143834-2626045635-1021053583-1651Bp€¦X=Ï6¯ ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1651 1250949070/10000185Bp8ÏX<]cß™&IDMAP/GID2SID/10000184 1250949070/S-1-5-21-4186143834-2626045635-1021053583-7620BplÙX=KT¾ç™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7620 1250949070/10000184BpØ“X;]9ÆR™&IDMAP/GID2SID/10000183 1250949070/S-1-5-21-4186143834-2626045635-1021053583-513BBpІX<Òù š™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-513 1250949070/10000183BBpÆX<}⎙&IDMAP/UID2SID/10000063 1250949070/S-1-5-21-4186143834-2626045635-1021053583-1183BpDÁX=;vÊE™&IDMAP/SID2UID/S-1-5-21-4186143834-2626045635-1021053583-1183 1250949070/10000063BppRP,¾}8•™&SAF/DOMAIN/MTVNE.AD.VIACOM.COM 1251229469/NEW-BRDC01.mtvne.ad.viacom.comh@…D,Ugaô™&SAF/DOMAIN/MTVNE 1251229469/NEW-BRDC01.mtvne.ad.viacom.com:0\¨²D'}Rª™&SAF/DOMAIN/AD.VIACOM.COM 1251229419/musselbeach.ad.viacom.com\|ãD"0({x™&NBT/UNITYNYAD01.IPT.VIACOM.COM#20 1250705340/172.21.200.27:0B\ÔÇX=}6U™&IDMAP/UID2SID/10000061 1245280903/S-1-5-21-1834383793-1770918451-929701000-148440p°©X>›Ò7Ê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148440 1245280903/10000061p0.X=­Ô7Ü™&IDMAP/GID2SID/10000176 1250795400/S-1-5-21-1834383793-1770918451-929701000-148426pì3X>3`ðý™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148426 1250795400/10000176pœ2X=­þšO™&IDMAP/GID2SID/10000175 1251822591/S-1-5-21-1834383793-1770918451-929701000-148427phóX>3×b™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148427 1251822591/10000175p rX=­Ra6™&IDMAP/GID2SID/10000173 1251823334/S-1-5-21-1834383793-1770918451-929701000-107054p@¢X>º'º™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107054 1251823334/10000173p\‚X=­|Ä©™&IDMAP/GID2SID/10000172 1251823334/S-1-5-21-2140803266-1626024873-1299147156-20439pdÇX>bÜê™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20439 1251823334/10000172pÜ>X<­¦'™&IDMAP/GID2SID/10000171 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7668Bp¸X=ûæ\™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7668 1251822594/10000171Bpœ9X<­ÐŠ™&IDMAP/GID2SID/10000170 1251823334/S-1-5-21-4186143834-2626045635-1021053583-7638BpàX=÷9™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7638 1251823334/10000170Bpœ@X=ýo©e™&IDMAP/GID2SID/10000169 1251823334/S-1-5-21-1834383793-1770918451-929701000-117589plEX>ßêΙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-117589 1251823334/10000169p |X<ý™ Ù™&IDMAP/GID2SID/10000168 1251823334/S-1-5-21-1834383793-1770918451-929701000-90130BpˆMX=bχ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90130 1251823334/10000168Bp\BX=ýÃoL™&IDMAP/GID2SID/10000167 1251823334/S-1-5-21-1834383793-1770918451-929701000-102786pUX>7N;\™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-102786 1251823334/10000167ptÊX=ýíÒ¿™&IDMAP/GID2SID/10000166 1251823334/S-1-5-21-1834383793-1770918451-929701000-117590p´X>_ð%™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-117590 1251823334/10000166pDX<ý63™&IDMAP/GID2SID/10000165 1251823334/S-1-5-21-1834383793-1770918451-929701000-23125BpX€X=69Ìy™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-23125 1251823334/10000165Bp‰X<}`¸t™&IDMAP/UID2SID/10000060 1251823334/S-1-5-21-1834383793-1770918451-929701000-32616BpÀ¥X=r´# ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-32616 1251823334/10000060pˆƒD-úÊVd™&SAF/DOMAIN/NETDEV 1251229765/NETDEVROOTDC1.netdev.viacom.como\€X2U®ì™&NBT/PARAMOUNT.AD.VIACOM.COM#1C 1251229229/166.77.172.94:389,166.77.172.108:389-Bpl0L!ã§ ™&NBT/VIACOM_CORP.AD.VIACOM.COM#1C 1244247425/166.77.86.15:389com.comCdЯT+#fIÇ™&AD_SITENAME/DOMAIN/PARAMOUNT.AD.VIACOM.COM 4294967295/US-California-Burbank9:l¸›D#Ö«²5™&AD_SITENAME/DOMAIN/PARAMOUNT 4294967295/US-California-Burbank\À}áS«fæþÙNBT/MTVNE.AD.VIACOM.COM#4@©X32e½™&NBT/MTVNASIA.AD.VIACOM.COM#1C 1251229229/166.77.172.140:389,166.77.172.115:389ompÈkX#1ÿ2™¬™&SAF/DOMAIN/PARAMOUNT.AD.VIACOM.COM 1251229469/bubblebuddy.paramount.ad.viacom.compÍT(ïÓ ÷™&NBT/SQUILLIAM.MTVNASIA.AD.VIACOM.COM#20 1251229216/166.77.172.140:0acom.coml8¤T(‹£Ï×™&NBT/MISSTUFTSY.HOSTING.AD.VIACOM.COM#20 1251229217/166.77.173.152:0com.com1lT*#÷6½™&AD_SITENAME/DOMAIN/MTVNASIA.AD.VIACOM.COM 4294967295/US-California-Burbank9.2l°°D#í3à™&AD_SITENAME/DOMAIN/MTVNASIA 4294967295/US-California-Burbank\`¨0e÷ê™&IDMAP/SID2GID/S-1-5-32-546 1251227603/-1BHмL-xÄ¡™&SAF/DOMAIN/MTVN 1251234708/perchperkins.mtvn.ad.viacom.com.128:0mBBdXX=í·Íš™&IDMAP/GID2SID/10000533 1249523687/S-1-5-21-2140803266-1626024873-1299147156-34227pìñX>Š ³™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34227 1249523687/10000533phNX=íá0™&IDMAP/GID2SID/10000532 1249523687/S-1-5-21-2140803266-1626024873-1299147156-37778pP X>fäè™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-37778 1249523687/10000532ppX=í ”™&IDMAP/GID2SID/10000531 1249523687/S-1-5-21-2140803266-1626024873-1299147156-19855pÝX>£é#™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-19855 1249523687/10000531p¬×X=í5÷ô™&IDMAP/GID2SID/10000530 1249523687/S-1-5-21-2140803266-1626024873-1299147156-34231pìãX> _9™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34231 1249523687/10000530pøX==ÕÊ™&IDMAP/GID2SID/10000529 1249523687/S-1-5-21-2140803266-1626024873-1299147156-34228pýX>Џ†™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34228 1249523687/10000529p(X==ÿx=™&IDMAP/GID2SID/10000528 1249523686/S-1-5-21-2140803266-1626024873-1299147156-34229plîX>Šhm}™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34229 1249523686/10000528p°X==)ܰ™&IDMAP/GID2SID/10000527 1249523686/S-1-5-21-2140803266-1626024873-1299147156-34230pÈdX> nxÔ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34230 1249523686/10000527p<×X==S?$™&IDMAP/GID2SID/10000526 1249523685/S-1-5-21-1834383793-1770918451-929701000-136405pTÄX>3Eé™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136405 1249523685/10000526p,éX=B÷^™&IDMAP/GID2SID/10000417 1249523685/S-1-5-21-1834383793-1770918451-929701000-160163p ãX>/ycx™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-160163 1249523685/10000417p<åX==}¢—™&IDMAP/GID2SID/10000525 1249523685/S-1-5-21-1834383793-1770918451-929701000-136403pXÍX>3å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136403 1249523685/10000525pÀ5X==§ ™&IDMAP/GID2SID/10000524 1250949070/S-1-5-21-1834383793-1770918451-929701000-136402p,X>35ܺ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136402 1250949070/10000524pÜîX==Ñh~™&IDMAP/GID2SID/10000523 1249523685/S-1-5-21-1834383793-1770918451-929701000-136406pX>3õvN™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136406 1249523685/10000523p¸ÑX<=ûËñ™&IDMAP/GID2SID/10000522 1249523684/S-1-5-21-1834383793-1770918451-929701000-64158Bp¸íX=ºæÅP™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64158 1249523684/10000522BpˆFX==%/e™&IDMAP/GID2SID/10000521 1249523684/S-1-5-21-1834383793-1770918451-929701000-136394püíX>=ñy™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136394 1249523684/10000521pˆ‰X==O’Ø™&IDMAP/GID2SID/10000520 1249523684/S-1-5-21-1834383793-1770918451-929701000-136295p\äX>[³¾×™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136295 1249523684/10000520päX=–½E™&IDMAP/GID2SID/10000415 1249523684/S-1-5-21-1834383793-1770918451-929701000-136410pìHX>³ 6Ô™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136410 1249523684/10000415ppX=î°­™&IDMAP/GID2SID/10000519 1249523684/S-1-5-21-1834383793-1770918451-929701000-136296ppX>[c¥<™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136296 1249523684/10000519p|êX=êƒ,™&IDMAP/GID2SID/10000413 1249523684/S-1-5-21-1834383793-1770918451-929701000-136409p°ÿX>3+}™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136409 1249523684/10000413pxqX<!™&IDMAP/GID2SID/10000518 1249523684/S-1-5-21-1834383793-1770918451-929701000-90338Bp°X=b{;™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90338 1249523684/10000518BpÈ/X=Bw”™&IDMAP/GID2SID/10000517 1249523684/S-1-5-21-1834383793-1770918451-929701000-136404pAX>3•©„™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136404 1249523684/10000517p¼ïX=lÚ™&IDMAP/GID2SID/10000516 1249523683/S-1-5-21-1834383793-1770918451-929701000-143490p€ýX>³¶ºÓ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143490 1249523683/10000516pÐ*X=–={™&IDMAP/GID2SID/10000515 1250949070/S-1-5-21-1834383793-1770918451-929701000-136401p¬X>3…õU™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136401 1250949070/10000515pxáX=À î™&IDMAP/GID2SID/10000514 1249523683/S-1-5-21-1834383793-1770918451-929701000-140136pÐþX>¯èË`™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140136 1249523683/10000514p8lX=êb™&IDMAP/GID2SID/10000513 1249523683/S-1-5-21-1834383793-1770918451-929701000-128030pØNX>tÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128030 1249523683/10000513p0X=gÕ™&IDMAP/GID2SID/10000512 1249523683/S-1-5-21-1834383793-1770918451-929701000-116610pÔûX> ~’E™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116610 1249523683/10000512pp-X=>ÊH™&IDMAP/GID2SID/10000511 1249523683/S-1-5-21-1834383793-1770918451-929701000-128031pð X>?[/™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128031 1249523683/10000511pHX=h-¼™&IDMAP/GID2SID/10000510 1249523682/S-1-5-21-1834383793-1770918451-929701000-127548pH,X>ßdï*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127548 1249523682/10000510pX=ÝL‘™&IDMAP/GID2SID/10000509 1249523682/S-1-5-21-1834383793-1770918451-929701000-140137ppIX>¯˜²Å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140137 1249523682/10000509pðX<Ý1¯™&IDMAP/GID2SID/10000508 1249523682/S-1-5-21-1834383793-1770918451-929701000-56310BpèxX= üI ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56310 1249523682/10000508BpÐX=Ý[x™&IDMAP/GID2SID/10000507 1249523682/S-1-5-21-1834383793-1770918451-929701000-127549p<óX>ßÖ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127549 1249523682/10000507p¨zX=Ý…uë™&IDMAP/GID2SID/10000506 1249523682/S-1-5-21-1834383793-1770918451-929701000-119975p8ñX>Üj™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119975 1249523682/10000506pà X=ݯØ^™&IDMAP/GID2SID/10000505 1249523682/S-1-5-21-1834383793-1770918451-929701000-105139ph÷X>¯ø³X™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-105139 1249523682/10000505p¨ÀX<ÝÙ;Ò™&IDMAP/GID2SID/10000504 1249523681/S-1-5-21-1834383793-1770918451-929701000-57905Bp¸ßX=ÞÍŸ§™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-57905 1249523681/10000504BpئX=ÝŸE™&IDMAP/GID2SID/10000503 1249523681/S-1-5-21-1834383793-1770918451-929701000-116608pØ@X>‹È ‰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116608 1249523681/10000503pœðX=Ý-¹™&IDMAP/GID2SID/10000502 1249523681/S-1-5-21-1834383793-1770918451-929701000-119974pè†X>,„©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119974 1249523681/10000502pˆöX=ÝWe,™&IDMAP/GID2SID/10000501 1249523681/S-1-5-21-1834383793-1770918451-929701000-140124pð)X>/S׳™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140124 1249523681/10000501p°X<Á~›™&IDMAP/UID2SID/10000345 1249523680/S-1-5-21-1834383793-1770918451-929701000-64298BpøÁX=Òôë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-64298 1249523680/10000345BpáX=Ýٻƙ&IDMAP/UID2SID/10000082 1251221751/S-1-5-21-1834383793-1770918451-929701000-129642pPÇX>ó¥ÁÒ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129642 1251221751/10000082pX=]Ò$C™&IDMAP/UID2SID/10000307 1250630963/S-1-5-21-1834383793-1770918451-929701000-105272pFX>Ã_|™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-105272 1250630963/10000307pHíX=-÷a™&IDMAP/UID2SID/10000278 1249520768/S-1-5-21-1834383793-1770918451-929701000-129577p(ùX>Ç|Ÿm™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129577 1249520768/10000278pPZ$Ö]­™&IDMAP/GID2SID/99 1251227602/-<ØåX=M1Q·™&IDMAP/GID2SID/10000455 1251825059/S-1-5-21-2140803266-1626024873-1299147156-32221pPˆX>Šèw»™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-32221 1251825059/10000455pX<M[´*™&IDMAP/GID2SID/10000454 1250200846/S-1-5-21-1834383793-1770918451-929701000-61975Bp¨ÜX=’¹A5™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-61975 1250200846/10000454BpìùX=M…ž™&IDMAP/GID2SID/10000453 1250200846/S-1-5-21-1834383793-1770918451-929701000-126290p¸ÃX>[CÒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126290 1250200846/10000453pØÂX<h­†™&IDMAP/GID2SID/10000410 1251837380/S-1-5-21-1834383793-1770918451-929701000-80133BpˆÖX=â þ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-80133 1251837380/10000410BpPX<M¯z™&IDMAP/GID2SID/10000452 1250200846/S-1-5-21-1834383793-1770918451-929701000-31583BplçX=>€2©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-31583 1250200846/10000452BpÐX<MÙÝ„™&IDMAP/GID2SID/10000451 1251826461/S-1-5-21-1834383793-1770918451-929701000-95336Bpl>X=bÊü™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-95336 1251826461/10000451Bp(IH 6ù^ð™&TDOM/HOSTING 1250633849/S-1-5-21-656259101-2991933430-3416489241B`L74ðÙé™&TDOM/PARAMOUNT 1250633849/S-1-5-21-3692268541-1264201430-3503654325BBdÐ1H3³¡íÅ™&TDOM/HARMONIX 1250633849/S-1-5-21-73586283-776561741-725345543BBB`xÚH 7Ê•{á™&TDOM/MTVNE 1250633849/S-1-5-21-2106152344-1726899929-2013803672BB`L7}Þ]µ™&TDOM/MTVNASIA 1250633849/S-1-5-21-1736519922-1920428879-1691616715BBBdÐFH6ÿرG™&TDOM/PLAYASUR 1250633849/S-1-5-21-2129485696-1739684832-945835055` üL7ªÒ~™&TDOM/VIACOM_CORP 1250633849/S-1-5-21-2140803266-1626024873-1299147156d@ND7S[ý™&TDOM/AD 1250633849/S-1-5-21-4186143834-2626045635-1021053583B\P5X=>J¨™&IDMAP/GID2SID/10000211 1249517309/S-1-5-21-1834383793-1770918451-929701000-107951p˜4X>±VË™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107951 1249517309/10000211pX=m†S˜™&IDMAP/UID2SID/10000337 1249517309/S-1-5-21-1834383793-1770918451-929701000-119188p°$X>—{ÝJ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119188 1249517309/10000337pèJX=m\ð$™&IDMAP/UID2SID/10000338 1249517309/S-1-5-21-1834383793-1770918451-929701000-119107p4X>—½Ì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119107 1249517309/10000338p°9X=ëá™&IDMAP/UID2SID/10000344 1249435951/S-1-5-21-1834383793-1770918451-929701000-148518pØ×X>ÇëO™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148518 1249435951/10000344p"X=E‚™&IDMAP/UID2SID/10000343 1250273007/S-1-5-21-1834383793-1770918451-929701000-148361p¾X>ï³Sî™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148361 1250273007/10000343p ºX= Й&IDMAP/UID2SID/10000215 1250725628/S-1-5-21-1834383793-1770918451-929701000-141235pÐ?X>Ù¿3™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141235 1250725628/10000215pð(¦)µS™&IDMAP/UID2SID/25238 1248799054/-B@?X=Í}™&IDMAP/UID2SID/10000256 1250639960/S-1-5-21-1834383793-1770918451-929701000-107870pØÉX>ËY‰™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107870 1250639960/10000256pÐX<mÚ™&IDMAP/UID2SID/10000335 1250016356/S-1-5-21-1834383793-1770918451-929701000-95298BpPÕX=Òü°ƒ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95298 1250016356/10000335BpøX<]~^\™&IDMAP/UID2SID/10000309 1249319817/S-1-5-21-1834383793-1770918451-929701000-79512Bp˜üX=r>á4™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79512 1249319817/10000309Bp8ãX= PF™&IDMAP/UID2SID/10000315 1250546951/S-1-5-21-1834383793-1770918451-929701000-143917p,âX>w"¯™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143917 1250546951/10000315p©X< ¹‰_™&IDMAP/UID2SID/10000317 1251151498/S-1-5-21-1834383793-1770918451-929701000-95238BpðÐX=Ê¢Y™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95238 1251151498/10000317BpùX=m‚¦L™&IDMAP/UID2SID/10000331 1251331910/S-1-5-21-1834383793-1770918451-929701000-148513pÐ’X>Ç{V™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148513 1251331910/10000331pÀ–X=]PN™&IDMAP/UID2SID/10000304 1251824050/S-1-5-21-1834383793-1770918451-929701000-141063p>X>ëf5™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141063 1251824050/10000304pØ$X< ß?‡™&IDMAP/UID2SID/10000310 1250714401/S-1-5-21-1834383793-1770918451-929701000-50388Bp (X=&cø™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-50388 1250714401/10000310Bp¨aX=m¬ À™&IDMAP/UID2SID/10000330 1250878988/S-1-5-21-1834383793-1770918451-929701000-148506p %X>GV¢™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148506 1250878988/10000330p ïX=½›A0™&IDMAP/UID2SID/10000321 1251156944/S-1-5-21-1834383793-1770918451-929701000-143923pÈÍX>÷—;S™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143923 1251156944/10000321pÔX=½K(•™&IDMAP/UID2SID/10000329 1250273129/S-1-5-21-1834383793-1770918451-929701000-148435pOX> ’ß™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148435 1250273129/10000329p@X=M³']™&IDMAP/GID2SID/10000458 1251149354/S-1-5-21-1834383793-1770918451-929701000-129629pŸX>‹ã`k™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129629 1251149354/10000458pðÉX<½u‹™&IDMAP/UID2SID/10000328 1250810099/S-1-5-21-1834383793-1770918451-929701000-87280Bp0¥X=&¿ÀÍ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87280 1250810099/10000328Bpˆ¬X;½Ö™&IDMAP/UID2SID/10000324 1251146424/S-1-5-21-1834383793-1770918451-929701000-1480BBp`X<¡õMd™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1480 1251146424/10000324BBpøëX=]c)1™&IDMAP/GID2SID/10000382 1251157458/S-1-5-21-1834383793-1770918451-929701000-118513pÀ²X>_Tí™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-118513 1251157458/10000382p¨X=]Œ¤™&IDMAP/GID2SID/10000381 1248890662/S-1-5-21-1834383793-1770918451-929701000-129546p˜ËX>ßâû™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129546 1248890662/10000381p ˆX=-u-»™&IDMAP/UID2SID/10000275 1251157458/S-1-5-21-1834383793-1770918451-929701000-119215p(¯X>Ã.0í™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119215 1251157458/10000275p3X=ç4™&IDMAP/UID2SID/10000290 1251141635/S-1-5-21-1834383793-1770918451-929701000-129688pïX>󛯼™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129688 1251141635/10000290p8X=½qÞ¼™&IDMAP/UID2SID/10000322 1251158331/S-1-5-21-1834383793-1770918451-929701000-148511p€X>ÇÂŒ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148511 1251158331/10000322p)X=½Å¤£™&IDMAP/UID2SID/10000320 1248824845/S-1-5-21-1834383793-1770918451-929701000-148375pP X>o©e™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148375 1248824845/10000320pàX=]¤„™&IDMAP/UID2SID/10000302 1251826461/S-1-5-21-1834383793-1770918451-929701000-148494p(ËX>ž–Í™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148494 1251826461/10000302p·X<êƒÁ™&IDMAP/UID2SID/10000291 1250717354/S-1-5-21-1834383793-1770918451-929701000-87529Bp°+X=žFª™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87529 1250717354/10000291BpèX=ÜÛ™&IDMAP/GID2SID/10000440 1251224362/S-1-5-21-1834383793-1770918451-929701000-129604p(¶X>‹‘¬™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129604 1251224362/10000440påX= ãìÒ™&IDMAP/UID2SID/10000316 1250644308/S-1-5-21-1834383793-1770918451-929701000-107715pø™X>Oƒ'™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107715 1250644308/10000316pPãX= &ì™&IDMAP/UID2SID/10000318 1251141808/S-1-5-21-1834383793-1770918451-929701000-107850p€0X>Ëî·Â™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107850 1251141808/10000318p˜çX= ‹y ™&IDMAP/UID2SID/10000312 1248801216/S-1-5-21-1834383793-1770918451-929701000-148504px°X>GöNØ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148504 1248801216/10000312p`FX=òxh™&IDMAP/GID2SID/10000441 1250632968/S-1-5-21-1834383793-1770918451-929701000-143927pxX>0uƒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143927 1250632968/10000441pXRX==ûK¼™&IDMAP/GID2SID/10000422 1251822639/S-1-5-21-1834383793-1770918451-929701000-148502pŒX>ßn «™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148502 1251822639/10000422pÐ#X=B÷ó™&IDMAP/UID2SID/10000295 1250525522/S-1-5-21-1834383793-1770918451-929701000-148311pØ÷X>o¨~™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148311 1250525522/10000295pøòX=½ó´÷™&IDMAP/UID2SID/10000125 1251141450/S-1-5-21-1834383793-1770918451-929701000-129580pРX>GâwŽ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129580 1251141450/10000125pxèX= µÜ™&IDMAP/UID2SID/10000311 1249660297/S-1-5-21-1834383793-1770918451-929701000-148288pŒØX>Cµ×o™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148288 1249660297/10000311pHvX= 7³¹™&IDMAP/UID2SID/10000314 1250637001/S-1-5-21-1834383793-1770918451-929701000-148454p@ËX>Èù@™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148454 1250637001/10000314pÐ8X=ÍÑÆõ™&IDMAP/UID2SID/10000254 1250697509/S-1-5-21-1834383793-1770918451-929701000-107733p¨ZX>Z$™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107733 1250697509/10000254p 3X< a-™&IDMAP/UID2SID/10000313 1250708830/S-1-5-21-1834383793-1770918451-929701000-87285Bp°2X=¦Ê„=™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87285 1250708830/10000313BptX=ݯX¾™&IDMAP/UID2SID/10000283 1251152830/S-1-5-21-1834383793-1770918451-929701000-148134pH§X>°_e™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148134 1251152830/10000283p :X=ÝÙ»1™&IDMAP/UID2SID/10000282 1251152830/S-1-5-21-1834383793-1770918451-929701000-148232p¸oX>É«¢™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148232 1251152830/10000282pà¿X=Íû)i™&IDMAP/UID2SID/10000253 1250817897/S-1-5-21-1834383793-1770918451-929701000-148133pX>y™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148133 1250817897/10000253p˜ X=Í%Ü™&IDMAP/UID2SID/10000252 1250905890/S-1-5-21-1834383793-1770918451-929701000-148467p¸X>› ÕR™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148467 1250905890/10000252pÏX=-KÊG™&IDMAP/UID2SID/10000276 1250642444/S-1-5-21-1834383793-1770918451-929701000-148405p(çX>›l6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148405 1250642444/10000276p8SX=]¤”N™&IDMAP/UID2SID/10000202 1249922180/S-1-5-21-1834383793-1770918451-929701000-143764p°X>ŸªŒ6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143764 1249922180/10000202p(pX=}æ»›™&IDMAP/UID2SID/10000169 1250872003/S-1-5-21-1834383793-1770918451-929701000-143826pPX>KnÖz™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143826 1250872003/10000169pèèX=-Ÿ.™&IDMAP/UID2SID/10000274 1250720448/S-1-5-21-1834383793-1770918451-929701000-143924pÈéX>÷G"¸™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143924 1250720448/10000274pÈ`X<=ÑèH™&IDMAP/GID2SID/10000423 1251824032/S-1-5-21-1834383793-1770918451-929701000-95355Bpˆ[X=:NÕ'™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-95355 1251824032/10000423Bp 6X==ÿø™&IDMAP/GID2SID/10000428 1250282972/S-1-5-21-2140803266-1626024873-1299147156-31601p áX>:d.D™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31601 1250282972/10000428pxX<=)\{™&IDMAP/GID2SID/10000427 1250282972/S-1-5-21-1834383793-1770918451-929701000-42569Bp X=æ¥Én™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42569 1250282972/10000427Bp@9X<=S¿î™&IDMAP/GID2SID/10000426 1250282972/S-1-5-21-1834383793-1770918451-929701000-42575Bp0X=’ Fé™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42575 1250282972/10000426Bpp4X==}"b™&IDMAP/GID2SID/10000425 1251156944/S-1-5-21-1834383793-1770918451-929701000-148356p ›X>ÇL ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148356 1251156944/10000425p°@X==§…Õ™&IDMAP/GID2SID/10000424 1250282972/S-1-5-21-1834383793-1770918451-929701000-129729püæX>7zr™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129729 1250282972/10000424p€7X<]ü‡¶™&IDMAP/UID2SID/10000306 1250282972/S-1-5-21-1834383793-1770918451-929701000-25076BpœâX=z¶H³™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-25076 1250282972/10000306Bp¸OX=]&ë)™&IDMAP/UID2SID/10000305 1250282972/S-1-5-21-1834383793-1770918451-929701000-143919p°X>w‚|Í™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143919 1250282972/10000305pØUX=lZg™&IDMAP/UID2SID/10000294 1250790522/S-1-5-21-1834383793-1770918451-929701000-143654ppâX>s;LL™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143654 1250790522/10000294pøtX=ÍyÓ™&IDMAP/UID2SID/10000150 1250873129/S-1-5-21-1834383793-1770918451-929701000-107732p(îX>ª¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107732 1250873129/10000150p¸ØX=m†Ób™&IDMAP/UID2SID/10000237 1250883037/S-1-5-21-1834383793-1770918451-929701000-143858p(œX>Ënî™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143858 1250883037/10000237p˜ÙX=m°6Ö™&IDMAP/UID2SID/10000236 1250883036/S-1-5-21-1834383793-1770918451-929701000-143884p ¾X>KOô™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143884 1250883036/10000236pˆX<?¨Š™&IDMAP/UID2SID/10000142 1250723949/S-1-5-21-1834383793-1770918451-929701000-79422Bp:X=xšn™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79422 1250723949/10000142Bp¨¤X=E™&IDMAP/UID2SID/10000143 1251133100/S-1-5-21-1834383793-1770918451-929701000-129687p˜…X>óëßW™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129687 1251133100/10000143p¨X=]Îw÷™&IDMAP/UID2SID/10000301 1251824032/S-1-5-21-1834383793-1770918451-929701000-108847pàŽX>K‰?o™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-108847 1251824032/10000301p AX; ¢€™&IDMAP/GID2SID/10000396 1248213312/S-1-5-21-4186143834-2626045635-1021053583-515BBp˜àX<*mÓ¨™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-515 1248213312/10000396BBpØšX<šj&™&IDMAP/UID2SID/10000299 1248213312/S-1-5-21-4186143834-2626045635-1021053583-1251Bp7X=7^7™&IDMAP/SID2UID/S-1-5-21-4186143834-2626045635-1021053583-1251 1248213312/10000299BpøfX= Ìdó™&IDMAP/GID2SID/10000395 1248213312/S-1-5-21-2140803266-1626024873-1299147156-25446px'X>â6/¢™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25446 1248213312/10000395pøÝX= öÇf™&IDMAP/GID2SID/10000394 1248213312/S-1-5-21-1834383793-1770918451-929701000-122075p8EX>ÕR™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122075 1248213312/10000394px·X< +Ú™&IDMAP/GID2SID/10000393 1248213312/S-1-5-21-1834383793-1770918451-929701000-68183BpH}X=>ˆù/™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68183 1248213312/10000393Bpà;X= JŽM™&IDMAP/GID2SID/10000392 1248213311/S-1-5-21-1834383793-1770918451-929701000-122068pøX>ƒ¯ßÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122068 1248213311/10000392p˜^X< tñÀ™&IDMAP/GID2SID/10000391 1248213311/S-1-5-21-4186143834-2626045635-1021053583-1647BpXéX=#>U™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1647 1248213311/10000391Bpø?X< žT4™&IDMAP/GID2SID/10000390 1248213311/S-1-5-21-4186143834-2626045635-1021053583-1211Bpp;X=PÊ·™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1211 1248213311/10000390BpøäX<]=s ™&IDMAP/GID2SID/10000389 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1246BpðNX=£Ú<™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1246 1251822594/10000389BpäX<]gÖ|™&IDMAP/GID2SID/10000388 1248213311/S-1-5-21-4186143834-2626045635-1021053583-1245Bp›X=#Ó²Y™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1245 1248213311/10000388BpxÅX<]‘9ð™&IDMAP/GID2SID/10000387 1248213311/S-1-5-21-4186143834-2626045635-1021053583-7625BppBX=Ë_‚W™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7625 1248213311/10000387Bp8ÎX<]»œc™&IDMAP/GID2SID/10000386 1248213310/S-1-5-21-4186143834-2626045635-1021053583-1194Bp0»X=ÿ½©Ì™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1194 1248213310/10000386BpØcX<]åÿÖ™&IDMAP/GID2SID/10000385 1248213310/S-1-5-21-4186143834-2626045635-1021053583-1255BpXYX=Ï Ì`™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1255 1248213310/10000385BpPJX<]cJ™&IDMAP/GID2SID/10000384 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1247BpðhX=#> ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1247 1251822594/10000384BpˆžX<]9ƽ™&IDMAP/GID2SID/10000383 1248213305/S-1-5-21-4186143834-2626045635-1021053583-7619Bp°NX=üÝ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7619 1248213305/10000383Bp80X<ÄÍ™™&IDMAP/UID2SID/10000298 1248213305/S-1-5-21-4186143834-2626045635-1021053583-1662Bpè”X=cÍPW™&IDMAP/SID2UID/S-1-5-21-4186143834-2626045635-1021053583-1662 1248213305/10000298BpðµX=-Í ¸™&IDMAP/UID2SID/10000179 1250898780/S-1-5-21-1834383793-1770918451-929701000-143653pÈžX>s‹eç™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143653 1250898780/10000179p8X=Ý1/d™&IDMAP/UID2SID/10000286 1249607338/S-1-5-21-1834383793-1770918451-929701000-143682pÌÝX>ó{ô+™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143682 1249607338/10000286pXDX=]·ï™&IDMAP/GID2SID/10000380 1249576851/S-1-5-21-1834383793-1770918451-929701000-113649pÀêX>‹N™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113649 1249576851/10000380pEX=­Ví™&IDMAP/GID2SID/10000379 1249576851/S-1-5-21-1834383793-1770918451-929701000-126724p¼ÓX>7­Ø™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126724 1249576851/10000379pø8X<-Éó¡™&IDMAP/UID2SID/10000273 1249576851/S-1-5-21-1834383793-1770918451-929701000-87132BpœéX=Ê 1£™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87132 1249576851/10000273BpxÓX=-óV™&IDMAP/UID2SID/10000272 1249576851/S-1-5-21-1834383793-1770918451-929701000-143734pŒÑX> ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143734 1249576851/10000272pøÈX= eà ™&IDMAP/UID2SID/10000119 1251141204/S-1-5-21-1834383793-1770918451-929701000-148269pÈ—X>Cúo™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148269 1251141204/10000119p8"X<}ŸD™&IDMAP/UID2SID/10000268 1251332584/S-1-5-21-1834383793-1770918451-929701000-95887BpÀJX=¦°i™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95887 1251332584/10000268BpèX<–½Ú™&IDMAP/UID2SID/10000293 1251218467/S-1-5-21-1834383793-1770918451-929701000-56083Bp¬5X=¦W±ö™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-56083 1251218467/10000293Bp(“X=À N™&IDMAP/UID2SID/10000292 1251218467/S-1-5-21-1834383793-1770918451-929701000-148487péX>›x#™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148487 1251218467/10000292pØÐX=Í}€Ù™&IDMAP/UID2SID/10000156 1251130673/S-1-5-21-1834383793-1770918451-929701000-119384pàœX>ï.uÅ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119384 1251130673/10000156pèX=}:¸™&IDMAP/UID2SID/10000267 1250527000/S-1-5-21-1834383793-1770918451-929701000-107719p°ÒX>»™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107719 1250527000/10000267p´ÈX=­ÐŠû™&IDMAP/GID2SID/10000370 1250637001/S-1-5-21-1834383793-1770918451-929701000-148229pLÚX>Ûüq™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148229 1250637001/10000370pX¸X=ͧc‚™&IDMAP/UID2SID/10000255 1251221622/S-1-5-21-1834383793-1770918451-929701000-118468pàX>›½zÌ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-118468 1251221622/10000255pøX=ݳ ™&IDMAP/UID2SID/10000289 1248110172/S-1-5-21-1834383793-1770918451-929701000-128816p¸ÊX>Ë8¹ý™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-128816 1248110172/10000289pX=X=Í):(™&IDMAP/UID2SID/10000258 1251218400/S-1-5-21-1834383793-1770918451-929701000-148496p{X>þc—™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148496 1251218400/10000258p87X=ÝÝh}™&IDMAP/UID2SID/10000288 1250873479/S-1-5-21-1834383793-1770918451-929701000-107559pD+ø+fæþÙBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,à‡X=î0N™&IDMAP/GID2SID/10000819 1251836362/S-1-5-21-1834383793-1770918451-929701000-141393p¸3X>•`™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-141393 1251836362/10000819p0`X=½›Áe™&IDMAP/UID2SID/10000421 1251836362/S-1-5-21-1834383793-1770918451-929701000-146636p ©X=}æ;Ñ™&IDMAP/UID2SID/10000269 1251826461/S-1-5-21-1834383793-1770918451-929701000-119073p€µX<½Å$Ù™&IDMAP/UID2SID/10000420 1251826461/S-1-5-21-1834383793-1770918451-929701000-45487Bp`‹X=¦Õï7™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-45487 1251826461/10000420Bp`¡X=ÝÌ1™&IDMAP/GID2SID/10000809 1251825059/S-1-5-21-2140803266-1626024873-1299147156-33834p X>ˆJÅ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-33834 1251825059/10000809p X=Ý1/¥™&IDMAP/GID2SID/10000808 1251825059/S-1-5-21-2140803266-1626024873-1299147156-37682pˆX>:ÀŽ’™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-37682 1251825059/10000808ppeX<Ý[’™&IDMAP/GID2SID/10000807 1251825059/S-1-5-21-1834383793-1770918451-929701000-56883BpÈÔX=>0Pþ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56883 1251825059/10000807BpЋX<Ý…õ‹™&IDMAP/GID2SID/10000806 1251825058/S-1-5-21-1834383793-1770918451-929701000-56882Bp ‰X=¾ú(™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56882 1251825058/10000806Bp ±X<ݯXÿ™&IDMAP/GID2SID/10000805 1251825058/S-1-5-21-1834383793-1770918451-929701000-56884BpÃX=¾ewá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56884 1251825058/10000805Bp؃X<ÝÙ»r™&IDMAP/GID2SID/10000804 1251825058/S-1-5-21-1834383793-1770918451-929701000-88296Bp X=jÏ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-88296 1251825058/10000804BpÈ•X; eC®™&IDMAP/UID2SID/10000419 1251825058/S-1-5-21-1834383793-1770918451-929701000-9105BBp êX=Ý-‚Y™&IDMAP/GID2SID/10000802 1251824351/S-1-5-21-2140803266-1626024873-1299147156-13928pÈ(X>>Là™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-13928 1251824351/10000802p”X=ÝWåÌ™&IDMAP/GID2SID/10000801 1251824350/S-1-5-21-2140803266-1626024873-1299147156-24501pˆÏX>Ž*ÊV™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24501 1251824350/10000801pè X=ÝH@™&IDMAP/GID2SID/10000800 1251824350/S-1-5-21-2140803266-1626024873-1299147156-20408pàIX>âÀÜ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20408 1251824350/10000800pPSX= $Øû™&IDMAP/GID2SID/10000799 1251824350/S-1-5-21-2140803266-1626024873-1299147156-15905pØGX>>Ѿ…™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-15905 1251824350/10000799p¤ÅX; ¦!™&IDMAP/UID2SID/10000418 1251824350/S-1-5-21-1834383793-1770918451-929701000-1428BBpfX<Ã×Ì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1428 1251824350/10000418BBpðŠX==§ ™&IDMAP/GID2SID/10000324 1251823992/S-1-5-21-2140803266-1626024873-1299147156-19915p¨˜X>¾fž™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-19915 1251823992/10000324p˜¿X==%/ú™&IDMAP/GID2SID/10000321 1251823992/S-1-5-21-2140803266-1626024873-1299147156-22860p HX>’hZ¿™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-22860 1251823992/10000321p€X= xžâ™&IDMAP/GID2SID/10000797 1251823992/S-1-5-21-2140803266-1626024873-1299147156-25508p¨ãX>Žúxæ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25508 1251823992/10000797pÀX<=ÿxÒ™&IDMAP/GID2SID/10000328 1251823992/S-1-5-21-4186143834-2626045635-1021053583-7657Bpˆ'X=Ïw3™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7657 1251823992/10000328Bp ªX==)ÜE™&IDMAP/GID2SID/10000327 1251823992/S-1-5-21-1834383793-1770918451-929701000-105930p »X>–a™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-105930 1251823992/10000327p€§X< ¹ •™&IDMAP/UID2SID/10000417 1251823991/S-1-5-21-1834383793-1770918451-929701000-44651Bp¹X=¢ç ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-44651 1251823991/10000417Bp ¦X< ÌdÉ™&IDMAP/GID2SID/10000795 1251823775/S-1-5-21-1834383793-1770918451-929701000-43407Bp¥X=Þàîþ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43407 1251823775/10000795BpØnX< öÇ<™&IDMAP/GID2SID/10000794 1251823775/S-1-5-21-1834383793-1770918451-929701000-86979BpèX=’?Ü®™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-86979 1251823775/10000794Bp0TX= +°™&IDMAP/GID2SID/10000793 1251823775/S-1-5-21-1834383793-1770918451-929701000-156559pQX>_JÞ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-156559 1251823775/10000793pLFX< ãl™&IDMAP/UID2SID/10000416 1251823775/S-1-5-21-1834383793-1770918451-929701000-52123Bp ÏX=žýÍ_™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-52123 1251823775/10000416Bp;X< Ð{™&IDMAP/UID2SID/10000415 1251823756/S-1-5-21-1834383793-1770918451-929701000-56596BpˆTX=M…—>™&IDMAP/GID2SID/10000753 1251836362/S-1-5-21-1834383793-1770918451-929701000-161746p ‚X>7xÀØ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-161746 1251836362/10000753pp•X=¶™&IDMAP/UID2SID/10000396 1251227786/S-1-5-21-1834383793-1770918451-929701000-162831pÚX>Ë3ò4™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162831 1251227786/10000396p<¿X=]øZ ™&IDMAP/UID2SID/10000400 1251221604/S-1-5-21-1834383793-1770918451-929701000-162836pÀ.X>Ë£s-™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162836 1251221604/10000400pØ+X=—(™&IDMAP/UID2SID/10000346 1251217829/S-1-5-21-1834383793-1770918451-929701000-148520pȱX>G¡ ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148520 1251217829/10000346pBX=ÝÙ;=™&IDMAP/GID2SID/10000704 1251823334/S-1-5-21-1834383793-1770918451-929701000-164366pà²X>‡üÉê™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-164366 1251823334/10000704pèÌX<î°B™&IDMAP/UID2SID/10000397 1251148929/S-1-5-21-1834383793-1770918451-929701000-87035Bpˆ*X=JªF™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87035 1251148929/10000397Bp@X= 73„™&IDMAP/UID2SID/10000214 1251132082/S-1-5-21-1834383793-1770918451-929701000-143829p–X>K~Š©™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143829 1251132082/10000214pÀÕX<Bw)™&IDMAP/UID2SID/10000395 1251131643/S-1-5-21-1834383793-1770918451-929701000-50238Bp@¯X=ÊB5™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-50238 1251131643/10000395Bp8zX=lÚœ™&IDMAP/UID2SID/10000394 1250901558/S-1-5-21-1834383793-1770918451-929701000-155079pxxX>k¼¯É™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-155079 1250901558/10000394p‰X=À ƒ™&IDMAP/UID2SID/10000392 1250892461/S-1-5-21-1834383793-1770918451-929701000-162830ppX>˃ Й&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162830 1250892461/10000392p¬!X=í9¤«™&IDMAP/GID2SID/10000736 1250868294/S-1-5-21-1834383793-1770918451-929701000-162201p8ÿX>Û„ý™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-162201 1250868294/10000736pà-X=íj’™&IDMAP/GID2SID/10000734 1250802845/S-1-5-21-1834383793-1770918451-929701000-126298pÐwX>[ø™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126298 1250802845/10000734pÈRX=í·Í™&IDMAP/GID2SID/10000733 1250802845/S-1-5-21-1834383793-1770918451-929701000-126309p ¥X>‡Ë¦'™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126309 1250802845/10000733pè_X=íá0y™&IDMAP/GID2SID/10000732 1250802845/S-1-5-21-1834383793-1770918451-929701000-125539p€ìX>_ßî™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-125539 1250802845/10000732pLX=í ”ì™&IDMAP/GID2SID/10000731 1250802845/S-1-5-21-1834383793-1770918451-929701000-126308pPÀX>‡À™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126308 1250802845/10000731p€åX=í5÷_™&IDMAP/GID2SID/10000730 1250802845/S-1-5-21-1834383793-1770918451-929701000-163450pÌäX>³àóã™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163450 1250802845/10000730pHÑX==Õ5™&IDMAP/GID2SID/10000729 1250802845/S-1-5-21-1834383793-1770918451-929701000-126310pL8X>ѱ~™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126310 1250802845/10000729p€)X==ÿx¨™&IDMAP/GID2SID/10000728 1250802845/S-1-5-21-1834383793-1770918451-929701000-126223pà£X>ÛÜs‰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126223 1250802845/10000728pHßX==)Ü™&IDMAP/GID2SID/10000727 1250802845/S-1-5-21-1834383793-1770918451-929701000-126305pP«X>‡ ”™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126305 1250802845/10000727pÌX==S?™&IDMAP/GID2SID/10000726 1250802845/S-1-5-21-1834383793-1770918451-929701000-126434ppÆX>³5´ß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126434 1250802845/10000726pð0X==}¢™&IDMAP/GID2SID/10000725 1250802845/S-1-5-21-1834383793-1770918451-929701000-163462pÀ¤X>3vè™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163462 1250802845/10000725pÓX<=§v™&IDMAP/GID2SID/10000724 1250802845/S-1-5-21-1834383793-1770918451-929701000-32714Bp0³X= "ÔC™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-32714 1250802845/10000724BphGX<=Ñhé™&IDMAP/GID2SID/10000723 1250802845/S-1-5-21-1834383793-1770918451-929701000-40067Bp0¬X=æ:Å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-40067 1250802845/10000723Bp@X<=ûË\™&IDMAP/GID2SID/10000722 1250802845/S-1-5-21-1834383793-1770918451-929701000-31839Bp°¶X=â ¿@™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-31839 1250802845/10000722Bpˆ—X==%/Й&IDMAP/GID2SID/10000721 1250802845/S-1-5-21-1834383793-1770918451-929701000-112531pX/X>__.4™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112531 1250802845/10000721p ·X<=O’C™&IDMAP/GID2SID/10000720 1250802845/S-1-5-21-1834383793-1770918451-929701000-25192Bp X=j,Ýž™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-25192 1250802845/10000720Bp ³X<î°™&IDMAP/GID2SID/10000719 1250802845/S-1-5-21-1834383793-1770918451-929701000-40068BphìX=fpìë™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-40068 1250802845/10000719BpÈ÷X<Œ™&IDMAP/GID2SID/10000718 1250802845/S-1-5-21-1834383793-1770918451-929701000-40069BplX=æ¥Ï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-40069 1250802845/10000718BphÐX=ÝÝè²™&IDMAP/UID2SID/10000388 1250802845/S-1-5-21-1834383793-1770918451-929701000-117852pð­X>ËNðÚ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-117852 1250802845/10000388pHAX=ÝŸÚ™&IDMAP/UID2SID/10000381 1250789362/S-1-5-21-1834383793-1770918451-929701000-148066pHHX>ëv‰Ñ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148066 1250789362/10000381p0X=ÝŸ°™&IDMAP/GID2SID/10000703 1251823992/S-1-5-21-1834383793-1770918451-929701000-126387p°cX>‡w™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126387 1251823992/10000703pˆëX=Ý-$™&IDMAP/GID2SID/10000702 1251825058/S-1-5-21-1834383793-1770918451-929701000-126428pà«X>3À'™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126428 1251825058/10000702pyX=ÝWe—™&IDMAP/GID2SID/10000701 1250789304/S-1-5-21-1834383793-1770918451-929701000-126437pHOX>³Eh™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126437 1250789304/10000701pH‹X<ÝÈ ™&IDMAP/GID2SID/10000700 1250789304/S-1-5-21-1834383793-1770918451-929701000-36752Bp8–X=º–Ó™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-36752 1250789304/10000700BpÈ=X=Ý[ ™&IDMAP/UID2SID/10000385 1250789303/S-1-5-21-1834383793-1770918451-929701000-107912pH%X>w²™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107912 1250789303/10000385p˜X=MAø™&IDMAP/GID2SID/10000450 1251826461/S-1-5-21-1834383793-1770918451-929701000-113651p`¶X> öΙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113651 1251826461/10000450prX<¢_Í™&IDMAP/GID2SID/10000449 1250727725/S-1-5-21-1834383793-1770918451-929701000-72021BpX=6¥Í™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-72021 1250727725/10000449BpíX<ÌÂ@™&IDMAP/GID2SID/10000448 1250727725/S-1-5-21-1834383793-1770918451-929701000-38288Bp€ X=¾‹ÃÕ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38288 1250727725/10000448BpýX=ö%´™&IDMAP/GID2SID/10000447 1250727725/S-1-5-21-1834383793-1770918451-929701000-129730pèCX>·"…É™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129730 1250727725/10000447plX< ‰'™&IDMAP/GID2SID/10000446 1250727725/S-1-5-21-1834383793-1770918451-929701000-52150Bp\òX=ºâBh™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-52150 1250727725/10000446BpHÊX<Jìš™&IDMAP/GID2SID/10000445 1250727725/S-1-5-21-1834383793-1770918451-929701000-38267Bpp X=æâiä™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38267 1250727725/10000445BpìX<tO™&IDMAP/GID2SID/10000444 1250727725/S-1-5-21-1834383793-1770918451-929701000-72022Bp&X=¶P̰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-72022 1250727725/10000444Bp@ŽX=ݯØó™&IDMAP/UID2SID/10000383 1250727725/S-1-5-21-1834383793-1770918451-929701000-108002pÀX>ëuW±™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-108002 1250727725/10000383p X=ÝÙ;g™&IDMAP/UID2SID/10000382 1250715069/S-1-5-21-1834383793-1770918451-929701000-119502p¨ÕX>G– ð™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119502 1250715069/10000382p¸:X=Ý-N™&IDMAP/UID2SID/10000380 1250713298/S-1-5-21-1834383793-1770918451-929701000-162826pxJX>KnLJ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162826 1250713298/10000380pÀ¹X=-Í #™&IDMAP/UID2SID/10000379 1250708248/S-1-5-21-1834383793-1770918451-929701000-162825p4X>K¾eå™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162825 1250708248/10000379pÐX=-!ç ™&IDMAP/UID2SID/10000377 1250616247/S-1-5-21-1834383793-1770918451-929701000-148175p€ X>6ãV™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148175 1250616247/10000377p¨ÿX=-KJ}™&IDMAP/UID2SID/10000376 1250545067/S-1-5-21-1834383793-1770918451-929701000-119375pä+X>o©4G™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119375 1250545067/10000376p€>X=-u­ð™&IDMAP/UID2SID/10000375 1251138855/S-1-5-21-1834383793-1770918451-929701000-162822p˜X>K®±¶™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162822 1251138855/10000375p ,X=-És×™&IDMAP/UID2SID/10000373 1251147240/S-1-5-21-1834383793-1770918451-929701000-107933p€"X>wÍ62™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107933 1251147240/10000373p ÖX=ͧ㷙&IDMAP/UID2SID/10000355 1250870551/S-1-5-21-1834383793-1770918451-929701000-162815p@ÙX>ˈ>™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162815 1250870551/10000355px<X=-óÖJ™&IDMAP/UID2SID/10000372 1250211480/S-1-5-21-1834383793-1770918451-929701000-162820pÐÑX>KNäì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162820 1250211480/10000372p—X=-G1™&IDMAP/UID2SID/10000370 1250200570/S-1-5-21-1834383793-1770918451-929701000-162819p\ÝX>ËHÙ•™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162819 1250200570/10000370p`1X=}ŽHÔ™&IDMAP/UID2SID/10000365 1250123071/S-1-5-21-1834383793-1770918451-929701000-107826ppÍX>Knªv™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107826 1250123071/10000365pÐíX==S¿Y™&IDMAP/GID2SID/10000626 1251141210/S-1-5-21-1834383793-1770918451-929701000-126435p€ŒX>³åšD™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126435 1251141210/10000626p<ìX==}"Í™&IDMAP/GID2SID/10000625 1251141210/S-1-5-21-1834383793-1770918451-929701000-126439pl#X>³¥5Ø™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126439 1251141210/10000625p¬ÐX<=§…@™&IDMAP/GID2SID/10000624 1251825059/S-1-5-21-1834383793-1770918451-929701000-46326Bp¨«X=¶ÛG™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-46326 1251825059/10000624Bp8X<=Ñè³™&IDMAP/GID2SID/10000623 1251141210/S-1-5-21-1834383793-1770918451-929701000-43571BpÛX=’3«™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43571 1251141210/10000623BplÒX==ûK'™&IDMAP/GID2SID/10000622 1251141210/S-1-5-21-1834383793-1770918451-929701000-126436pèXX>³•©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126436 1251141210/10000622p`æX==%¯š™&IDMAP/GID2SID/10000621 1251141210/S-1-5-21-1834383793-1770918451-929701000-126438p(õX>³õNs™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126438 1251141210/10000621pX==O™&IDMAP/GID2SID/10000620 1251141210/S-1-5-21-1834383793-1770918451-929701000-113227pÀX>Ûœƒf™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113227 1251141210/10000620pÀÜX<î0ã™&IDMAP/GID2SID/10000619 1251141210/S-1-5-21-1834383793-1770918451-929701000-35587Bp°šX=>V{o™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-35587 1251141210/10000619Bp(ƒX=”V™&IDMAP/GID2SID/10000618 1251141210/S-1-5-21-1834383793-1770918451-929701000-107859ph2X>c÷rë™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107859 1251141210/10000618pÑX=B÷É™&IDMAP/GID2SID/10000617 1251141210/S-1-5-21-1834383793-1770918451-929701000-112793pX•X>·s_™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112793 1251141210/10000617p0/X;ÍyÓø™&IDMAP/UID2SID/10000350 1251141210/S-1-5-21-1834383793-1770918451-929701000-1401BBpè°X<M/g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1401 1251141210/10000350BBphÞX=}â»™&IDMAP/UID2SID/10000363 1250118308/S-1-5-21-1834383793-1770918451-929701000-162818pˆX>˘ò0™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162818 1250118308/10000363p`#X<Í}€D™&IDMAP/UID2SID/10000356 1250784084/S-1-5-21-1834383793-1770918451-929701000-64745BpÜÒX=ö3ØÓ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-64745 1250784084/10000356Bp<ÞX=½ó´b™&IDMAP/UID2SID/10000325 1250095624/S-1-5-21-1834383793-1770918451-929701000-148418p@$X>²÷G™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148418 1250095624/10000325px X=ÍÿVê™&IDMAP/UID2SID/10000359 1250809196/S-1-5-21-1834383793-1770918451-929701000-162817pÈX>Ëè Ì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162817 1250809196/10000359p0ëX= N;™&IDMAP/GID2SID/10000598 1251837380/S-1-5-21-1834383793-1770918451-929701000-129656phUX> t"æ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129656 1251837380/10000598pŒßX; xžw™&IDMAP/GID2SID/10000597 1251823756/S-1-5-21-1834383793-1770918451-929701000-9881BBp<X<åÇLÕ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-9881 1251823756/10000597BBpŒíX< ¢ë™&IDMAP/GID2SID/10000596 1251837380/S-1-5-21-1834383793-1770918451-929701000-34573BpŠX=’FZ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-34573 1251837380/10000596Bp äX< Ìd^™&IDMAP/GID2SID/10000595 1251837380/S-1-5-21-1834383793-1770918451-929701000-65873Bp|X=’N?Û™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-65873 1251837380/10000595Bp0äX=í9$v™&IDMAP/GID2SID/10000636 1250027977/S-1-5-21-1834383793-1770918451-929701000-148240pÓX>Û7¤X™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148240 1250027977/10000636p\ÖX;Í)º]™&IDMAP/UID2SID/10000358 1250027977/S-1-5-21-1834383793-1770918451-929701000-3687BBp èX<U9»—™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-3687 1250027977/10000358BBpàX=ÍSÑ™&IDMAP/UID2SID/10000357 1250017630/S-1-5-21-1834383793-1770918451-929701000-162816pˆÁX>Ë8%g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162816 1250017630/10000357pX±X=ÍÑF+™&IDMAP/UID2SID/10000354 1250010978/S-1-5-21-1834383793-1770918451-929701000-154305püßX>ï2îG™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-154305 1250010978/10000354p(-X=ÍOp…™&IDMAP/UID2SID/10000351 1250561251/S-1-5-21-1834383793-1770918451-929701000-148519p˜îX>Ç›÷³™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148519 1250561251/10000351p0üX=òÍ™&IDMAP/UID2SID/10000349 1249930193/S-1-5-21-1834383793-1770918451-929701000-143850pX>ËîãÆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143850 1249930193/10000349p8>X<CUA™&IDMAP/UID2SID/10000348 1250615979/S-1-5-21-1834383793-1770918451-929701000-95251BpìÜX=>J~™&IDMAP/GID2SID/10000611 1250805470/S-1-5-21-1834383793-1770918451-929701000-148264p(PX>Ûb²™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148264 1250805470/10000611pHX&û¯ò0™&NBT/NEW-BRDC01.MTVNE.AD.VIACOM.COM#20 1251229216/166.77.172.123:00.64.99.4:389BBp8êX=ÝÌÆ™&IDMAP/GID2SID/10000609 1250805470/S-1-5-21-1834383793-1770918451-929701000-148266p¦X>ÛÂZ|™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148266 1250805470/10000609p¸%X=Ý[’­™&IDMAP/GID2SID/10000607 1250805470/S-1-5-21-1834383793-1770918451-929701000-148262pHX>ÛÀè™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148262 1250805470/10000607p DX=ݯX”™&IDMAP/GID2SID/10000605 1250805470/S-1-5-21-1834383793-1770918451-929701000-148267pXX>ÛrAá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148267 1250805470/10000605p¼áX=ÝHÕ™&IDMAP/GID2SID/10000600 1251130207/S-1-5-21-1834383793-1770918451-929701000-148521p (X>ß)ˆ ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148521 1251130207/10000600pÌ4X=m°¶ ™&IDMAP/UID2SID/10000336 1250902730/S-1-5-21-1834383793-1770918451-929701000-141062p ëX>ë¶N ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141062 1250902730/10000336pPêX=i i™&IDMAP/UID2SID/10000341 1249604757/S-1-5-21-1834383793-1770918451-929701000-156773p°GX>0Xk™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-156773 1249604757/10000341pìX=“nÜ™&IDMAP/UID2SID/10000340 1249604757/S-1-5-21-1834383793-1770918451-929701000-107684p°çX>óÛ•ñ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107684 1249604757/10000340p,ðX=Ý:™&IDMAP/UID2SID/10000081 1251228438/S-1-5-21-1834383793-1770918451-929701000-129672p X>sF7|™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129672 1251228438/10000081pðEX=ýo)™&IDMAP/GID2SID/10000469 1251133100/S-1-5-21-1834383793-1770918451-929701000-148514pL1X>_X™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148514 1251133100/10000469p,ÛX=]z±™&IDMAP/UID2SID/10000303 1250197567/S-1-5-21-1834383793-1770918451-929701000-143720p˜X>ŸU™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143720 1250197567/10000303p|ÜX=­¦§½™&IDMAP/GID2SID/10000471 1251825059/S-1-5-21-1834383793-1770918451-929701000-164035pÐOX>ÿ!Ç™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-164035 1251825059/10000471pX÷X=­Ð 1™&IDMAP/GID2SID/10000470 1251825058/S-1-5-21-1834383793-1770918451-929701000-153022pÐVX>ƒ¹{™™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-153022 1251825058/10000470pèóX= ]™&IDMAP/GID2SID/10000546 1249523691/S-1-5-21-1834383793-1770918451-929701000-156570pX>_…Ë™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-156570 1249523691/10000546pLúX=JlЙ&IDMAP/GID2SID/10000545 1249523690/S-1-5-21-1834383793-1770918451-929701000-163262p dX>Û¶‚™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163262 1249523690/10000545p¨õX=tÏC™&IDMAP/GID2SID/10000544 1249523690/S-1-5-21-1834383793-1770918451-929701000-163260pÌÖX>ۢ踙&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163260 1249523690/10000544pØX=ž2·™&IDMAP/GID2SID/10000543 1249523690/S-1-5-21-1834383793-1770918451-929701000-156572pLÓX>_åÝ”™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-156572 1249523690/10000543pHøX=È•*™&IDMAP/GID2SID/10000542 1249523690/S-1-5-21-2140803266-1626024873-1299147156-24690p ÕX>º•]õ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24690 1249523690/10000542pP'X=òø™&IDMAP/GID2SID/10000541 1249523690/S-1-5-21-2140803266-1626024873-1299147156-34233p0DX> ~,™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34233 1249523690/10000541pLèX=\™&IDMAP/GID2SID/10000540 1249523689/S-1-5-21-2140803266-1626024873-1299147156-34232p\ëX> ÎEž™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34232 1249523689/10000540p8aX=í»zæ™&IDMAP/GID2SID/10000539 1249523689/S-1-5-21-2140803266-1626024873-1299147156-34226p8ZX>ŠX¹N™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34226 1249523689/10000539p`þX<íåÝY™&IDMAP/GID2SID/10000538 1249523689/S-1-5-21-4186143834-2626045635-1021053583-1210Bp¬åX=Ÿ£Ô™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1210 1249523689/10000538Bp8ÇX==Ñh™&IDMAP/GID2SID/10000323 1249523689/S-1-5-21-2140803266-1626024873-1299147156-14614ppX>º©S!™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-14614 1249523689/10000323p8 X=íAÍ™&IDMAP/GID2SID/10000537 1249523689/S-1-5-21-2140803266-1626024873-1299147156-34225pXÔX>ЍÒé™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34225 1249523689/10000537p8)X=í9¤@™&IDMAP/GID2SID/10000536 1249523689/S-1-5-21-2140803266-1626024873-1299147156-21811pûX> ç™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-21811 1249523689/10000536p0‹X=íc´™&IDMAP/GID2SID/10000535 1249523689/S-1-5-21-2140803266-1626024873-1299147156-20386püØX>6ÓÒ$™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20386 1249523689/10000535p€X;íj'™&IDMAP/GID2SID/10000534 1249523688/S-1-5-21-2129485696-1739684832-945835055-1850BBplàX<ùˆöw™&IDMAP/SID2GID/S-1-5-21-2129485696-1739684832-945835055-1850 1249523688/10000534BBp#X>s0ë·™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-146636 1251836362/10000421pldb-2.0.8/lib/tdb/test/test_tdbbackup.sh0000770000000000000000000000220313573675413020063 0ustar rootroot00000000000000#!/bin/sh # Blackbox test for tdbbackup of given ldb or tdb database # Copyright (C) 2018 Andrew Bartlett if [ $# -lt 1 ]; then echo "Usage: $0 LDBFILE" exit 1; fi LDBFILE=$1 timestamp() { date -u +'time: %Y-%m-%d %H:%M:%S.%6NZ' | sed 's/\..*NZ$/.000000Z/' } subunit_fail_test () { timestamp printf 'failure: %s [\n' "$1" cat - echo "]" } testit () { name="$1" shift cmdline="$@" timestamp printf 'test: %s\n' "$1" output=`$cmdline 2>&1` status=$? if [ x$status = x0 ]; then timestamp printf 'success: %s\n' "$name" else echo "$output" | subunit_fail_test "$name" fi return $status } $BINDIR/tdbdump $LDBFILE | sort > orig_dump testit "normal tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak $BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump testit "cmp between tdbdumps of original and backup" cmp orig_dump bak_dump rm $LDBFILE.bak rm bak_dump testit "readonly tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak -r $BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump testit "cmp between tdbdumps of original and back dbs" cmp orig_dump bak_dump rm $LDBFILE.bak rm bak_dump rm orig_dump ldb-2.0.8/lib/tdb/tools/tdbbackup.c0000660000000000000000000002021113573675413017012 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. low level tdb backup and restore utility Copyright (C) Andrew Tridgell 2002 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 . */ /* This program is meant for backup/restore of tdb databases. Typical usage would be: tdbbackup *.tdb when Samba shuts down cleanly, which will make a backup of all the local databases to *.bak files. Then on Samba startup you would use: tdbbackup -v *.tdb and this will check the databases for corruption and if corruption is detected then the backup will be restored. You may also like to do a backup on a regular basis while Samba is running, perhaps using cron. The reason this program is needed is to cope with power failures while Samba is running. A power failure could lead to database corruption and Samba will then not start correctly. Note that many of the databases in Samba are transient and thus don't need to be backed up, so you can optimise the above a little by only running the backup on the critical databases. */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" #ifdef HAVE_GETOPT_H #include #endif static int failed; static struct tdb_logging_context log_ctx; #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); fflush(stdout); } static char *add_suffix(const char *name, const char *suffix) { char *ret; int len = strlen(name) + strlen(suffix) + 1; ret = (char *)malloc(len); if (!ret) { fprintf(stderr,"Out of memory!\n"); exit(1); } snprintf(ret, len, "%s%s", name, suffix); return ret; } static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new)); failed = 1; return 1; } return 0; } static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { return 0; } /* carefully backup a tdb, validating the contents and only doing the backup if its OK this function is also used for restore */ static int backup_tdb(const char *old_name, const char *new_name, int hash_size, int nolock, bool readonly) { TDB_CONTEXT *tdb; TDB_CONTEXT *tdb_new; char *tmp_name; struct stat st; int count1, count2; tmp_name = add_suffix(new_name, ".tmp"); /* stat the old tdb to find its permissions */ if (stat(old_name, &st) != 0) { perror(old_name); free(tmp_name); return 1; } /* open the old tdb */ tdb = tdb_open_ex(old_name, 0, TDB_DEFAULT | (nolock ? TDB_NOLOCK : 0), O_RDWR, 0, &log_ctx, NULL); if (!tdb) { printf("Failed to open %s\n", old_name); free(tmp_name); return 1; } /* create the new tdb */ unlink(tmp_name); tdb_new = tdb_open_ex(tmp_name, hash_size ? hash_size : tdb_hash_size(tdb), TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, st.st_mode & 0777, &log_ctx, NULL); if (!tdb_new) { perror(tmp_name); free(tmp_name); return 1; } if (readonly) { if (tdb_lockall_read(tdb) != 0) { printf("Failed to obtain read only lock on old tdb\n"); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } } else if (tdb_transaction_start(tdb) != 0) { printf("Failed to start transaction on db\n"); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } /* lock the backup tdb so that nobody else can change it */ if (tdb_lockall(tdb_new) != 0) { printf("Failed to lock backup tdb\n"); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } failed = 0; /* traverse and copy */ if (readonly) { count1 = tdb_traverse_read(tdb, copy_fn, (void *)tdb_new); } else { count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); } if (count1 < 0 || failed) { fprintf(stderr,"failed to copy %s\n", old_name); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } /* close the old tdb */ tdb_close(tdb); /* copy done, unlock the backup tdb */ tdb_unlockall(tdb_new); #ifdef HAVE_FDATASYNC if (fdatasync(tdb_fd(tdb_new)) != 0) { #else if (fsync(tdb_fd(tdb_new)) != 0) { #endif /* not fatal */ fprintf(stderr, "failed to fsync backup file\n"); } /* close the new tdb and re-open read-only */ tdb_close(tdb_new); tdb_new = tdb_open_ex(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0, &log_ctx, NULL); if (!tdb_new) { fprintf(stderr,"failed to reopen %s\n", tmp_name); unlink(tmp_name); perror(tmp_name); free(tmp_name); return 1; } /* traverse the new tdb to confirm */ count2 = tdb_traverse(tdb_new, test_fn, NULL); if (count2 != count1) { fprintf(stderr,"failed to copy %s\n", old_name); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } /* close the new tdb and rename it to .bak */ tdb_close(tdb_new); if (rename(tmp_name, new_name) != 0) { perror(new_name); free(tmp_name); return 1; } free(tmp_name); return 0; } /* verify a tdb and if it is corrupt then restore from *.bak */ static int verify_tdb(const char *fname, const char *bak_name) { TDB_CONTEXT *tdb; int count = -1; /* open the tdb */ tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &log_ctx, NULL); /* traverse the tdb, then close it */ if (tdb) { count = tdb_traverse(tdb, test_fn, NULL); tdb_close(tdb); } /* count is < 0 means an error */ if (count < 0) { printf("restoring %s\n", fname); return backup_tdb(bak_name, fname, 0, 0, 0); } printf("%s : %d records\n", fname, count); return 0; } /* see if one file is newer than another */ static int file_newer(const char *fname1, const char *fname2) { struct stat st1, st2; if (stat(fname1, &st1) != 0) { return 0; } if (stat(fname2, &st2) != 0) { return 1; } return (st1.st_mtime > st2.st_mtime); } static void usage(void) { printf("Usage: tdbbackup [options] \n\n"); printf(" -h this help message\n"); printf(" -s suffix set the backup suffix\n"); printf(" -v verify mode (restore if corrupt)\n"); printf(" -n hashsize set the new hash size for the backup\n"); printf(" -l open without locking to back up mutex dbs\n"); printf(" -r open with read only locking\n"); } int main(int argc, char *argv[]) { int i; int ret = 0; int c; int verify = 0; int hashsize = 0; int nolock = 0; bool readonly = false; const char *suffix = ".bak"; log_ctx.log_fn = tdb_log; while ((c = getopt(argc, argv, "vhs:n:lr")) != -1) { switch (c) { case 'h': usage(); exit(0); case 'v': verify = 1; break; case 's': suffix = optarg; break; case 'n': hashsize = atoi(optarg); break; case 'l': nolock = 1; break; case 'r': readonly = true; } } argc -= optind; argv += optind; if (argc < 1) { usage(); exit(1); } for (i=0; i. */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" static void print_data(TDB_DATA d) { unsigned char *p = (unsigned char *)d.dptr; int len = d.dsize; while (len--) { if (isprint(*p) && !strchr("\"\\", *p)) { fputc(*p, stdout); } else { printf("\\%02X", *p); } p++; } } static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { printf("{\n"); printf("key(%zu) = \"", key.dsize); print_data(key); printf("\"\n"); printf("data(%zu) = \"", dbuf.dsize); print_data(dbuf); printf("\"\n"); printf("}\n"); return 0; } static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; const char *name = tdb_name(tdb); const char *prefix = ""; if (!name) name = "unnamed"; switch (level) { case TDB_DEBUG_ERROR: prefix = "ERROR: "; break; case TDB_DEBUG_WARNING: prefix = "WARNING: "; break; case TDB_DEBUG_TRACE: return; default: case TDB_DEBUG_FATAL: prefix = "FATAL: "; break; } va_start(ap, fmt); fprintf(stderr, "tdb(%s): %s", name, prefix); vfprintf(stderr, fmt, ap); va_end(ap); } static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) { if (keyname) { if (key.dsize != strlen(keyname)) return; if (memcmp(key.dptr, keyname, key.dsize) != 0) return; } traverse_fn(NULL, key, dbuf, NULL); } static int dump_tdb(const char *fname, const char *keyname, bool emergency) { TDB_CONTEXT *tdb; TDB_DATA key, value; struct tdb_logging_context logfn = { .log_fn = log_stderr, }; int tdb_flags = TDB_DEFAULT; /* * Note: that O_RDONLY implies TDB_NOLOCK, but we want to make it * explicit as it's important when working on databases which were * created with mutex locking. */ tdb_flags |= TDB_NOLOCK; tdb = tdb_open_ex(fname, 0, tdb_flags, O_RDONLY, 0, &logfn, NULL); if (!tdb) { printf("Failed to open %s\n", fname); return 1; } if (emergency) { return tdb_rescue(tdb, emergency_walk, discard_const(keyname)) == 0; } if (!keyname) { return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0; } else { key.dptr = discard_const_p(uint8_t, keyname); key.dsize = strlen(keyname); value = tdb_fetch(tdb, key); if (!value.dptr) { return 1; } else { print_data(value); free(value.dptr); } } return 0; } static void usage( void) { printf( "Usage: tdbdump [options] \n\n"); printf( " -h this help message\n"); printf( " -k keyname dumps value of keyname\n"); printf( " -e emergency dump, for corrupt databases\n"); } int main(int argc, char *argv[]) { char *fname, *keyname=NULL; bool emergency = false; int c; if (argc < 2) { printf("Usage: tdbdump \n"); exit(1); } while ((c = getopt( argc, argv, "hk:e")) != -1) { switch (c) { case 'h': usage(); exit( 0); case 'k': keyname = optarg; break; case 'e': emergency = true; break; default: usage(); exit( 1); } } fname = argv[optind]; return dump_tdb(fname, keyname, emergency); } ldb-2.0.8/lib/tdb/tools/tdbrestore.c0000660000000000000000000001013012553526140017214 0ustar rootroot00000000000000/* tdbrestore -- construct a tdb from tdbdump output. Copyright (C) Volker Lendecke 2010 Copyright (C) Simon McVittie 2005 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 . */ #include "replace.h" #include #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" static int read_linehead(FILE *f) { int i, c; int num_bytes; char prefix[128]; while (1) { c = getc(f); if (c == EOF) { return -1; } if (c == '(') { break; } } for (i=0; idptr = (unsigned char *)malloc(size); if (d->dptr == NULL) { return -1; } d->dsize = size; for (i=0; idptr[i] = (low|high); } else { d->dptr[i] = c; } } return 0; } static int swallow(FILE *f, const char *s, int *eof) { char line[128]; if (fgets(line, sizeof(line), f) == NULL) { if (eof != NULL) { *eof = 1; } return -1; } if (strcmp(line, s) != 0) { return -1; } return 0; } static int read_rec(FILE *f, TDB_CONTEXT *tdb, int *eof) { int length; TDB_DATA key, data; int ret = -1; key.dptr = NULL; data.dptr = NULL; if (swallow(f, "{\n", eof) == -1) { goto fail; } length = read_linehead(f); if (length == -1) { goto fail; } if (read_data(f, &key, length) == -1) { goto fail; } if (swallow(f, "\"\n", NULL) == -1) { goto fail; } length = read_linehead(f); if (length == -1) { goto fail; } if (read_data(f, &data, length) == -1) { goto fail; } if ((swallow(f, "\"\n", NULL) == -1) || (swallow(f, "}\n", NULL) == -1)) { goto fail; } if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { fprintf(stderr, "TDB error: %s\n", tdb_errorstr(tdb)); goto fail; } ret = 0; fail: free(key.dptr); free(data.dptr); return ret; } static int restore_tdb(const char *fname) { TDB_CONTEXT *tdb; tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT|O_EXCL, 0666); if (!tdb) { perror("tdb_open"); fprintf(stderr, "Failed to open %s\n", fname); return 1; } while (1) { int eof = 0; if (read_rec(stdin, tdb, &eof) == -1) { if (eof) { break; } return 1; } } if (tdb_close(tdb)) { fprintf(stderr, "Error closing tdb\n"); return 1; } return 0; } int main(int argc, char *argv[]) { char *fname; if (argc < 2) { printf("Usage: %s dbname < tdbdump_output\n", argv[0]); exit(1); } fname = argv[1]; return restore_tdb(fname); } ldb-2.0.8/lib/tdb/tools/tdbtest.c0000660000000000000000000001223712406075657016533 0ustar rootroot00000000000000/* a test program for tdb - the trivial database */ #include "replace.h" #include "tdb.h" #include "system/filesys.h" #include "system/time.h" #include #define DELETE_PROB 7 #define STORE_PROB 5 static struct tdb_context *db; static GDBM_FILE gdbm; struct timeval tp1,tp2; static void _start_timer(void) { gettimeofday(&tp1,NULL); } static double _end_timer(void) { gettimeofday(&tp2,NULL); return((tp2.tv_sec - tp1.tv_sec) + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); } static void fatal(const char *why) { perror(why); exit(1); } #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); fflush(stdout); } static void compare_db(void) { TDB_DATA d, key, nextkey; datum gd, gkey, gnextkey; key = tdb_firstkey(db); while (key.dptr) { d = tdb_fetch(db, key); gkey.dptr = key.dptr; gkey.dsize = key.dsize; gd = gdbm_fetch(gdbm, gkey); if (!gd.dptr) fatal("key not in gdbm"); if (gd.dsize != d.dsize) fatal("data sizes differ"); if (memcmp(gd.dptr, d.dptr, d.dsize)) { fatal("data differs"); } nextkey = tdb_nextkey(db, key); free(key.dptr); free(d.dptr); free(gd.dptr); key = nextkey; } gkey = gdbm_firstkey(gdbm); while (gkey.dptr) { gd = gdbm_fetch(gdbm, gkey); key.dptr = gkey.dptr; key.dsize = gkey.dsize; d = tdb_fetch(db, key); if (!d.dptr) fatal("key not in db"); if (d.dsize != gd.dsize) fatal("data sizes differ"); if (memcmp(d.dptr, gd.dptr, gd.dsize)) { fatal("data differs"); } gnextkey = gdbm_nextkey(gdbm, gkey); free(gkey.dptr); free(gd.dptr); free(d.dptr); gkey = gnextkey; } } static char *randbuf(int len) { char *buf; int i; buf = (char *)malloc(len+1); for (i=0;i. */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" static int do_command(void); const char *cmdname; char *arg1, *arg2; size_t arg1len, arg2len; int bIterate = 0; char *line; TDB_DATA iterate_kbuf; char cmdline[1024]; static int disable_mmap; static int _disable_lock; enum commands { CMD_CREATE_TDB, CMD_OPEN_TDB, CMD_TRANSACTION_START, CMD_TRANSACTION_COMMIT, CMD_TRANSACTION_CANCEL, CMD_ERASE, CMD_DUMP, CMD_INSERT, CMD_MOVE, CMD_STOREHEX, CMD_STORE, CMD_SHOW, CMD_KEYS, CMD_HEXKEYS, CMD_DELETE, CMD_LIST_HASH_FREE, CMD_LIST_FREE, CMD_FREELIST_SIZE, CMD_INFO, CMD_MMAP, CMD_SPEED, CMD_FIRST, CMD_NEXT, CMD_SYSTEM, CMD_CHECK, CMD_REPACK, CMD_QUIT, CMD_HELP }; typedef struct { const char *name; enum commands cmd; } COMMAND_TABLE; COMMAND_TABLE cmd_table[] = { {"create", CMD_CREATE_TDB}, {"open", CMD_OPEN_TDB}, {"transaction_start", CMD_TRANSACTION_START}, {"transaction_commit", CMD_TRANSACTION_COMMIT}, {"transaction_cancel", CMD_TRANSACTION_CANCEL}, {"erase", CMD_ERASE}, {"dump", CMD_DUMP}, {"insert", CMD_INSERT}, {"move", CMD_MOVE}, {"storehex", CMD_STOREHEX}, {"store", CMD_STORE}, {"show", CMD_SHOW}, {"keys", CMD_KEYS}, {"hexkeys", CMD_HEXKEYS}, {"delete", CMD_DELETE}, {"list", CMD_LIST_HASH_FREE}, {"free", CMD_LIST_FREE}, {"freelist_size", CMD_FREELIST_SIZE}, {"info", CMD_INFO}, {"speed", CMD_SPEED}, {"mmap", CMD_MMAP}, {"first", CMD_FIRST}, {"1", CMD_FIRST}, {"next", CMD_NEXT}, {"n", CMD_NEXT}, {"check", CMD_CHECK}, {"quit", CMD_QUIT}, {"q", CMD_QUIT}, {"!", CMD_SYSTEM}, {"repack", CMD_REPACK}, {NULL, CMD_HELP} }; struct timeval tp1,tp2; static void _start_timer(void) { gettimeofday(&tp1,NULL); } static double _end_timer(void) { gettimeofday(&tp2,NULL); return((tp2.tv_sec - tp1.tv_sec) + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); } #ifdef PRINTF_ATTRIBUTE static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { const char *mutex_msg = "Can use mutexes only with MUTEX_LOCKING or NOLOCK\n"; char *p; va_list ap; p = strstr(format, mutex_msg); if (p != NULL) { /* * Yes, this is a hack, but we don't want to see this * message on first open, but we want to see * everything else. */ return; } va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } /* a tdb tool for manipulating a tdb database */ static TDB_CONTEXT *tdb; static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); static void print_asc(const char *buf,int len) { int i; /* We're probably printing ASCII strings so don't try to display the trailing NULL character. */ if (buf[len - 1] == 0) len--; for (i=0;i8) printf(" "); while (n--) printf(" "); n = i%16; if (n > 8) n = 8; print_asc(&buf[i-(i%16)],n); printf(" "); n = (i%16) - n; if (n>0) print_asc(&buf[i-n],n); printf("\n"); } } static void help(void) { printf("\n" "tdbtool: \n" " create dbname : create a database\n" " open dbname : open an existing database\n" " transaction_start : start a transaction\n" " transaction_commit : commit a transaction\n" " transaction_cancel : cancel a transaction\n" " erase : erase the database\n" " dump : dump the database as strings\n" " keys : dump the database keys as strings\n" " hexkeys : dump the database keys as hex values\n" " info : print summary info about the database\n" " insert key data : insert a record\n" " move key file : move a record to a destination tdb\n" " storehex key data : store a record (replace), key/value in hex format\n" " store key data : store a record (replace)\n" " show key : show a record by key\n" " delete key : delete a record by key\n" " list : print the database hash table and freelist\n" " free : print the database freelist\n" " freelist_size : print the number of records in the freelist\n" " check : check the integrity of an opened database\n" " repack : repack the database\n" " speed : perform speed tests on the database\n" " ! command : execute system command\n" " 1 | first : print the first record\n" " n | next : print the next record\n" " q | quit : terminate\n" " \\n : repeat 'next' command\n" "\n"); } static void terror(const char *why) { printf("%s\n", why); } static void create_tdb(const char *tdbname) { struct tdb_logging_context log_ctx = { NULL, NULL}; log_ctx.log_fn = tdb_log; if (tdb) tdb_close(tdb); tdb = tdb_open_ex(tdbname, 0, TDB_CLEAR_IF_FIRST | (disable_mmap?TDB_NOMMAP:0) | (_disable_lock?TDB_NOLOCK:0), O_RDWR | O_CREAT | O_TRUNC, 0600, &log_ctx, NULL); if (!tdb) { printf("Could not create %s: %s\n", tdbname, strerror(errno)); } } static void open_tdb(const char *tdbname) { struct tdb_logging_context log_ctx = { NULL, NULL }; log_ctx.log_fn = tdb_log_open; if (tdb) tdb_close(tdb); tdb = tdb_open_ex(tdbname, 0, (disable_mmap?TDB_NOMMAP:0) | (_disable_lock?TDB_NOLOCK:0), O_RDWR, 0600, &log_ctx, NULL); log_ctx.log_fn = tdb_log; if (tdb != NULL) { tdb_set_logging_function(tdb, &log_ctx); } if ((tdb == NULL) && (errno == EINVAL)) { /* * Retry NOLOCK and readonly. There we want to see all * error messages. */ tdb = tdb_open_ex(tdbname, 0, (disable_mmap?TDB_NOMMAP:0) |TDB_NOLOCK, O_RDONLY, 0600, &log_ctx, NULL); } if (!tdb) { printf("Could not open %s: %s\n", tdbname, strerror(errno)); } } static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) { TDB_DATA key, dbuf; if ((keyname == NULL) || (keylen == 0)) { terror("need key"); return; } key.dptr = (unsigned char *)keyname; key.dsize = keylen; dbuf.dptr = (unsigned char *)data; dbuf.dsize = datalen; if (tdb_store(tdb, key, dbuf, TDB_INSERT) != 0) { terror("insert failed"); } } static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) { TDB_DATA key, dbuf; if ((keyname == NULL) || (keylen == 0)) { terror("need key"); return; } if ((data == NULL) || (datalen == 0)) { terror("need data"); return; } key.dptr = (unsigned char *)keyname; key.dsize = keylen; dbuf.dptr = (unsigned char *)data; dbuf.dsize = datalen; printf("Storing key:\n"); print_rec(tdb, key, dbuf, NULL); if (tdb_store(tdb, key, dbuf, TDB_REPLACE) != 0) { terror("store failed"); } } static bool hexchar(char c, uint8_t *v) { if ((c >= '0') && (c <= '9')) { *v = (c - '0'); return true; } if ((c >= 'A') && (c <= 'F')) { *v = (c - 'A' + 10); return true; } if ((c >= 'a') && (c <= 'f')) { *v = (c - 'a' + 10); return true; } return false; } static bool parse_hex(const char *src, size_t srclen, uint8_t *dst) { size_t i=0; if ((srclen % 2) != 0) { return false; } while (iname) { cmd_len = strlen(ctp->name); if (strncmp(ctp->name,cmdname,cmd_len) == 0) { mycmd = ctp->cmd; break; } ctp++; } } } switch (mycmd) { case CMD_CREATE_TDB: bIterate = 0; create_tdb(arg1); return 0; case CMD_OPEN_TDB: bIterate = 0; open_tdb(arg1); return 0; case CMD_SYSTEM: /* Shell command */ if (system(arg1) == -1) { terror("system() call failed\n"); } return 0; case CMD_QUIT: return 1; default: /* all the rest require a open database */ if (!tdb) { bIterate = 0; terror("database not open"); help(); return 0; } switch (mycmd) { case CMD_TRANSACTION_START: bIterate = 0; tdb_transaction_start(tdb); return 0; case CMD_TRANSACTION_COMMIT: bIterate = 0; tdb_transaction_commit(tdb); return 0; case CMD_REPACK: bIterate = 0; tdb_repack(tdb); return 0; case CMD_TRANSACTION_CANCEL: bIterate = 0; tdb_transaction_cancel(tdb); return 0; case CMD_ERASE: bIterate = 0; tdb_wipe_all(tdb); return 0; case CMD_DUMP: bIterate = 0; tdb_traverse(tdb, print_rec, NULL); return 0; case CMD_INSERT: bIterate = 0; insert_tdb(arg1, arg1len,arg2,arg2len); return 0; case CMD_MOVE: bIterate = 0; move_rec(arg1,arg1len,arg2); return 0; case CMD_STORE: bIterate = 0; store_tdb(arg1,arg1len,arg2,arg2len); return 0; case CMD_STOREHEX: bIterate = 0; store_hex_tdb(arg1,arg1len,arg2,arg2len); return 0; case CMD_SHOW: bIterate = 0; show_tdb(arg1, arg1len); return 0; case CMD_KEYS: tdb_traverse(tdb, print_key, NULL); return 0; case CMD_HEXKEYS: tdb_traverse(tdb, print_hexkey, NULL); return 0; case CMD_DELETE: bIterate = 0; delete_tdb(arg1,arg1len); return 0; case CMD_LIST_HASH_FREE: tdb_dump_all(tdb); return 0; case CMD_LIST_FREE: tdb_printfreelist(tdb); return 0; case CMD_FREELIST_SIZE: { int size; size = tdb_freelist_size(tdb); if (size < 0) { printf("Error getting freelist size.\n"); } else { printf("freelist size: %d\n", size); } return 0; } case CMD_INFO: info_tdb(); return 0; case CMD_SPEED: speed_tdb(arg1); return 0; case CMD_MMAP: toggle_mmap(); return 0; case CMD_FIRST: bIterate = 1; first_record(tdb, &iterate_kbuf); return 0; case CMD_NEXT: if (bIterate) next_record(tdb, &iterate_kbuf); return 0; case CMD_CHECK: check_db(tdb); return 0; case CMD_HELP: help(); return 0; case CMD_CREATE_TDB: case CMD_OPEN_TDB: case CMD_SYSTEM: case CMD_QUIT: /* * unhandled commands. cases included here to avoid compiler * warnings. */ return 0; } } return 0; } static char *tdb_convert_string(char *instring, size_t *sizep) { size_t length = 0; char *outp, *inp; char temp[3]; outp = inp = instring; while (*inp) { if (*inp == '\\') { inp++; if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { temp[0] = *inp++; temp[1] = '\0'; if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { temp[1] = *inp++; temp[2] = '\0'; } *outp++ = (char)strtol((const char *)temp,NULL,16); } else { *outp++ = *inp++; } } else { *outp++ = *inp++; } length++; } *sizep = length; return instring; } int main(int argc, char *argv[]) { cmdname = ""; arg1 = NULL; arg1len = 0; arg2 = NULL; arg2len = 0; if (argv[1] && (strcmp(argv[1], "-l") == 0)) { _disable_lock = 1; argv[1] = argv[0]; argv += 1; argc -= 1; } if (argv[1]) { cmdname = "open"; arg1 = argv[1]; do_command(); cmdname = ""; arg1 = NULL; } switch (argc) { case 1: case 2: /* Interactive mode */ while ((cmdname = tdb_getline("tdb> "))) { arg2 = arg1 = NULL; if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { arg1++; arg2 = arg1; while (*arg2) { if (*arg2 == ' ') { *arg2++ = '\0'; break; } if ((*arg2++ == '\\') && (*arg2 == ' ')) { arg2++; } } } if (arg1) arg1 = tdb_convert_string(arg1,&arg1len); if (arg2) arg2 = tdb_convert_string(arg2,&arg2len); if (do_command()) break; } 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; } if (tdb) tdb_close(tdb); return 0; } ldb-2.0.8/lib/tdb/tools/tdbtorture.c0000660000000000000000000002367413573675413017271 0ustar rootroot00000000000000/* this tests tdb by doing lots of ops from several simultaneous writers - that stresses the locking code. */ #include "replace.h" #include "system/time.h" #include "system/wait.h" #include "system/filesys.h" #include "tdb.h" #ifdef HAVE_GETOPT_H #include #endif #define REOPEN_PROB 30 #define DELETE_PROB 8 #define STORE_PROB 4 #define APPEND_PROB 6 #define TRANSACTION_PROB 10 #define TRANSACTION_PREPARE_PROB 2 #define LOCKSTORE_PROB 5 #define TRAVERSE_PROB 20 #define TRAVERSE_READ_PROB 20 #define CULL_PROB 100 #define KEYLEN 3 #define DATALEN 100 static struct tdb_context *db; static int in_transaction; static int error_count; static int always_transaction = 0; static int hash_size = 2; static unsigned loopnum; static int count_pipe; static bool mutex = false; static struct tdb_logging_context log_ctx; #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { va_list ap; /* trace level messages do not indicate an error */ if (level != TDB_DEBUG_TRACE) { error_count++; } va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); fflush(stdout); #if 0 if (level != TDB_DEBUG_TRACE) { char *ptr; signal(SIGUSR1, SIG_IGN); asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); system(ptr); free(ptr); } #endif } static void fatal(const char *why) { perror(why); error_count++; } static char *randbuf(int len) { char *buf; int i; buf = (char *)malloc(len+1); for (i=0;i ldb

tdb

TDB is a Trivial Database. In concept, it is very much like GDBM, and BSD's DB except that it allows multiple simultaneous writers and uses locking internally to keep writers from trampling on each other. TDB is also extremely small.

Download

You can download the latest releases of tdb from the tdb directory on the samba public source archive.

Discussion and bug reports

tdb does not currently have its own mailing list or bug tracking system. For now, please use the samba-technical mailing list, and the Samba bugzilla bug tracking system.

Download

You can download the latest code either via git or rsync.

To fetch via git see the following guide:
Using Git for Samba Development
Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory.

To fetch via rsync use these commands:
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
and build in tdb. It will find the replace library in the directory above automatically. ldb-2.0.8/lib/tdb/wscript0000660000000000000000000002057113573675413015176 0ustar rootroot00000000000000#!/usr/bin/env python APPNAME = 'tdb' VERSION = '1.4.2' import sys, os # find the buildtools directory top = '.' while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: top = top + '/..' sys.path.insert(0, top + '/buildtools/wafsamba') out = 'bin' import wafsamba from wafsamba import samba_dist, samba_utils from waflib import Options, Logs, Context import shutil samba_dist.DIST_DIRS('lib/tdb:. lib/replace:lib/replace buildtools:buildtools third_party/waf:third_party/waf') tdb1_unit_tests = [ 'run-3G-file', 'run-bad-tdb-header', 'run', 'run-check', 'run-corrupt', 'run-die-during-transaction', 'run-endian', 'run-incompatible', 'run-nested-transactions', 'run-nested-traverse', 'run-no-lock-during-traverse', 'run-oldhash', 'run-open-during-transaction', 'run-readonly-check', 'run-rescue', 'run-rescue-find_entry', 'run-rdlock-upgrade', 'run-rwlock-check', 'run-summary', 'run-transaction-expand', 'run-traverse-in-transaction', 'run-wronghash-fail', 'run-zero-append', 'run-fcntl-deadlock', 'run-marklock-deadlock', 'run-allrecord-traverse-deadlock', 'run-mutex-openflags2', 'run-mutex-trylock', 'run-mutex-allrecord-bench', 'run-mutex-allrecord-trylock', 'run-mutex-allrecord-block', 'run-mutex-transaction1', 'run-mutex-die', 'run-mutex1', 'run-circular-chain', 'run-circular-freelist', 'run-traverse-chain', ] def options(opt): opt.BUILTIN_DEFAULT('replace') opt.PRIVATE_EXTENSION_DEFAULT('tdb', noextension='tdb') opt.RECURSE('lib/replace') opt.add_option('--disable-tdb-mutex-locking', help=("Disable the use of pthread robust mutexes"), action="store_true", dest='disable_tdb_mutex_locking', default=False) def configure(conf): conf.env.disable_tdb_mutex_locking = getattr(Options.options, 'disable_tdb_mutex_locking', False) if not conf.env.disable_tdb_mutex_locking: conf.env.replace_add_global_pthread = True conf.RECURSE('lib/replace') conf.env.standalone_tdb = conf.IN_LAUNCH_DIR() conf.env.building_tdb = True if not conf.env.standalone_tdb: if conf.CHECK_BUNDLED_SYSTEM_PKG('tdb', minversion=VERSION, implied_deps='replace'): conf.define('USING_SYSTEM_TDB', 1) conf.env.building_tdb = False if not conf.env.disable_python and \ conf.CHECK_BUNDLED_SYSTEM_PYTHON('pytdb', 'tdb', minversion=VERSION): conf.define('USING_SYSTEM_PYTDB', 1) if (conf.CONFIG_SET('HAVE_ROBUST_MUTEXES') and conf.env.building_tdb and not conf.env.disable_tdb_mutex_locking): conf.define('USE_TDB_MUTEX_LOCKING', 1) conf.CHECK_XSLTPROC_MANPAGES() conf.SAMBA_CHECK_PYTHON() conf.SAMBA_CHECK_PYTHON_HEADERS() conf.SAMBA_CONFIG_H() conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() def build(bld): bld.RECURSE('lib/replace') COMMON_FILES='''check.c error.c tdb.c traverse.c freelistcheck.c lock.c dump.c freelist.c io.c open.c transaction.c hash.c summary.c rescue.c mutex.c''' COMMON_SRC = bld.SUBDIR('common', COMMON_FILES) if bld.env.standalone_tdb: bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' private_library = False else: private_library = True if not bld.CONFIG_SET('USING_SYSTEM_TDB'): tdb_deps = 'replace' if bld.CONFIG_SET('USE_TDB_MUTEX_LOCKING'): tdb_deps += ' pthread' bld.SAMBA_LIBRARY('tdb', COMMON_SRC, deps=tdb_deps, includes='include', abi_directory='ABI', abi_match='tdb_*', hide_symbols=True, vnum=VERSION, public_headers=('' if private_library else 'include/tdb.h'), public_headers_install=not private_library, pc_files='tdb.pc', private_library=private_library) bld.SAMBA_BINARY('tdbtorture', 'tools/tdbtorture.c', 'tdb', install=False) bld.SAMBA_BINARY('tdbrestore', 'tools/tdbrestore.c', 'tdb', manpages='man/tdbrestore.8') bld.SAMBA_BINARY('tdbdump', 'tools/tdbdump.c', 'tdb', manpages='man/tdbdump.8') bld.SAMBA_BINARY('tdbbackup', 'tools/tdbbackup.c', 'tdb', manpages='man/tdbbackup.8') bld.SAMBA_BINARY('tdbtool', 'tools/tdbtool.c', 'tdb', manpages='man/tdbtool.8') if bld.env.standalone_tdb: # FIXME: This hardcoded list is stupid, stupid, stupid. bld.SAMBA_SUBSYSTEM('tdb-test-helpers', 'test/external-agent.c test/lock-tracking.c test/logging.c', tdb_deps, includes='include') for t in tdb1_unit_tests: b = "tdb1-" + t s = "test/" + t + ".c" bld.SAMBA_BINARY(b, s, 'replace tdb-test-helpers', includes='include', install=False) if not bld.CONFIG_SET('USING_SYSTEM_PYTDB'): bld.SAMBA_PYTHON('pytdb', 'pytdb.c', deps='tdb', enabled=not bld.env.disable_python, realname='tdb.so', cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) if not bld.env.disable_python: bld.SAMBA_SCRIPT('_tdb_text.py', pattern='_tdb_text.py', installdir='python') bld.INSTALL_FILES('${PYTHONARCHDIR}', '_tdb_text.py') def testonly(ctx): '''run tdb testsuite''' ecode = 0 blddir = Context.g_module.out test_prefix = "%s/st" % (blddir) shutil.rmtree(test_prefix, ignore_errors=True) os.makedirs(test_prefix) os.environ['TEST_DATA_PREFIX'] = test_prefix env = samba_utils.LOAD_ENVIRONMENT() # FIXME: This is horrible :( if env.building_tdb: # Create scratch directory for tests. testdir = os.path.join(test_prefix, 'tdb-tests') samba_utils.mkdir_p(testdir) # Symlink back to source dir so it can find tests in test/ link = os.path.join(testdir, 'test') if not os.path.exists(link): os.symlink(ctx.path.make_node('test').abspath(), link) sh_tests = ["test/test_tdbbackup.sh test/jenkins-be-hash.tdb"] for sh_test in sh_tests: cmd = "BINDIR=%s %s" % (blddir, sh_test) print("shell test: " + cmd) ret = samba_utils.RUN_COMMAND(cmd) if ret != 0: print("%s sh test failed" % cmd) ecode = ret break for t in tdb1_unit_tests: f = "tdb1-" + t cmd = "cd " + testdir + " && " + os.path.abspath(os.path.join(blddir, f)) + " > test-output 2>&1" print("..." + f) ret = samba_utils.RUN_COMMAND(cmd) if ret != 0: print("%s failed:" % f) samba_utils.RUN_COMMAND("cat " + os.path.join(testdir, 'test-output')) ecode = ret break if ecode == 0: cmd = os.path.join(blddir, 'tdbtorture') ret = samba_utils.RUN_COMMAND(cmd) print("testsuite returned %d" % ret) if ret != 0: ecode = ret pyret = samba_utils.RUN_PYTHON_TESTS(['python/tests/simple.py']) print("python testsuite returned %d" % pyret) sys.exit(ecode or pyret) # WAF doesn't build the unit tests for this, maybe because they don't link with tdb? # This forces it def test(ctx): Options.commands.append('build') Options.commands.append('testonly') def dist(): '''makes a tarball for distribution''' samba_dist.dist() def reconfigure(ctx): '''reconfigure if config scripts have changed''' samba_utils.reconfigure(ctx) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs0000660000000000000000000001254512406075657016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t) tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *) tdb_allrecord_lock: int (struct tdb_context *, int, enum tdb_lock_flags, bool) tdb_allrecord_unlock: int (struct tdb_context *, int, bool) tdb_allrecord_upgrade: int (struct tdb_context *) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_brlock: int (struct tdb_context *, int, tdb_off_t, size_t, enum tdb_lock_flags) tdb_brunlock: int (struct tdb_context *, int, tdb_off_t, size_t) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_convert: void *(void *, uint32_t) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_expand: int (struct tdb_context *, tdb_off_t) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_have_extra_locks: bool (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_io_init: void (struct tdb_context *) tdb_lock: int (struct tdb_context *, int, int) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lock_record: int (struct tdb_context *, tdb_off_t) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_mmap: void (struct tdb_context *) tdb_munmap: int (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_needs_recovery: bool (struct tdb_context *) tdb_nest_lock: int (struct tdb_context *, uint32_t, int, enum tdb_lock_flags) tdb_nest_unlock: int (struct tdb_context *, uint32_t, int, bool) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *) tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *) tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *) tdb_release_transaction_locks: void (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_lock: int (struct tdb_context *, int, enum tdb_lock_flags) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_recover: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_unlock: int (struct tdb_context *, int) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlock_record: int (struct tdb_context *, tdb_off_t) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) tdb_write_lock_record: int (struct tdb_context *, tdb_off_t) tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs0000660000000000000000000000672112406075657016327 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs0000660000000000000000000000704612406075657016331 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs0000660000000000000000000000704612406075657016332 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs0000660000000000000000000000704612406075657016333 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs0000660000000000000000000000623012406075657016243 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs0000660000000000000000000000623012406075657016244 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs0000660000000000000000000000623012406075657016245 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs0000660000000000000000000000630412406075657016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs0000660000000000000000000000630412406075657016251 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs0000660000000000000000000000630412406075657016252 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs0000660000000000000000000000630412406075657016253 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs0000660000000000000000000000635612406075657016263 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs0000660000000000000000000000713012406075657016242 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs0000660000000000000000000000713012406075657016243 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs0000660000000000000000000000723212746330636016324 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs0000660000000000000000000000734712761221116016321 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs0000660000000000000000000000734713017565171016331 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs0000660000000000000000000000734713100601766016324 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs0000660000000000000000000000743313126252766016333 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs0000660000000000000000000000743313444661620016330 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs0000660000000000000000000000743313444661620016331 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs0000660000000000000000000000771313573675413016343 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs0000660000000000000000000000771313573675413016344 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs0000660000000000000000000000713012436323671016237 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs0000660000000000000000000000713012437274221016235 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs0000660000000000000000000000713012445751350016240 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs0000660000000000000000000000723212520121120016220 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs0000660000000000000000000000723212536700353016243 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs0000660000000000000000000000723212553526406016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs0000660000000000000000000000723212617125445016250 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs0000660000000000000000000000723212702766507016256 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs0000660000000000000000000000771313573675413016254 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs0000660000000000000000000000771313573675413016255 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs0000660000000000000000000000771313573675413016256 0ustar rootroot00000000000000tdb_add_flags: void (struct tdb_context *, unsigned int) tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) tdb_chainlock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) tdb_chainunlock: int (struct tdb_context *, TDB_DATA) tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_close: int (struct tdb_context *) tdb_delete: int (struct tdb_context *, TDB_DATA) tdb_dump_all: void (struct tdb_context *) tdb_enable_seqnum: void (struct tdb_context *) tdb_error: enum TDB_ERROR (struct tdb_context *) tdb_errorstr: const char *(struct tdb_context *) tdb_exists: int (struct tdb_context *, TDB_DATA) tdb_fd: int (struct tdb_context *) tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_firstkey: TDB_DATA (struct tdb_context *) tdb_freelist_size: int (struct tdb_context *) tdb_get_flags: int (struct tdb_context *) tdb_get_logging_private: void *(struct tdb_context *) tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) tdb_lockall_read: int (struct tdb_context *) tdb_lockall_read_nonblock: int (struct tdb_context *) tdb_lockall_unmark: int (struct tdb_context *) tdb_log_fn: tdb_log_func (struct tdb_context *) tdb_map_size: size_t (struct tdb_context *) tdb_name: const char *(struct tdb_context *) tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) tdb_null: dptr = 0xXXXX, dsize = 0 tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_printfreelist: int (struct tdb_context *) tdb_remove_flags: void (struct tdb_context *, unsigned int) tdb_reopen: int (struct tdb_context *) tdb_reopen_all: int (int) tdb_repack: int (struct tdb_context *) tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) tdb_runtime_check_for_robust_mutexes: bool (void) tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) tdb_summary: char *(struct tdb_context *) tdb_transaction_active: bool (struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) tdb_transaction_write_lock_mark: int (struct tdb_context *) tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) tdb_wipe_all: int (struct tdb_context *) ldb-2.0.8/lib/tdb/Makefile0000660000000000000000000000166413573675413015222 0ustar rootroot00000000000000# simple makefile wrapper to run waf WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` WAF_BINARY=$(PYTHON) $(WAF_BIN) WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) all: $(WAF) build install: $(WAF) install uninstall: $(WAF) uninstall test: FORCE $(WAF) test $(TEST_OPTIONS) testenv: $(WAF) test --testenv $(TEST_OPTIONS) quicktest: $(WAF) test --quick $(TEST_OPTIONS) dist: touch .tmplock WAFLOCK=.tmplock $(WAF) dist distcheck: touch .tmplock WAFLOCK=.tmplock $(WAF) distcheck clean: $(WAF) clean distclean: $(WAF) distclean reconfigure: configure $(WAF) reconfigure show_waf_options: $(WAF) --help # some compatibility make targets everything: all testsuite: all check: test torture: all # this should do an install as well, once install is finished installcheck: test etags: $(WAF) etags ctags: $(WAF) ctags pydoctor: $(WAF) pydoctor bin/%:: FORCE $(WAF) --targets=`basename $@` FORCE: ldb-2.0.8/lib/tdb/_tdb_text.py0000660000000000000000000000642113573675413016104 0ustar rootroot00000000000000# Text wrapper for tdb bindings # # Copyright (C) 2015 Petr Viktorin # Published under the GNU LGPLv3 or later import sys import tdb class TdbTextWrapper(object): """Text interface for a TDB file""" def __init__(self, tdb): self._tdb = tdb @property def raw(self): return self._tdb def get(self, key): key = key.encode('utf-8') result = self._tdb.get(key) if result is not None: return result.decode('utf-8') def append(self, key, value): key = key.encode('utf-8') value = value.encode('utf-8') self._tdb.append(key, value) def firstkey(self): result = self._tdb.firstkey() if result: return result.decode('utf-8') def nextkey(self, key): key = key.encode('utf-8') result = self._tdb.nextkey(key) if result is not None: return result.decode('utf-8') def delete(self, key): key = key.encode('utf-8') self._tdb.delete(key) def store(self, key, value): key = key.encode('utf-8') value = value.encode('utf-8') self._tdb.store(key, value) def __iter__(self): for key in iter(self._tdb): yield key.decode('utf-8') def __getitem__(self, key): key = key.encode('utf-8') result = self._tdb[key] return result.decode('utf-8') def __contains__(self, key): key = key.encode('utf-8') return key in self._tdb def __repr__(self): return '' % self._tdb def __setitem__(self, key, value): key = key.encode('utf-8') value = value.encode('utf-8') self._tdb[key] = value def __delitem__(self, key): key = key.encode('utf-8') del self._tdb[key] if sys.version_info > (3, 0): keys = __iter__ else: iterkeys = __iter__ has_key = __contains__ ## Add wrappers for functions and getters that don't deal with text def _add_wrapper(name): orig = getattr(tdb.Tdb, name) def wrapper(self, *args, **kwargs): return orig(self._tdb, *args, **kwargs) wrapper.__name__ = orig.__name__ wrapper.__doc__ = orig.__doc__ setattr(TdbTextWrapper, name, wrapper) for name in ("transaction_cancel", "transaction_commit", "transaction_prepare_commit", "transaction_start", "reopen", "lock_all", "unlock_all", "read_lock_all", "read_unlock_all", "close", "add_flags", "remove_flags", "clear", "repack", "enable_seqnum", "increment_seqnum_nonblock", ): _add_wrapper(name) def _add_getter(name): orig = getattr(tdb.Tdb, name) doc = orig.__doc__ def getter(self): return getattr(self._tdb, name) def setter(self, value): return setattr(self._tdb, name, value) setattr(TdbTextWrapper, name, property(getter, setter, doc=doc)) for name in ("hash_size", "map_size", "freelist_size", "flags", "max_dead", "filename", "seqnum", "text", ): _add_getter(name) ldb-2.0.8/lib/tdb/common/check.c0000660000000000000000000003150013573675413016263 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Rusty Russell 2009 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* Since we opened it, these shouldn't fail unless it's recent corruption. */ static bool tdb_check_header(struct tdb_context *tdb, tdb_off_t *recovery) { struct tdb_header hdr; uint32_t h1, h2; if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) return false; if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) goto corrupt; CONVERT(hdr); if (hdr.version != TDB_VERSION) goto corrupt; if (hdr.rwlocks != 0 && hdr.rwlocks != TDB_FEATURE_FLAG_MAGIC && hdr.rwlocks != TDB_HASH_RWLOCK_MAGIC) goto corrupt; tdb_header_hash(tdb, &h1, &h2); if (hdr.magic1_hash && hdr.magic2_hash && (hdr.magic1_hash != h1 || hdr.magic2_hash != h2)) goto corrupt; if (hdr.hash_size == 0) goto corrupt; if (hdr.hash_size != tdb->hash_size) goto corrupt; if (hdr.recovery_start != 0 && hdr.recovery_start < TDB_DATA_START(tdb->hash_size)) goto corrupt; *recovery = hdr.recovery_start; return true; corrupt: tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Header is corrupt\n")); return false; } /* Generic record header check. */ static bool tdb_check_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec) { tdb_off_t tailer; /* Check rec->next: 0 or points to record offset, aligned. */ if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)){ TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too small next %u\n", off, rec->next)); goto corrupt; } if (rec->next + sizeof(*rec) < rec->next) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too large next %u\n", off, rec->next)); goto corrupt; } if ((rec->next % TDB_ALIGNMENT) != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u misaligned next %u\n", off, rec->next)); goto corrupt; } if (tdb_oob(tdb, rec->next, sizeof(*rec), 0)) goto corrupt; /* Check rec_len: similar to rec->next, implies next record. */ if ((rec->rec_len % TDB_ALIGNMENT) != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u misaligned length %u\n", off, rec->rec_len)); goto corrupt; } /* Must fit tailer. */ if (rec->rec_len < sizeof(tailer)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too short length %u\n", off, rec->rec_len)); goto corrupt; } /* OOB allows "right at the end" access, so this works for last rec. */ if (tdb_oob(tdb, off, sizeof(*rec)+rec->rec_len, 0)) goto corrupt; /* Check tailer. */ if (tdb_ofs_read(tdb, off+sizeof(*rec)+rec->rec_len-sizeof(tailer), &tailer) == -1) goto corrupt; if (tailer != sizeof(*rec) + rec->rec_len) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u invalid tailer\n", off)); goto corrupt; } return true; corrupt: tdb->ecode = TDB_ERR_CORRUPT; return false; } /* Grab some bytes: may copy if can't use mmap. Caller has already done bounds check. */ static TDB_DATA get_bytes(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) { TDB_DATA d; d.dsize = len; if (tdb->transaction == NULL && tdb->map_ptr != NULL) d.dptr = (unsigned char *)tdb->map_ptr + off; else d.dptr = tdb_alloc_read(tdb, off, d.dsize); return d; } /* Frees data if we're not able to simply use mmap. */ static void put_bytes(struct tdb_context *tdb, TDB_DATA d) { if (tdb->transaction == NULL && tdb->map_ptr != NULL) return; free(d.dptr); } /* We use the excellent Jenkins lookup3 hash; this is based on hash_word2. * See: http://burtleburtle.net/bob/c/lookup3.c */ #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) static void hash(uint32_t key, uint32_t *pc, uint32_t *pb) { uint32_t a,b,c; /* Set up the internal state */ a = b = c = 0xdeadbeef + *pc; c += *pb; a += key; c ^= b; c -= rot(b,14); a ^= c; a -= rot(c,11); b ^= a; b -= rot(a,25); c ^= b; c -= rot(b,16); a ^= c; a -= rot(c,4); b ^= a; b -= rot(a,14); c ^= b; c -= rot(b,24); *pc=c; *pb=b; } /* We want to check that all free records are in the free list (only once), and all free list entries are free records. Similarly for each hash chain of used records. Doing that naively (without walking hash chains, since we want to be linear) means keeping a list of records which have been seen in each hash chain, and another of records pointed to (ie. next pointers from records and the initial hash chain heads). These two lists should be equal. This will take 8 bytes per record, and require sorting at the end. So instead, we record each offset in a bitmap such a way that recording it twice will cancel out. Since each offset should appear exactly twice, the bitmap should be zero at the end. The approach was inspired by Bloom Filters (see Wikipedia). For each value, we flip K bits in a bitmap of size N. The number of distinct arrangements is: N! / (K! * (N-K)!) Of course, not all arrangements are actually distinct, but testing shows this formula to be close enough. So, if K == 8 and N == 256, the probability of two things flipping the same bits is 1 in 409,663,695,276,000. Given that ldb uses a hash size of 10000, using 32 bytes per hash chain (320k) seems reasonable. */ #define NUM_HASHES 8 #define BITMAP_BITS 256 static void bit_flip(unsigned char bits[], unsigned int idx) { bits[idx / CHAR_BIT] ^= (1 << (idx % CHAR_BIT)); } /* We record offsets in a bitmap for the particular chain it should be in. */ static void record_offset(unsigned char bits[], tdb_off_t off) { uint32_t h1 = off, h2 = 0; unsigned int i; /* We get two good hash values out of jhash2, so we use both. Then * we keep going to produce further hash values. */ for (i = 0; i < NUM_HASHES / 2; i++) { hash(off, &h1, &h2); bit_flip(bits, h1 % BITMAP_BITS); bit_flip(bits, h2 % BITMAP_BITS); h2++; } } /* Check that an in-use record is valid. */ static bool tdb_check_used_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec, unsigned char **hashes, int (*check)(TDB_DATA, TDB_DATA, void *), 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) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u too short for contents\n", off)); return false; } key = get_bytes(tdb, off + sizeof(*rec), rec->key_len); if (!key.dptr) return false; if (tdb->hash_fn(&key) != rec->full_hash) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record offset %u has incorrect hash\n", off)); goto fail_put_key; } /* Mark this offset as a known value for this hash bucket. */ record_offset(hashes[BUCKET(rec->full_hash)+1], off); /* And similarly if the next pointer is valid. */ if (rec->next) record_offset(hashes[BUCKET(rec->full_hash)+1], rec->next); /* If they supply a check function and this record isn't dead, get data and feed it. */ if (check && rec->magic != TDB_DEAD_MAGIC) { data = get_bytes(tdb, off + sizeof(*rec) + rec->key_len, rec->data_len); if (!data.dptr) goto fail_put_key; if (check(key, data, private_data) == -1) goto fail_put_data; put_bytes(tdb, data); } put_bytes(tdb, key); return true; fail_put_data: put_bytes(tdb, data); fail_put_key: put_bytes(tdb, key); return false; } /* Check that an unused record is valid. */ static bool tdb_check_free_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec, unsigned char **hashes) { if (!tdb_check_record(tdb, off, rec)) return false; /* Mark this offset as a known value for the free list. */ record_offset(hashes[0], off); /* And similarly if the next pointer is valid. */ if (rec->next) record_offset(hashes[0], rec->next); return true; } /* Slow, but should be very rare. */ size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off) { size_t len; for (len = 0; off + len < tdb->map_size; len++) { char c; if (tdb->methods->tdb_read(tdb, off, &c, 1, 0)) return 0; if (c != 0 && c != 0x42) break; } return len; } _PUBLIC_ int tdb_check(struct tdb_context *tdb, int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { unsigned int h; unsigned char **hashes; tdb_off_t off, recovery_start; struct tdb_record rec; bool found_recovery = false; tdb_len_t dead; bool locked; /* Read-only databases use no locking at all: it's best-effort. * We may have a write lock already, so skip that case too. */ if (tdb->read_only || tdb->allrecord_lock.count != 0) { locked = false; } else { if (tdb_lockall_read(tdb) == -1) return -1; locked = true; } /* Make sure we know true size of the underlying file. */ tdb_oob(tdb, tdb->map_size, 1, 1); /* Header must be OK: also gets us the recovery ptr, if any. */ if (!tdb_check_header(tdb, &recovery_start)) goto unlock; /* We should have the whole header, too. */ if (tdb->map_size < TDB_DATA_START(tdb->hash_size)) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "File too short for hashes\n")); goto unlock; } /* One big malloc: pointers then bit arrays. */ hashes = (unsigned char **)calloc( 1, sizeof(hashes[0]) * (1+tdb->hash_size) + BITMAP_BITS / CHAR_BIT * (1+tdb->hash_size)); if (!hashes) { tdb->ecode = TDB_ERR_OOM; goto unlock; } /* Initialize pointers */ hashes[0] = (unsigned char *)(&hashes[1+tdb->hash_size]); for (h = 1; h < 1+tdb->hash_size; h++) hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT; /* Freelist and hash headers are all in a row: read them. */ for (h = 0; h < 1+tdb->hash_size; h++) { if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), &off) == -1) goto free; if (off) record_offset(hashes[h], off); } /* For each record, read it in and check it's ok. */ for (off = TDB_DATA_START(tdb->hash_size); off < tdb->map_size; off += sizeof(rec) + rec.rec_len) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == -1) goto free; switch (rec.magic) { case TDB_MAGIC: case TDB_DEAD_MAGIC: if (!tdb_check_used_record(tdb, off, &rec, hashes, check, private_data)) goto free; break; case TDB_FREE_MAGIC: if (!tdb_check_free_record(tdb, off, &rec, hashes)) goto free; break; /* If we crash after ftruncate, we can get zeroes or fill. */ case TDB_RECOVERY_INVALID_MAGIC: case 0x42424242: if (recovery_start == off) { found_recovery = true; break; } dead = tdb_dead_space(tdb, off); if (dead < sizeof(rec)) goto corrupt; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Dead space at %u-%u (of %u)\n", off, off + dead, tdb->map_size)); rec.rec_len = dead - sizeof(rec); break; case TDB_RECOVERY_MAGIC: if (recovery_start != off) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Unexpected recovery record at offset %u\n", off)); goto free; } found_recovery = true; break; default: ; corrupt: tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Bad magic 0x%x at offset %u\n", rec.magic, off)); goto free; } } /* Now, hashes should all be empty: each record exists and is referred * to by one other. */ for (h = 0; h < 1+tdb->hash_size; h++) { unsigned int i; for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) { if (hashes[h][i] != 0) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "Hashes do not match records\n")); goto free; } } } /* We must have found recovery area if there was one. */ if (recovery_start != 0 && !found_recovery) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "Expected a recovery area at %u\n", recovery_start)); goto free; } free(hashes); if (locked) { tdb_unlockall_read(tdb); } return 0; free: free(hashes); unlock: if (locked) { tdb_unlockall_read(tdb); } return -1; } ldb-2.0.8/lib/tdb/common/dump.c0000660000000000000000000000755213573675413016165 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash, tdb_off_t offset) { struct tdb_record rec; tdb_off_t tailer_ofs, tailer; if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { printf("ERROR: failed to read record at %u\n", offset); return 0; } printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%u " "key_len=%u data_len=%u full_hash=0x%08x magic=0x%08x\n", hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t); if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) { printf("ERROR: failed to read tailer at %u\n", tailer_ofs); return rec.next; } if (tailer != rec.rec_len + sizeof(rec)) { printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec))); } return rec.next; } static int tdb_dump_chain(struct tdb_context *tdb, int i) { struct tdb_chainwalk_ctx chainwalk; tdb_off_t rec_ptr, top; if (i == -1) { top = FREELIST_TOP; } else { top = TDB_HASH_TOP(i); } if (tdb_lock(tdb, i, F_WRLCK) != 0) return -1; if (tdb_ofs_read(tdb, top, &rec_ptr) == -1) return tdb_unlock(tdb, i, F_WRLCK); tdb_chainwalk_init(&chainwalk, rec_ptr); if (rec_ptr) printf("hash=%d\n", i); while (rec_ptr) { bool ok; rec_ptr = tdb_dump_record(tdb, i, rec_ptr); ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { printf("circular hash chain %d\n", i); break; } } return tdb_unlock(tdb, i, F_WRLCK); } _PUBLIC_ void tdb_dump_all(struct tdb_context *tdb) { uint32_t i; for (i=0;ihash_size;i++) { tdb_dump_chain(tdb, i); } printf("freelist:\n"); tdb_dump_chain(tdb, -1); } _PUBLIC_ int tdb_printfreelist(struct tdb_context *tdb) { int ret; long total_free = 0; tdb_off_t offset, rec_ptr; struct tdb_record rec; if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) return ret; offset = FREELIST_TOP; /* read in the freelist top */ if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) { tdb_unlock(tdb, -1, F_WRLCK); return 0; } printf("freelist top=[0x%08x]\n", rec_ptr ); while (rec_ptr) { if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { tdb_unlock(tdb, -1, F_WRLCK); return -1; } if (rec.magic != TDB_FREE_MAGIC) { printf("bad magic 0x%08x in free list\n", rec.magic); tdb_unlock(tdb, -1, F_WRLCK); return -1; } printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%u)] (end = 0x%08x)\n", rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); total_free += rec.rec_len; /* move to the next record */ rec_ptr = rec.next; } printf("total rec_len = [0x%08lx (%lu)]\n", total_free, total_free); return tdb_unlock(tdb, -1, F_WRLCK); } ldb-2.0.8/lib/tdb/common/error.c0000660000000000000000000000360512406075657016342 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" _PUBLIC_ enum TDB_ERROR tdb_error(struct tdb_context *tdb) { return tdb->ecode; } static struct tdb_errname { enum TDB_ERROR ecode; const char *estring; } emap[] = { {TDB_SUCCESS, "Success"}, {TDB_ERR_CORRUPT, "Corrupt database"}, {TDB_ERR_IO, "IO Error"}, {TDB_ERR_LOCK, "Locking error"}, {TDB_ERR_OOM, "Out of memory"}, {TDB_ERR_EXISTS, "Record exists"}, {TDB_ERR_NOLOCK, "Lock exists on other keys"}, {TDB_ERR_EINVAL, "Invalid parameter"}, {TDB_ERR_NOEXIST, "Record does not exist"}, {TDB_ERR_RDONLY, "write not permitted"} }; /* Error string for the last tdb error */ _PUBLIC_ const char *tdb_errorstr(struct tdb_context *tdb) { uint32_t i; for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) if (tdb->ecode == emap[i].ecode) return emap[i].estring; return "Invalid error code"; } ldb-2.0.8/lib/tdb/common/freelist.c0000660000000000000000000004257113573675413017035 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* read a freelist record and check for simple errors */ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec) { if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) return -1; if (rec->magic == TDB_MAGIC) { /* this happens when a app is showdown while deleting a record - we should not completely fail when this happens */ TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%u - fixing\n", rec->magic, off)); rec->magic = TDB_FREE_MAGIC; if (tdb_rec_write(tdb, off, rec) == -1) return -1; } if (rec->magic != TDB_FREE_MAGIC) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%u\n", rec->magic, off)); return -1; } if (tdb_oob(tdb, rec->next, sizeof(*rec), 0) != 0) return -1; return 0; } /* update a record tailer (must hold allocation lock) */ static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, const struct tdb_record *rec) { tdb_off_t totalsize; /* Offset of tailer from record header */ totalsize = sizeof(*rec) + rec->rec_len; return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t), &totalsize); } /** * Read the record directly on the left. * Fail if there is no record on the left. */ static int read_record_on_left(struct tdb_context *tdb, tdb_off_t rec_ptr, tdb_off_t *left_p, struct tdb_record *left_r) { tdb_off_t left_ptr; tdb_off_t left_size; struct tdb_record left_rec; int ret; left_ptr = rec_ptr - sizeof(tdb_off_t); if (left_ptr <= TDB_DATA_START(tdb->hash_size)) { /* no record on the left */ return -1; } /* Read in tailer and jump back to header */ ret = tdb_ofs_read(tdb, left_ptr, &left_size); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left_ptr)); return -1; } /* it could be uninitialised data */ if (left_size == 0 || left_size == TDB_PAD_U32) { return -1; } if (left_size > rec_ptr) { return -1; } left_ptr = rec_ptr - left_size; if (left_ptr < TDB_DATA_START(tdb->hash_size)) { return -1; } /* Now read in the left record */ ret = tdb->methods->tdb_read(tdb, left_ptr, &left_rec, sizeof(left_rec), DOCONV()); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left_ptr, left_size)); return -1; } *left_p = left_ptr; *left_r = left_rec; return 0; } /** * Merge new freelist record with the direct left neighbour. * This assumes that left_rec represents the record * directly to the left of right_rec and that this is * a freelist record. */ static int merge_with_left_record(struct tdb_context *tdb, tdb_off_t left_ptr, struct tdb_record *left_rec, struct tdb_record *right_rec) { int ret; left_rec->rec_len += sizeof(*right_rec) + right_rec->rec_len; ret = tdb_rec_write(tdb, left_ptr, left_rec); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "merge_with_left_record: update_left failed at %u\n", left_ptr)); return -1; } ret = update_tailer(tdb, left_ptr, left_rec); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "merge_with_left_record: update_tailer failed at %u\n", left_ptr)); return -1; } return 0; } /** * Check whether the record left of a given freelist record is * also a freelist record, and if so, merge the two records. * * Return code: * -1 upon error * 0 if left was not a free record * 1 if left was free and successfully merged. * * The current record is handed in with pointer and fully read record. * * The left record pointer and struct can be retrieved as result * in lp and lr; */ static int check_merge_with_left_record(struct tdb_context *tdb, tdb_off_t rec_ptr, struct tdb_record *rec, tdb_off_t *lp, struct tdb_record *lr) { tdb_off_t left_ptr; struct tdb_record left_rec; int ret; ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); if (ret != 0) { return 0; } if (left_rec.magic != TDB_FREE_MAGIC) { return 0; } /* It's free - expand to include it. */ ret = merge_with_left_record(tdb, left_ptr, &left_rec, rec); if (ret != 0) { return -1; } if (lp != NULL) { *lp = left_ptr; } if (lr != NULL) { *lr = left_rec; } return 1; } /** * Check whether the record left of a given freelist record is * also a freelist record, and if so, merge the two records. * * Return code: * -1 upon error * 0 if left was not a free record * 1 if left was free and successfully merged. * * In this variant, the input record is specified just as the pointer * and is read from the database if needed. * * next_ptr will contain the original record's next pointer after * successful merging (which will be lost after merging), so that * the caller can update the last pointer. */ static int check_merge_ptr_with_left_record(struct tdb_context *tdb, tdb_off_t rec_ptr, tdb_off_t *next_ptr) { tdb_off_t left_ptr; struct tdb_record rec, left_rec; int ret; ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); if (ret != 0) { return 0; } if (left_rec.magic != TDB_FREE_MAGIC) { return 0; } /* It's free - expand to include it. */ ret = tdb->methods->tdb_read(tdb, rec_ptr, &rec, sizeof(rec), DOCONV()); if (ret != 0) { return -1; } ret = merge_with_left_record(tdb, left_ptr, &left_rec, &rec); if (ret != 0) { return -1; } if (next_ptr != NULL) { *next_ptr = rec.next; } return 1; } /** * Add an element into the freelist. * * We merge the new record into the left record if it is also a * free record, but not with the right one. This makes the * operation O(1) instead of O(n): merging with the right record * requires a traverse of the freelist to find the previous * record in the free list. * * This prevents db traverses from being O(n^2) after a lot of deletes. */ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) { int ret; /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; /* set an initial tailer, so if we fail we don't leave a bogus record */ if (update_tailer(tdb, offset, rec) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n")); goto fail; } ret = check_merge_with_left_record(tdb, offset, rec, NULL, NULL); if (ret == -1) { goto fail; } if (ret == 1) { /* merged */ goto done; } /* Nothing to merge, prepend to free list */ rec->magic = TDB_FREE_MAGIC; if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || tdb_rec_write(tdb, offset, rec) == -1 || tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%u\n", offset)); goto fail; } done: /* And we're done. */ tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: tdb_unlock(tdb, -1, F_WRLCK); return -1; } /* the core of tdb_allocate - called when we have decided which free list entry to use Note that we try to allocate by grabbing data from the end of an existing record, not the beginning. This is so the left merge in a free is more likely to be able to free up the record without fragmentation */ static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, tdb_len_t length, tdb_off_t rec_ptr, struct tdb_record *rec, tdb_off_t last_ptr) { #define MIN_REC_SIZE (sizeof(struct tdb_record) + sizeof(tdb_off_t) + 8) if (rec->rec_len < length + MIN_REC_SIZE) { /* we have to grab the whole record */ /* unlink it from the previous record */ if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { return 0; } /* mark it not free */ rec->magic = TDB_MAGIC; if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { return 0; } return rec_ptr; } /* we're going to just shorten the existing record */ rec->rec_len -= (length + sizeof(*rec)); if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { return 0; } if (update_tailer(tdb, rec_ptr, rec) == -1) { return 0; } /* and setup the new record */ rec_ptr += sizeof(*rec) + rec->rec_len; memset(rec, '\0', sizeof(*rec)); rec->rec_len = length; rec->magic = TDB_MAGIC; if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { return 0; } if (update_tailer(tdb, rec_ptr, rec) == -1) { return 0; } return rec_ptr; } /* allocate some space from the free list. The offset returned points to a unconnected tdb_record within the database with room for at least length bytes of total data 0 is returned if the space could not be allocated */ static tdb_off_t tdb_allocate_from_freelist( struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec) { tdb_off_t rec_ptr, last_ptr, newrec_ptr; struct tdb_chainwalk_ctx chainwalk; bool modified; struct { tdb_off_t rec_ptr, last_ptr; tdb_len_t rec_len; } bestfit; float multiplier = 1.0; bool merge_created_candidate; /* over-allocate to reduce fragmentation */ length *= 1.25; /* Extra bytes required for tailer */ length += sizeof(tdb_off_t); length = TDB_ALIGN(length, TDB_ALIGNMENT); again: merge_created_candidate = false; last_ptr = FREELIST_TOP; /* read in the freelist top */ if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) return 0; modified = false; tdb_chainwalk_init(&chainwalk, rec_ptr); bestfit.rec_ptr = 0; bestfit.last_ptr = 0; bestfit.rec_len = 0; /* this is a best fit allocation strategy. Originally we used a first fit strategy, but it suffered from massive fragmentation issues when faced with a slowly increasing record size. */ while (rec_ptr) { int ret; tdb_off_t left_ptr; struct tdb_record left_rec; if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { return 0; } ret = check_merge_with_left_record(tdb, rec_ptr, rec, &left_ptr, &left_rec); if (ret == -1) { return 0; } if (ret == 1) { /* merged */ rec_ptr = rec->next; ret = tdb_ofs_write(tdb, last_ptr, &rec->next); if (ret == -1) { return 0; } /* * We have merged the current record into the left * neighbour. So our traverse of the freelist will * skip it and consider the next record in the chain. * * But the enlarged left neighbour may be a candidate. * If it is, we can not directly use it, though. * The only thing we can do and have to do here is to * update the current best fit size in the chain if the * current best fit is the left record. (By that we may * worsen the best fit we already had, bit this is not a * problem.) * * If the current best fit is not the left record, * all we can do is remember the fact that a merge * created a new candidate so that we can trigger * a second walk of the freelist if at the end of * the first walk we have not found any fit. * This way we can avoid expanding the database. */ if (bestfit.rec_ptr == left_ptr) { bestfit.rec_len = left_rec.rec_len; } if (left_rec.rec_len > length) { merge_created_candidate = true; } modified = true; continue; } if (rec->rec_len >= length) { if (bestfit.rec_ptr == 0 || rec->rec_len < bestfit.rec_len) { bestfit.rec_len = rec->rec_len; bestfit.rec_ptr = rec_ptr; bestfit.last_ptr = last_ptr; } } /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; if (!modified) { bool ok; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return 0; } } /* if we've found a record that is big enough, then stop searching if its also not too big. The definition of 'too big' changes as we scan through */ if (bestfit.rec_len > 0 && bestfit.rec_len < length * multiplier) { break; } /* this multiplier means we only extremely rarely search more than 50 or so records. At 50 records we accept records up to 11 times larger than what we want */ multiplier *= 1.05; } if (bestfit.rec_ptr != 0) { if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { return 0; } newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, rec, bestfit.last_ptr); return newrec_ptr; } if (merge_created_candidate) { goto again; } /* we didn't find enough space. See if we can expand the database and if we can then try again */ if (tdb_expand(tdb, length + sizeof(*rec)) == 0) goto again; return 0; } static bool tdb_alloc_dead( struct tdb_context *tdb, int hash, tdb_len_t length, tdb_off_t *rec_ptr, struct tdb_record *rec) { tdb_off_t last_ptr; *rec_ptr = tdb_find_dead(tdb, hash, rec, length, &last_ptr); if (*rec_ptr == 0) { return false; } /* * Unlink the record from the hash chain, it's about to be moved into * another one. */ return (tdb_ofs_write(tdb, last_ptr, &rec->next) == 0); } static void tdb_purge_dead(struct tdb_context *tdb, uint32_t hash) { int max_dead_records = tdb->max_dead_records; tdb->max_dead_records = 0; tdb_trim_dead(tdb, hash); tdb->max_dead_records = max_dead_records; } /* * Chain "hash" is assumed to be locked */ tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, struct tdb_record *rec) { tdb_off_t ret; uint32_t i; if (tdb->max_dead_records == 0) { /* * No dead records to expect anywhere. Do the blocking * freelist lock without trying to steal from others */ goto blocking_freelist_allocate; } /* * The following loop tries to get the freelist lock nonblocking. If * it gets the lock, allocate from there. If the freelist is busy, * instead of waiting we try to steal dead records from other hash * chains. * * Be aware that we do nonblocking locks on the other hash chains as * well and fail gracefully. This way we avoid deadlocks (we block two * hash chains, something which is pretty bad normally) */ for (i=0; ihash_size; i++) { int list; list = BUCKET(hash+i); if (tdb_lock_nonblock(tdb, list, F_WRLCK) == 0) { bool got_dead; got_dead = tdb_alloc_dead(tdb, list, length, &ret, rec); tdb_unlock(tdb, list, F_WRLCK); if (got_dead) { return ret; } } if (tdb_lock_nonblock(tdb, -1, F_WRLCK) == 0) { /* * Under the freelist lock take the chance to give * back our dead records. */ tdb_purge_dead(tdb, hash); ret = tdb_allocate_from_freelist(tdb, length, rec); tdb_unlock(tdb, -1, F_WRLCK); return ret; } } blocking_freelist_allocate: if (tdb_lock(tdb, -1, F_WRLCK) == -1) { return 0; } /* * Dead records can happen even if max_dead_records==0, they * are older than the max_dead_records concept: They happen if * tdb_delete happens concurrently with a traverse. */ tdb_purge_dead(tdb, hash); ret = tdb_allocate_from_freelist(tdb, length, rec); tdb_unlock(tdb, -1, F_WRLCK); return ret; } /** * Merge adjacent records in the freelist. */ static int tdb_freelist_merge_adjacent(struct tdb_context *tdb, int *count_records, int *count_merged) { tdb_off_t cur, next; int count = 0; int merged = 0; int ret; ret = tdb_lock(tdb, -1, F_RDLCK); if (ret == -1) { return -1; } cur = FREELIST_TOP; while (tdb_ofs_read(tdb, cur, &next) == 0 && next != 0) { tdb_off_t next2; count++; ret = check_merge_ptr_with_left_record(tdb, next, &next2); if (ret == -1) { goto done; } if (ret == 1) { /* * merged: * now let cur->next point to next2 instead of next */ ret = tdb_ofs_write(tdb, cur, &next2); if (ret != 0) { goto done; } next = next2; merged++; } cur = next; } if (count_records != NULL) { *count_records = count; } if (count_merged != NULL) { *count_merged = merged; } ret = 0; done: tdb_unlock(tdb, -1, F_RDLCK); return ret; } /** * return the size of the freelist - no merging done */ static int tdb_freelist_size_no_merge(struct tdb_context *tdb) { tdb_off_t ptr; int count=0; if (tdb_lock(tdb, -1, F_RDLCK) == -1) { return -1; } ptr = FREELIST_TOP; while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { count++; } tdb_unlock(tdb, -1, F_RDLCK); return count; } /** * return the size of the freelist - used to decide if we should repack * * As a side effect, adjacent records are merged unless the * database is read-only, in order to reduce the fragmentation * without repacking. */ _PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) { int count = 0; if (tdb->read_only) { count = tdb_freelist_size_no_merge(tdb); } else { int ret; ret = tdb_freelist_merge_adjacent(tdb, &count, NULL); if (ret != 0) { return -1; } } return count; } ldb-2.0.8/lib/tdb/common/freelistcheck.c0000660000000000000000000000517013573675413020025 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. trivial database library Copyright (C) Jeremy Allison 2006 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* Check the freelist is good and contains no loops. Very memory intensive - only do this as a consistency checker. Heh heh - uses an in memory tdb as the storage for the "seen" record list. For some reason this strikes me as extremely clever as I don't have to write another tree data structure implementation :-). */ static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) { TDB_DATA key; key.dptr = (unsigned char *)&rec_ptr; key.dsize = sizeof(rec_ptr); return tdb_store(mem_tdb, key, tdb_null, TDB_INSERT); } _PUBLIC_ int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) { struct tdb_context *mem_tdb = NULL; struct tdb_record rec; tdb_off_t rec_ptr, last_ptr; int ret = -1; *pnum_entries = 0; mem_tdb = tdb_open("flval", tdb->hash_size, TDB_INTERNAL, O_RDWR, 0600); if (!mem_tdb) { return -1; } if (tdb_lock(tdb, -1, F_WRLCK) == -1) { tdb_close(mem_tdb); return 0; } last_ptr = FREELIST_TOP; /* Store the FREELIST_TOP record. */ if (seen_insert(mem_tdb, last_ptr) == -1) { tdb->ecode = TDB_ERR_CORRUPT; ret = -1; goto fail; } /* read in the freelist top */ if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) { goto fail; } while (rec_ptr) { /* If we can't store this record (we've seen it before) then the free list has a loop and must be corrupt. */ if (seen_insert(mem_tdb, rec_ptr)) { tdb->ecode = TDB_ERR_CORRUPT; ret = -1; goto fail; } if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) { goto fail; } /* move to the next record */ rec_ptr = rec.next; *pnum_entries += 1; } ret = 0; fail: tdb_close(mem_tdb); tdb_unlock(tdb, -1, F_WRLCK); return ret; } ldb-2.0.8/lib/tdb/common/hash.c0000660000000000000000000003051113444661620016122 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Rusty Russell 2010 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* This is based on the hash algorithm from gdbm */ unsigned int tdb_old_hash(TDB_DATA *key) { uint32_t value; /* Used to compute the hash value. */ uint32_t i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) value = (value + (key->dptr[i] << (i*5 % 24))); return (1103515243 * value + 12345); } #ifndef WORDS_BIGENDIAN # define HASH_LITTLE_ENDIAN 1 # define HASH_BIG_ENDIAN 0 #else # define HASH_LITTLE_ENDIAN 0 # define HASH_BIG_ENDIAN 1 #endif /* ------------------------------------------------------------------------------- lookup3.c, by Bob Jenkins, May 2006, Public Domain. These are functions for producing 32-bit hashes for hash table lookup. hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and 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 hashlittle(). hashlittle() and hashbig() hash byte arrays. hashlittle() is is faster than hashbig() on little-endian machines. Intel and AMD are little-endian machines. On second thought, you probably want hashlittle2(), which is identical to hashlittle() except it returns two 32-bit hashes for the price of one. You could implement hashbig2() 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; mix(a,b,c); a += i4; b += i5; c += i6; mix(a,b,c); a += i7; final(a,b,c); then use c as the hash value. If you have a variable length array of 4-byte integers to hash, use hash_word(). If you have a byte array (like a character string), use hashlittle(). If you have several byte arrays, or a mix of things, see the comments above hashlittle(). 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. */ #define hashsize(n) ((uint32_t)1<<(n)) #define hashmask(n) (hashsize(n)-1) #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) /* ------------------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. This is reversible, so any information in (a,b,c) before mix() is still in (a,b,c) after mix(). If four pairs of (a,b,c) inputs are run through mix(), or through 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^=rot(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 mix(a,b,c) \ { \ a -= c; a ^= rot(c, 4); c += b; \ b -= a; b ^= rot(a, 6); a += c; \ c -= b; c ^= rot(b, 8); b += a; \ a -= c; a ^= rot(c,16); c += b; \ b -= a; b ^= rot(a,19); a += c; \ c -= b; c ^= rot(b, 4); b += a; \ } /* ------------------------------------------------------------------------------- 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 final(a,b,c) \ { \ c ^= b; c -= rot(b,14); \ a ^= c; a -= rot(c,11); \ b ^= a; b -= rot(a,25); \ c ^= b; c -= rot(b,16); \ a ^= c; a -= rot(c,4); \ b ^= a; b -= rot(a,14); \ c ^= b; c -= rot(b,24); \ } /* ------------------------------------------------------------------------------- hashlittle() -- hash a variable-length key into a 32-bit value k : the key (the unaligned variable-length array of bytes) length : the length of the key, counting by bytes val2 : IN: can be any 4-byte value OUT: second 32 bit hash. 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. Note that the return value is better mixed than val2, so use that first. 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 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; 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 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 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 1 : a+=k8[0]; break; case 0 : return c; } } 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 (length > 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); mix(a,b,c); length -= 12; k += 6; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; switch(length) { 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; 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 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 6 : b+=k[2]; a+=k[0]+(((uint32_t)k[1])<<16); break; 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 2 : a+=k[0]; break; case 1 : a+=k8[0]; break; case 0 : return c; /* zero length requires no mixing */ } } 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 (length > 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; mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) { 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 1 : a+=k[0]; break; case 0 : return c; } } final(a,b,c); return c; } _PUBLIC_ unsigned int tdb_jenkins_hash(TDB_DATA *key) { return hashlittle(key->dptr, key->dsize); } ldb-2.0.8/lib/tdb/common/io.c0000660000000000000000000004517113573675413015626 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* * We prepend the mutex area, so fixup offsets. See mutex.c for details. * tdb->hdr_ofs is 0 or header.mutex_size. * * Note: that we only have the 4GB limit of tdb_off_t for * tdb->map_size. The file size on disk can be 4GB + tdb->hdr_ofs! */ static bool tdb_adjust_offset(struct tdb_context *tdb, off_t *off) { off_t tmp = tdb->hdr_ofs + *off; if ((tmp < tdb->hdr_ofs) || (tmp < *off)) { errno = EIO; return false; } *off = tmp; return true; } static ssize_t tdb_pwrite(struct tdb_context *tdb, const void *buf, size_t count, off_t offset) { ssize_t ret; if (!tdb_adjust_offset(tdb, &offset)) { return -1; } do { ret = pwrite(tdb->fd, buf, count, offset); } while ((ret == -1) && (errno == EINTR)); return ret; } static ssize_t tdb_pread(struct tdb_context *tdb, void *buf, size_t count, off_t offset) { ssize_t ret; if (!tdb_adjust_offset(tdb, &offset)) { return -1; } do { ret = pread(tdb->fd, buf, count, offset); } while ((ret == -1) && (errno == EINTR)); return ret; } static int tdb_ftruncate(struct tdb_context *tdb, off_t length) { ssize_t ret; if (!tdb_adjust_offset(tdb, &length)) { return -1; } do { ret = ftruncate(tdb->fd, length); } while ((ret == -1) && (errno == EINTR)); return ret; } #ifdef HAVE_POSIX_FALLOCATE static int tdb_posix_fallocate(struct tdb_context *tdb, off_t offset, off_t len) { ssize_t ret; if (!tdb_adjust_offset(tdb, &offset)) { return -1; } do { ret = posix_fallocate(tdb->fd, offset, len); } while ((ret == -1) && (errno == EINTR)); return ret; } #endif static int tdb_fstat(struct tdb_context *tdb, struct stat *buf) { int ret; ret = fstat(tdb->fd, buf); if (ret == -1) { return -1; } if (buf->st_size < tdb->hdr_ofs) { errno = EIO; return -1; } buf->st_size -= tdb->hdr_ofs; return ret; } /* check for an out of bounds access - if it is out of bounds then see if the database has been expanded by someone else and expand if necessary */ static int tdb_notrans_oob( struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { struct stat st; if (len + off < len) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob off %u len %u wrap\n", off, len)); } return -1; } /* * This duplicates functionality from tdb_oob(). Don't remove: * we still have direct callers of tdb->methods->tdb_oob() * inside transaction.c. */ if (off + len <= tdb->map_size) return 0; if (tdb->flags & TDB_INTERNAL) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond internal malloc size %u\n", (int)(off + len), (int)tdb->map_size)); } return -1; } if (tdb_fstat(tdb, &st) == -1) { tdb->ecode = TDB_ERR_IO; return -1; } /* Beware >4G files! */ if ((tdb_off_t)st.st_size != st.st_size) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_oob len %llu too large!\n", (long long)st.st_size)); return -1; } /* Unmap, update size, remap. We do this unconditionally, to handle * the unusual case where the db is truncated. * * This can happen to a child using tdb_reopen_all(true) on a * TDB_CLEAR_IF_FIRST tdb whose parent crashes: the next * opener will truncate the database. */ if (tdb_munmap(tdb) == -1) { tdb->ecode = TDB_ERR_IO; return -1; } tdb->map_size = st.st_size; if (tdb_mmap(tdb) != 0) { return -1; } if (st.st_size < (size_t)off + len) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond eof at %u\n", (int)(off + len), (int)st.st_size)); } return -1; } return 0; } /* write a lump of data at a specified offset */ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { if (len == 0) { return 0; } if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } if (tdb_oob(tdb, off, len, 0) != 0) return -1; if (tdb->map_ptr) { memcpy(off + (char *)tdb->map_ptr, buf, len); } else { #ifdef HAVE_INCOHERENT_MMAP tdb->ecode = TDB_ERR_IO; return -1; #else ssize_t written; written = tdb_pwrite(tdb, buf, len, off); if ((written != (ssize_t)len) && (written != -1)) { /* try once more */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only " "%zi of %u bytes at %u, trying once more\n", written, len, off)); written = tdb_pwrite(tdb, (const char *)buf+written, len-written, off+written); } if (written == -1) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %u " "len=%u (%s)\n", off, len, strerror(errno))); return -1; } else if (written != (ssize_t)len) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to " "write %u bytes at %u in two attempts\n", len, off)); return -1; } #endif } return 0; } /* Endian conversion: we only ever deal with 4 byte quantities */ void *tdb_convert(void *buf, uint32_t size) { uint32_t i, *p = (uint32_t *)buf; for (i = 0; i < size / 4; i++) p[i] = TDB_BYTEREV(p[i]); return buf; } /* read a lump of data at a specified offset, maybe convert */ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { if (tdb_oob(tdb, off, len, 0) != 0) { return -1; } if (tdb->map_ptr) { memcpy(buf, off + (char *)tdb->map_ptr, len); } else { #ifdef HAVE_INCOHERENT_MMAP tdb->ecode = TDB_ERR_IO; return -1; #else ssize_t ret; ret = tdb_pread(tdb, buf, len, off); if (ret != (ssize_t)len) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %u " "len=%u ret=%zi (%s) map_size=%u\n", off, len, ret, strerror(errno), tdb->map_size)); return -1; } #endif } if (cv) { tdb_convert(buf, len); } return 0; } /* do an unlocked scan of the hash table heads to find the next non-zero head. The value will then be confirmed with the lock held */ static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) { uint32_t h = *chain; if (tdb->map_ptr) { for (;h < tdb->hash_size;h++) { if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { break; } } } else { uint32_t off=0; for (;h < tdb->hash_size;h++) { if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { break; } } } (*chain) = h; } int tdb_munmap(struct tdb_context *tdb) { if (tdb->flags & TDB_INTERNAL) return 0; #ifdef HAVE_MMAP if (tdb->map_ptr) { int ret; ret = munmap(tdb->map_ptr, tdb->map_size); if (ret != 0) return ret; } #endif tdb->map_ptr = NULL; return 0; } /* If mmap isn't coherent, *everyone* must always mmap. */ static bool should_mmap(const struct tdb_context *tdb) { #ifdef HAVE_INCOHERENT_MMAP return true; #else return !(tdb->flags & TDB_NOMMAP); #endif } int tdb_mmap(struct tdb_context *tdb) { if (tdb->flags & TDB_INTERNAL) return 0; #ifdef HAVE_MMAP if (should_mmap(tdb)) { tdb->map_ptr = mmap(NULL, tdb->map_size, PROT_READ|(tdb->read_only? 0:PROT_WRITE), MAP_SHARED|MAP_FILE, tdb->fd, tdb->hdr_ofs); /* * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! */ if (tdb->map_ptr == MAP_FAILED) { tdb->map_ptr = NULL; TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %u (%s)\n", tdb->map_size, strerror(errno))); #ifdef HAVE_INCOHERENT_MMAP tdb->ecode = TDB_ERR_IO; return -1; #endif } } else { tdb->map_ptr = NULL; } #else tdb->map_ptr = NULL; #endif return 0; } /* expand a file. we prefer to use ftruncate, as that is what posix says to use for mmap expansion */ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { char buf[8192]; tdb_off_t new_size; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } if (!tdb_add_off_t(size, addition, &new_size)) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " "overflow detected current size[%u] addition[%u]!\n", (unsigned)size, (unsigned)addition)); errno = ENOSPC; return -1; } #ifdef HAVE_POSIX_FALLOCATE ret = tdb_posix_fallocate(tdb, size, addition); if (ret == 0) { return 0; } if (ret == ENOSPC) { /* * The Linux glibc (at least as of 2.24) fallback if * the file system does not support fallocate does not * reset the file size back to where it was. Also, to * me it is unclear from the posix spec of * posix_fallocate whether this is allowed or * not. Better be safe than sorry and "goto fail" but * "return -1" here, leaving the EOF pointer too * large. */ goto fail; } /* * Retry the "old" way. Possibly unnecessary, but looking at * our configure script there seem to be weird failure modes * for posix_fallocate. See commit 3264a98ff16de, which * probably refers to * https://sourceware.org/bugzilla/show_bug.cgi?id=1083. */ #endif ret = tdb_ftruncate(tdb, new_size); if (ret == -1) { char b = 0; ssize_t written = tdb_pwrite(tdb, &b, 1, new_size - 1); if (written == 0) { /* try once more, potentially revealing errno */ written = tdb_pwrite(tdb, &b, 1, new_size - 1); } if (written == 0) { /* again - give up, guessing errno */ errno = ENOSPC; } if (written != 1) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %u failed (%s)\n", (unsigned)new_size, strerror(errno))); return -1; } } /* now fill the file with something. This ensures that the file isn't sparse, which would be very bad if we ran out of disk. This must be done with write, not via mmap */ memset(buf, TDB_PAD_BYTE, sizeof(buf)); while (addition) { size_t n = addition>sizeof(buf)?sizeof(buf):addition; ssize_t written = tdb_pwrite(tdb, buf, n, size); if (written == 0) { /* prevent infinite loops: try _once_ more */ written = tdb_pwrite(tdb, buf, n, size); } if (written == 0) { /* give up, trying to provide a useful errno */ tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " "returned 0 twice: giving up!\n")); errno = ENOSPC; goto fail; } if (written == -1) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of " "%u bytes failed (%s)\n", (int)n, strerror(errno))); goto fail; } if (written != n) { TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote " "only %zu of %zi bytes - retrying\n", written, n)); } addition -= written; size += written; } return 0; fail: { int err = errno; /* * We're holding the freelist lock or are inside a * transaction. Cutting the file is safe, the space we * tried to allocate can't have been used anywhere in * the meantime. */ ret = tdb_ftruncate(tdb, size); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: " "retruncate to %ju failed\n", (uintmax_t)size)); } errno = err; } return -1; } /* You need 'size', this tells you how much you should expand by. */ tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size) { tdb_off_t new_size, top_size, increment; tdb_off_t max_size = UINT32_MAX - map_size; if (size > max_size) { /* * We can't round up anymore, just give back * what we're asked for. * * The caller has to take care of the ENOSPC handling. */ return size; } /* limit size in order to avoid using up huge amounts of memory for * in memory tdbs if an oddball huge record creeps in */ if (size > 100 * 1024) { increment = size * 2; } else { increment = size * 100; } if (increment < size) { goto overflow; } if (!tdb_add_off_t(map_size, increment, &top_size)) { goto overflow; } /* always make room for at least top_size more records, and at least 25% more space. if the DB is smaller than 100MiB, otherwise grow it by 10% only. */ if (map_size > 100 * 1024 * 1024) { new_size = map_size * 1.10; } else { new_size = map_size * 1.25; } if (new_size < map_size) { goto overflow; } /* Round the database up to a multiple of the page size */ new_size = MAX(top_size, new_size); if (new_size + page_size < new_size) { /* There's a "+" in TDB_ALIGN that might overflow... */ goto overflow; } return TDB_ALIGN(new_size, page_size) - map_size; overflow: /* * Somewhere in between we went over 4GB. Make one big jump to * exactly 4GB database size. */ return max_size; } /* expand the database at least size bytes by expanding the underlying file and doing the mmap again if necessary */ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) { struct tdb_record rec; tdb_off_t offset; tdb_off_t new_size; if (tdb_lock(tdb, -1, F_WRLCK) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); return -1; } /* must know about any previous expansions by another process */ tdb_oob(tdb, tdb->map_size, 1, 1); /* * Note: that we don't care about tdb->hdr_ofs != 0 here * * The 4GB limitation is just related to tdb->map_size * and the offset calculation in the records. * * The file on disk can be up to 4GB + tdb->hdr_ofs */ size = tdb_expand_adjust(tdb->map_size, size, tdb->page_size); if (!tdb_add_off_t(tdb->map_size, size, &new_size)) { tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_expand " "overflow detected current map_size[%u] size[%u]!\n", (unsigned)tdb->map_size, (unsigned)size)); goto fail; } /* form a new freelist record */ offset = tdb->map_size; memset(&rec,'\0',sizeof(rec)); rec.rec_len = size - sizeof(rec); if (tdb->flags & TDB_INTERNAL) { char *new_map_ptr; new_map_ptr = (char *)realloc(tdb->map_ptr, new_size); if (!new_map_ptr) { tdb->ecode = TDB_ERR_OOM; goto fail; } tdb->map_ptr = new_map_ptr; tdb->map_size = new_size; } else { int ret; /* * expand the file itself */ ret = tdb->methods->tdb_expand_file(tdb, tdb->map_size, size); if (ret != 0) { goto fail; } /* Explicitly remap: if we're in a transaction, this won't * happen automatically! */ tdb_munmap(tdb); tdb->map_size = new_size; if (tdb_mmap(tdb) != 0) { goto fail; } } /* link it into the free list */ if (tdb_free(tdb, offset, &rec) == -1) goto fail; tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: tdb_unlock(tdb, -1, F_WRLCK); return -1; } int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { int ret = tdb->methods->tdb_oob(tdb, off, len, probe); return ret; } /* read/write a tdb_off_t */ int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) { return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); } int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) { tdb_off_t off = *d; return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); } /* read a lump of data, allocating the space for it */ unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len) { unsigned char *buf; /* some systems don't like zero length malloc */ if (!(buf = (unsigned char *)malloc(len ? len : 1))) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%u (%s)\n", len, strerror(errno))); return NULL; } if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) { SAFE_FREE(buf); return NULL; } return buf; } /* Give a piece of tdb data to a parser */ int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, tdb_off_t offset, tdb_len_t len, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { TDB_DATA data; int result; data.dsize = len; if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { /* * Optimize by avoiding the malloc/memcpy/free, point the * parser directly at the mmap area. */ if (tdb_oob(tdb, offset, len, 0) != 0) { return -1; } data.dptr = offset + (unsigned char *)tdb->map_ptr; return parser(key, data, private_data); } if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) { return -1; } result = parser(key, data, private_data); free(data.dptr); return result; } /* 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)) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_CORRUPT; 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_oob(tdb, offset, rec->key_len, 1); if (ret == -1) { return -1; } ret = tdb_oob(tdb, offset, rec->data_len, 1); if (ret == -1) { return -1; } ret = tdb_oob(tdb, offset, rec->rec_len, 1); if (ret == -1) { return -1; } return tdb_oob(tdb, rec->next, sizeof(*rec), 0); } int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) { struct tdb_record r = *rec; return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); } static const struct tdb_methods io_methods = { tdb_read, tdb_write, tdb_next_hash_chain, tdb_notrans_oob, tdb_expand_file, }; /* initialise the default methods table */ void tdb_io_init(struct tdb_context *tdb) { tdb->methods = &io_methods; } ldb-2.0.8/lib/tdb/common/lock.c0000660000000000000000000006173313573675413016151 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" _PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) { tdb->interrupt_sig_ptr = ptr; } static int fcntl_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, bool waitflag) { struct flock fl; int cmd; #ifdef USE_TDB_MUTEX_LOCKING { int ret; if (tdb_mutex_lock(tdb, rw, off, len, waitflag, &ret)) { return ret; } } #endif fl.l_type = rw; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; cmd = waitflag ? F_SETLKW : F_SETLK; return fcntl(tdb->fd, cmd, &fl); } static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len) { struct flock fl; #if 0 /* Check they matched up locks and unlocks correctly. */ char line[80]; FILE *locks; bool found = false; locks = fopen("/proc/locks", "r"); while (fgets(line, 80, locks)) { char *p; int type, start, l; /* eg. 1: FLOCK ADVISORY WRITE 2440 08:01:2180826 0 EOF */ p = strchr(line, ':') + 1; if (strncmp(p, " POSIX ADVISORY ", strlen(" POSIX ADVISORY "))) continue; p += strlen(" FLOCK ADVISORY "); if (strncmp(p, "READ ", strlen("READ ")) == 0) type = F_RDLCK; else if (strncmp(p, "WRITE ", strlen("WRITE ")) == 0) type = F_WRLCK; else abort(); p += 6; if (atoi(p) != getpid()) continue; p = strchr(strchr(p, ' ') + 1, ' ') + 1; start = atoi(p); p = strchr(p, ' ') + 1; if (strncmp(p, "EOF", 3) == 0) l = 0; else l = atoi(p) - start + 1; if (off == start) { if (len != l) { fprintf(stderr, "Len %u should be %u: %s", (int)len, l, line); abort(); } if (type != rw) { fprintf(stderr, "Type %s wrong: %s", rw == F_RDLCK ? "READ" : "WRITE", line); abort(); } found = true; break; } } if (!found) { fprintf(stderr, "Unlock on %u@%u not found!\n", (int)off, (int)len); abort(); } fclose(locks); #endif #ifdef USE_TDB_MUTEX_LOCKING { int ret; if (tdb_mutex_unlock(tdb, rw, off, len, &ret)) { return ret; } } #endif fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; return fcntl(tdb->fd, F_SETLKW, &fl); } /* * Calculate the lock offset for a list * * list -1 is the freelist, otherwise a hash chain. * * Note that we consistently (but without real reason) lock hash chains at an * offset that is 4 bytes below the real offset of the corresponding list head * in the db. * * This is the memory layout of the hashchain array: * * FREELIST_TOP + 0 = freelist * FREELIST_TOP + 4 = hashtable list 0 * FREELIST_TOP + 8 = hashtable list 1 * ... * * Otoh lock_offset computes: * * freelist = FREELIST_TOP - 4 * list 0 = FREELIST_TOP + 0 * list 1 = FREELIST_TOP + 4 * ... * * Unfortunately we can't change this calculation in order to align the locking * offset with the memory layout, as that would make the locking incompatible * between different tdb versions. */ static tdb_off_t lock_offset(int list) { return FREELIST_TOP + 4*list; } /* a byte range locking function - return 0 on success this functions locks/unlocks "len" byte at the specified offset. On error, errno is also set so that errors are passed back properly through tdb_open(). note that a len of zero means lock to end of file */ int tdb_brlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len, enum tdb_lock_flags flags) { int ret; if (tdb->flags & TDB_NOLOCK) { return 0; } if (flags & TDB_LOCK_MARK_ONLY) { return 0; } if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { tdb->ecode = TDB_ERR_RDONLY; return -1; } do { ret = fcntl_lock(tdb, rw_type, offset, len, flags & TDB_LOCK_WAIT); /* Check for a sigalarm break. */ if (ret == -1 && errno == EINTR && tdb->interrupt_sig_ptr && *tdb->interrupt_sig_ptr) { break; } } while (ret == -1 && errno == EINTR); if (ret == -1) { tdb->ecode = TDB_ERR_LOCK; /* Generic lock error. errno set by fcntl. * EAGAIN is an expected return from non-blocking * locks. */ if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) { TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %u rw_type=%d flags=%d len=%zu\n", tdb->fd, offset, rw_type, flags, len)); } return -1; } return 0; } int tdb_brunlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len) { int ret; if (tdb->flags & TDB_NOLOCK) { return 0; } do { ret = fcntl_unlock(tdb, rw_type, offset, len); } while (ret == -1 && errno == EINTR); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %u rw_type=%u len=%zu\n", tdb->fd, offset, rw_type, len)); } return ret; } /* * Do a tdb_brlock in a loop. Some OSes (such as solaris) have too * conservative deadlock detection and claim a deadlock when progress can be * made. For those OSes we may loop for a while. */ static int tdb_brlock_retry(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len, enum tdb_lock_flags flags) { int count = 1000; while (count--) { struct timeval tv; int ret; ret = tdb_brlock(tdb, rw_type, offset, len, flags); if (ret == 0) { return 0; } if (errno != EDEADLK) { break; } /* sleep for as short a time as we can - more portable than usleep() */ tv.tv_sec = 0; tv.tv_usec = 1; select(0, NULL, NULL, NULL, &tv); } return -1; } /* upgrade a read lock to a write lock. */ int tdb_allrecord_upgrade(struct tdb_context *tdb) { int ret; if (tdb->allrecord_lock.count != 1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_allrecord_upgrade failed: count %u too high\n", tdb->allrecord_lock.count)); tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.off != 1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_allrecord_upgrade failed: already upgraded?\n")); tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb_have_mutexes(tdb)) { ret = tdb_mutex_allrecord_upgrade(tdb); if (ret == -1) { goto fail; } ret = tdb_brlock_retry(tdb, F_WRLCK, lock_offset(tdb->hash_size), 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE); if (ret == -1) { tdb_mutex_allrecord_downgrade(tdb); } } else { ret = tdb_brlock_retry(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE); } if (ret == 0) { tdb->allrecord_lock.ltype = F_WRLCK; tdb->allrecord_lock.off = 0; return 0; } fail: TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_allrecord_upgrade failed\n")); return -1; } static struct tdb_lock_type *find_nestlock(struct tdb_context *tdb, tdb_off_t offset) { int i; for (i=0; inum_lockrecs; i++) { if (tdb->lockrecs[i].off == offset) { return &tdb->lockrecs[i]; } } return NULL; } /* lock an offset in the database. */ int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, enum tdb_lock_flags flags) { struct tdb_lock_type *new_lck; if (offset >= lock_offset(tdb->hash_size)) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid offset %u for ltype=%d\n", offset, ltype)); return -1; } if (tdb->flags & TDB_NOLOCK) return 0; new_lck = find_nestlock(tdb, offset); if (new_lck) { if ((new_lck->ltype == F_RDLCK) && (ltype == F_WRLCK)) { if (!tdb_have_mutexes(tdb)) { int ret; /* * Upgrade the underlying fcntl * lock. Mutexes don't do readlocks, * so this only applies to fcntl * locking. */ ret = tdb_brlock(tdb, ltype, offset, 1, flags); if (ret != 0) { return ret; } } new_lck->ltype = F_WRLCK; } /* * Just increment the in-memory struct, posix locks * don't stack. */ new_lck->count++; return 0; } if (tdb->num_lockrecs == tdb->lockrecs_array_length) { new_lck = (struct tdb_lock_type *)realloc( tdb->lockrecs, sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); if (new_lck == NULL) { errno = ENOMEM; return -1; } tdb->lockrecs_array_length = tdb->num_lockrecs+1; tdb->lockrecs = new_lck; } /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ if (tdb_brlock(tdb, ltype, offset, 1, flags)) { return -1; } new_lck = &tdb->lockrecs[tdb->num_lockrecs]; new_lck->off = offset; new_lck->count = 1; new_lck->ltype = ltype; tdb->num_lockrecs++; return 0; } static int tdb_lock_and_recover(struct tdb_context *tdb) { int ret; /* We need to match locking order in transaction commit. */ if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT)) { return -1; } if (tdb_brlock(tdb, F_WRLCK, OPEN_LOCK, 1, TDB_LOCK_WAIT)) { tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); return -1; } ret = tdb_transaction_recover(tdb); tdb_brunlock(tdb, F_WRLCK, OPEN_LOCK, 1); tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); return ret; } static bool have_data_locks(const struct tdb_context *tdb) { int i; for (i = 0; i < tdb->num_lockrecs; i++) { if (tdb->lockrecs[i].off >= lock_offset(-1)) return true; } return false; } /* * A allrecord lock allows us to avoid per chain locks. Check if the allrecord * lock is strong enough. */ static int tdb_lock_covered_by_allrecord_lock(struct tdb_context *tdb, int ltype) { if (ltype == F_RDLCK) { /* * The allrecord_lock is equal (F_RDLCK) or stronger * (F_WRLCK). Pass. */ return 0; } if (tdb->allrecord_lock.ltype == F_RDLCK) { /* * We ask for ltype==F_WRLCK, but the allrecord_lock * is too weak. We can't upgrade here, so fail. */ tdb->ecode = TDB_ERR_LOCK; return -1; } /* * Asking for F_WRLCK, allrecord is F_WRLCK as well. Pass. */ return 0; } static int tdb_lock_list(struct tdb_context *tdb, int list, int ltype, enum tdb_lock_flags waitflag) { int ret; bool check = false; if (tdb->allrecord_lock.count) { return tdb_lock_covered_by_allrecord_lock(tdb, ltype); } /* * Check for recoveries: Someone might have kill -9'ed a process * during a commit. */ check = !have_data_locks(tdb); ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag); if (ret == 0 && check && tdb_needs_recovery(tdb)) { tdb_nest_unlock(tdb, lock_offset(list), ltype, false); if (tdb_lock_and_recover(tdb) == -1) { return -1; } return tdb_lock_list(tdb, list, ltype, waitflag); } return ret; } /* lock a list in the database. list -1 is the alloc list */ int tdb_lock(struct tdb_context *tdb, int list, int ltype) { int ret; ret = tdb_lock_list(tdb, list, ltype, TDB_LOCK_WAIT); if (ret) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " "ltype=%d (%s)\n", list, ltype, strerror(errno))); } return ret; } /* lock a list in the database. list -1 is the alloc list. non-blocking lock */ _PUBLIC_ int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) { return tdb_lock_list(tdb, list, ltype, TDB_LOCK_NOWAIT); } int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, bool mark_lock) { int ret = -1; struct tdb_lock_type *lck; if (tdb->flags & TDB_NOLOCK) return 0; /* Sanity checks */ if (offset >= lock_offset(tdb->hash_size)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: offset %u invalid (%d)\n", offset, tdb->hash_size)); return ret; } lck = find_nestlock(tdb, offset); if ((lck == NULL) || (lck->count == 0)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); return -1; } if (lck->count > 1) { lck->count--; return 0; } /* * This lock has count==1 left, so we need to unlock it in the * kernel. We don't bother with decrementing the in-memory array * element, we're about to overwrite it with the last array element * anyway. */ if (mark_lock) { ret = 0; } else { ret = tdb_brunlock(tdb, ltype, offset, 1); } /* * Shrink the array by overwriting the element just unlocked with the * last array element. */ *lck = tdb->lockrecs[--tdb->num_lockrecs]; /* * We don't bother with realloc when the array shrinks, but if we have * a completely idle tdb we should get rid of the locked array. */ if (ret) TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); return ret; } _PUBLIC_ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) { /* a global lock allows us to avoid per chain locks */ if (tdb->allrecord_lock.count) { return tdb_lock_covered_by_allrecord_lock(tdb, ltype); } return tdb_nest_unlock(tdb, lock_offset(list), ltype, false); } /* get the transaction lock */ int tdb_transaction_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags lockflags) { return tdb_nest_lock(tdb, TRANSACTION_LOCK, ltype, lockflags); } /* release the transaction lock */ int tdb_transaction_unlock(struct tdb_context *tdb, int ltype) { return tdb_nest_unlock(tdb, TRANSACTION_LOCK, ltype, false); } /* Returns 0 if all done, -1 if error, 1 if ok. */ static int tdb_allrecord_check(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable) { /* There are no locks on read-only dbs */ if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.count && tdb->allrecord_lock.ltype == (uint32_t)ltype) { tdb->allrecord_lock.count++; return 0; } if (tdb->allrecord_lock.count) { /* a global lock of a different type exists */ tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb_have_extra_locks(tdb)) { /* can't combine global and chain locks */ tdb->ecode = TDB_ERR_LOCK; return -1; } if (upgradable && ltype != F_RDLCK) { /* tdb error: you can't upgrade a write lock! */ tdb->ecode = TDB_ERR_LOCK; return -1; } return 1; } /* We only need to lock individual bytes, but Linux merges consecutive locks * so we lock in contiguous ranges. */ static int tdb_chainlock_gradual(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, size_t off, size_t len) { int ret; enum tdb_lock_flags nb_flags = (flags & ~TDB_LOCK_WAIT); if (len <= 4) { /* Single record. Just do blocking lock. */ return tdb_brlock(tdb, ltype, off, len, flags); } /* First we try non-blocking. */ ret = tdb_brlock(tdb, ltype, off, len, nb_flags); if (ret == 0) { return 0; } /* Try locking first half, then second. */ ret = tdb_chainlock_gradual(tdb, ltype, flags, off, len / 2); if (ret == -1) return -1; ret = tdb_chainlock_gradual(tdb, ltype, flags, off + len / 2, len - len / 2); if (ret == -1) { tdb_brunlock(tdb, ltype, off, len / 2); return -1; } return 0; } /* lock/unlock entire database. It can only be upgradable if you have some * other way of guaranteeing exclusivity (ie. transaction write lock). * We do the locking gradually to avoid being starved by smaller locks. */ int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable) { int ret; switch (tdb_allrecord_check(tdb, ltype, flags, upgradable)) { case -1: return -1; case 0: return 0; } /* We cover two kinds of locks: * 1) Normal chain locks. Taken for almost all operations. * 2) Individual records locks. Taken after normal or free * chain locks. * * It is (1) which cause the starvation problem, so we're only * gradual for that. */ if (tdb_have_mutexes(tdb)) { ret = tdb_mutex_allrecord_lock(tdb, ltype, flags); } else { ret = tdb_chainlock_gradual(tdb, ltype, flags, FREELIST_TOP, tdb->hash_size * 4); } if (ret == -1) { return -1; } /* Grab individual record locks. */ if (tdb_brlock(tdb, ltype, lock_offset(tdb->hash_size), 0, flags) == -1) { if (tdb_have_mutexes(tdb)) { tdb_mutex_allrecord_unlock(tdb); } else { tdb_brunlock(tdb, ltype, FREELIST_TOP, tdb->hash_size * 4); } return -1; } tdb->allrecord_lock.count = 1; /* If it's upgradable, it's actually exclusive so we can treat * it as a write lock. */ tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype; tdb->allrecord_lock.off = upgradable; if (tdb_needs_recovery(tdb)) { bool mark = flags & TDB_LOCK_MARK_ONLY; tdb_allrecord_unlock(tdb, ltype, mark); if (mark) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall_mark cannot do recovery\n")); return -1; } if (tdb_lock_and_recover(tdb) == -1) { return -1; } return tdb_allrecord_lock(tdb, ltype, flags, upgradable); } return 0; } /* unlock entire db */ int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock) { /* There are no locks on read-only dbs */ if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.count == 0) { tdb->ecode = TDB_ERR_LOCK; return -1; } /* Upgradable locks are marked as write locks. */ if (tdb->allrecord_lock.ltype != (uint32_t)ltype && (!tdb->allrecord_lock.off || ltype != F_RDLCK)) { tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->allrecord_lock.count > 1) { tdb->allrecord_lock.count--; return 0; } if (!mark_lock) { int ret; if (tdb_have_mutexes(tdb)) { ret = tdb_mutex_allrecord_unlock(tdb); if (ret == 0) { ret = tdb_brunlock(tdb, ltype, lock_offset(tdb->hash_size), 0); } } else { ret = tdb_brunlock(tdb, ltype, FREELIST_TOP, 0); } if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed " "(%s)\n", strerror(errno))); return -1; } } tdb->allrecord_lock.count = 0; tdb->allrecord_lock.ltype = 0; return 0; } /* lock entire database with write lock */ _PUBLIC_ int tdb_lockall(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall"); return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); } /* lock entire database with write lock - mark only */ _PUBLIC_ int tdb_lockall_mark(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_mark"); return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY, false); } /* unlock entire database with write lock - unmark only */ _PUBLIC_ int tdb_lockall_unmark(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_unmark"); return tdb_allrecord_unlock(tdb, F_WRLCK, true); } /* lock entire database with write lock - nonblocking varient */ _PUBLIC_ int tdb_lockall_nonblock(struct tdb_context *tdb) { int ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret); return ret; } /* unlock entire database with write lock */ _PUBLIC_ int tdb_unlockall(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_unlockall"); return tdb_allrecord_unlock(tdb, F_WRLCK, false); } /* lock entire database with read lock */ _PUBLIC_ int tdb_lockall_read(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_read"); return tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); } /* lock entire database with read lock - nonblock varient */ _PUBLIC_ int tdb_lockall_read_nonblock(struct tdb_context *tdb) { int ret = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_NOWAIT, false); tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret); return ret; } /* unlock entire database with read lock */ _PUBLIC_ int tdb_unlockall_read(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_unlockall_read"); return tdb_allrecord_unlock(tdb, F_RDLCK, false); } /* lock/unlock one hash chain. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ _PUBLIC_ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); tdb_trace_1rec(tdb, "tdb_chainlock", key); return ret; } /* lock/unlock one hash chain, non-blocking. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ _PUBLIC_ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret); return ret; } /* mark a chain as locked without actually locking it. Warning! use with great caution! */ _PUBLIC_ int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_nest_lock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), F_WRLCK, TDB_LOCK_MARK_ONLY); tdb_trace_1rec(tdb, "tdb_chainlock_mark", key); return ret; } /* unmark a chain as locked without actually locking it. Warning! use with great caution! */ _PUBLIC_ int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key); return tdb_nest_unlock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), F_WRLCK, true); } _PUBLIC_ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainunlock", key); return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } _PUBLIC_ int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) { int ret; ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); tdb_trace_1rec(tdb, "tdb_chainlock_read", key); return ret; } _PUBLIC_ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainunlock_read", key); return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); } _PUBLIC_ int tdb_chainlock_read_nonblock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); tdb_trace_1rec_ret(tdb, "tdb_chainlock_read_nonblock", key, ret); return ret; } /* record lock stops delete underneath */ int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) { if (tdb->allrecord_lock.count) { return 0; } return off ? tdb_brlock(tdb, F_RDLCK, off, 1, TDB_LOCK_WAIT) : 0; } /* Write locks override our own fcntl readlocks, so check it here. Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not an error to fail to get the lock here. */ int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off) { struct tdb_traverse_lock *i; if (tdb == NULL) { return -1; } for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) return -1; if (tdb->allrecord_lock.count) { if (tdb->allrecord_lock.ltype == F_WRLCK) { return 0; } return -1; } return tdb_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); } int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off) { if (tdb->allrecord_lock.count) { return 0; } return tdb_brunlock(tdb, F_WRLCK, off, 1); } /* fcntl locks don't stack: avoid unlocking someone else's */ int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) { struct tdb_traverse_lock *i; uint32_t count = 0; if (tdb->allrecord_lock.count) { return 0; } if (off == 0) return 0; for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) count++; return (count == 1 ? tdb_brunlock(tdb, F_RDLCK, off, 1) : 0); } bool tdb_have_extra_locks(struct tdb_context *tdb) { unsigned int extra = tdb->num_lockrecs; /* A transaction holds the lock for all records. */ if (!tdb->transaction && tdb->allrecord_lock.count) { return true; } /* We always hold the active lock if CLEAR_IF_FIRST. */ if (find_nestlock(tdb, ACTIVE_LOCK)) { extra--; } /* In a transaction, we expect to hold the transaction lock */ if (tdb->transaction && find_nestlock(tdb, TRANSACTION_LOCK)) { extra--; } return extra; } /* The transaction code uses this to remove all locks. */ void tdb_release_transaction_locks(struct tdb_context *tdb) { int i; unsigned int active = 0; if (tdb->allrecord_lock.count != 0) { tdb_allrecord_unlock(tdb, tdb->allrecord_lock.ltype, false); tdb->allrecord_lock.count = 0; } for (i=0;inum_lockrecs;i++) { struct tdb_lock_type *lck = &tdb->lockrecs[i]; /* Don't release the active lock! Copy it to first entry. */ if (lck->off == ACTIVE_LOCK) { tdb->lockrecs[active++] = *lck; } else { tdb_brunlock(tdb, lck->ltype, lck->off, 1); } } tdb->num_lockrecs = active; } /* Following functions are added specifically to support CTDB. */ /* Don't do actual fcntl locking, just mark tdb locked */ int tdb_transaction_write_lock_mark(struct tdb_context *tdb); _PUBLIC_ int tdb_transaction_write_lock_mark(struct tdb_context *tdb) { return tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY); } /* Don't do actual fcntl unlocking, just mark tdb unlocked */ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb); _PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb) { return tdb_nest_unlock(tdb, TRANSACTION_LOCK, F_WRLCK, true); } ldb-2.0.8/lib/tdb/common/mutex.c0000660000000000000000000005501013100601766016334 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. trivial database library Copyright (C) Volker Lendecke 2012,2013 Copyright (C) Stefan Metzmacher 2013,2014 Copyright (C) Michael Adam 2014 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" #include "system/threads.h" #ifdef USE_TDB_MUTEX_LOCKING /* * If we run with mutexes, we store the "struct tdb_mutexes" at the * beginning of the file. We store an additional tdb_header right * beyond the mutex area, page aligned. All the offsets within the tdb * are relative to the area behind the mutex area. tdb->map_ptr points * behind the mmap area as well, so the read and write path in the * mutex case can remain unchanged. * * Early in the mutex development the mutexes were placed between the hash * chain pointers and the real tdb data. This had two drawbacks: First, it * made pointer calculations more complex. Second, we had to mmap the mutex * area twice. One was the normal map_ptr in the tdb. This frequently changed * from within tdb_oob. At least the Linux glibc robust mutex code assumes * constant pointers in memory, so a constantly changing mmap area destroys * the mutex list. So we had to mmap the first bytes of the file with a second * mmap call. With that scheme, very weird errors happened that could be * easily fixed by doing the mutex mmap in a second file. It seemed that * mapping the same memory area twice does not end up in accessing the same * physical page, looking at the mutexes in gdb it seemed that old data showed * up after some re-mapping. To avoid a separate mutex file, the code now puts * the real content of the tdb file after the mutex area. This way we do not * have overlapping mmap areas, the mutex area is mmapped once and not * changed, the tdb data area's mmap is constantly changed but does not * overlap. */ struct tdb_mutexes { struct tdb_header hdr; /* protect allrecord_lock */ pthread_mutex_t allrecord_mutex; /* * F_UNLCK: free, * F_RDLCK: shared, * F_WRLCK: exclusive */ short int allrecord_lock; /* * Index 0 is the freelist mutex, followed by * one mutex per hashchain. */ pthread_mutex_t hashchains[1]; }; bool tdb_have_mutexes(struct tdb_context *tdb) { return ((tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) != 0); } size_t tdb_mutex_size(struct tdb_context *tdb) { size_t mutex_size; if (!tdb_have_mutexes(tdb)) { return 0; } mutex_size = sizeof(struct tdb_mutexes); mutex_size += tdb->hash_size * sizeof(pthread_mutex_t); return TDB_ALIGN(mutex_size, tdb->page_size); } /* * Get the index for a chain mutex */ static bool tdb_mutex_index(struct tdb_context *tdb, off_t off, off_t len, unsigned *idx) { /* * Weird but true: We fcntl lock 1 byte at an offset 4 bytes before * the 4 bytes of the freelist start and the hash chain that is about * to be locked. See lock_offset() where the freelist is -1 vs the * "+1" in TDB_HASH_TOP(). Because the mutex array is represented in * the tdb file itself as data, we need to adjust the offset here. */ const off_t freelist_lock_ofs = FREELIST_TOP - sizeof(tdb_off_t); if (!tdb_have_mutexes(tdb)) { return false; } if (len != 1) { /* Possibly the allrecord lock */ return false; } if (off < freelist_lock_ofs) { /* One of the special locks */ return false; } if (tdb->hash_size == 0) { /* tdb not initialized yet, called from tdb_open_ex() */ return false; } if (off >= TDB_DATA_START(tdb->hash_size)) { /* Single record lock from traverses */ return false; } /* * Now we know it's a freelist or hash chain lock. Those are always 4 * byte aligned. Paranoia check. */ if ((off % sizeof(tdb_off_t)) != 0) { abort(); } /* * Re-index the fcntl offset into an offset into the mutex array */ off -= freelist_lock_ofs; /* rebase to index 0 */ off /= sizeof(tdb_off_t); /* 0 for freelist 1-n for hashchain */ *idx = off; return true; } static bool tdb_have_mutex_chainlocks(struct tdb_context *tdb) { size_t i; for (i=0; i < tdb->num_lockrecs; i++) { bool ret; unsigned idx; ret = tdb_mutex_index(tdb, tdb->lockrecs[i].off, tdb->lockrecs[i].count, &idx); if (!ret) { continue; } if (idx == 0) { /* this is the freelist mutex */ continue; } return true; } return false; } static int chain_mutex_lock(pthread_mutex_t *m, bool waitflag) { int ret; if (waitflag) { ret = pthread_mutex_lock(m); } else { ret = pthread_mutex_trylock(m); } if (ret != EOWNERDEAD) { return ret; } /* * For chainlocks, we don't do any cleanup (yet?) */ return pthread_mutex_consistent(m); } static int allrecord_mutex_lock(struct tdb_mutexes *m, bool waitflag) { int ret; if (waitflag) { ret = pthread_mutex_lock(&m->allrecord_mutex); } else { ret = pthread_mutex_trylock(&m->allrecord_mutex); } if (ret != EOWNERDEAD) { return ret; } /* * The allrecord lock holder died. We need to reset the allrecord_lock * to F_UNLCK. This should also be the indication for * tdb_needs_recovery. */ m->allrecord_lock = F_UNLCK; return pthread_mutex_consistent(&m->allrecord_mutex); } bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, bool waitflag, int *pret) { struct tdb_mutexes *m = tdb->mutexes; pthread_mutex_t *chain; int ret; unsigned idx; bool allrecord_ok; if (!tdb_mutex_index(tdb, off, len, &idx)) { return false; } chain = &m->hashchains[idx]; again: ret = chain_mutex_lock(chain, waitflag); if (ret == EBUSY) { ret = EAGAIN; } if (ret != 0) { errno = ret; goto fail; } if (idx == 0) { /* * This is a freelist lock, which is independent to * the allrecord lock. So we're done once we got the * freelist mutex. */ *pret = 0; return true; } if (tdb_have_mutex_chainlocks(tdb)) { /* * We can only check the allrecord lock once. If we do it with * one chain mutex locked, we will deadlock with the allrecord * locker process in the following way: We lock the first hash * chain, we check for the allrecord lock. We keep the hash * chain locked. Then the allrecord locker locks the * allrecord_mutex. It walks the list of chain mutexes, * locking them all in sequence. Meanwhile, we have the chain * mutex locked, so the allrecord locker blocks trying to lock * our chain mutex. Then we come in and try to lock the second * chain lock, which in most cases will be the freelist. We * see that the allrecord lock is locked and put ourselves on * the allrecord_mutex. This will never be signalled though * because the allrecord locker waits for us to give up the * chain lock. */ *pret = 0; return true; } /* * Check if someone is has the allrecord lock: queue if so. */ allrecord_ok = false; if (m->allrecord_lock == F_UNLCK) { /* * allrecord lock not taken */ allrecord_ok = true; } if ((m->allrecord_lock == F_RDLCK) && (rw == F_RDLCK)) { /* * allrecord shared lock taken, but we only want to read */ allrecord_ok = true; } if (allrecord_ok) { *pret = 0; return true; } ret = pthread_mutex_unlock(chain); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(chain_mutex) failed: %s\n", strerror(ret))); errno = ret; goto fail; } ret = allrecord_mutex_lock(m, waitflag); if (ret == EBUSY) { ret = EAGAIN; } if (ret != 0) { if (waitflag || (ret != EAGAIN)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_%slock" "(allrecord_mutex) failed: %s\n", waitflag ? "" : "try_", strerror(ret))); } errno = ret; goto fail; } ret = pthread_mutex_unlock(&m->allrecord_mutex); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(allrecord_mutex) failed: %s\n", strerror(ret))); errno = ret; goto fail; } goto again; fail: *pret = -1; return true; } bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, int *pret) { struct tdb_mutexes *m = tdb->mutexes; pthread_mutex_t *chain; int ret; unsigned idx; if (!tdb_mutex_index(tdb, off, len, &idx)) { return false; } chain = &m->hashchains[idx]; ret = pthread_mutex_unlock(chain); if (ret == 0) { *pret = 0; return true; } errno = ret; *pret = -1; return true; } int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags) { struct tdb_mutexes *m = tdb->mutexes; int ret; uint32_t i; bool waitflag = (flags & TDB_LOCK_WAIT); int saved_errno; if (tdb->flags & TDB_NOLOCK) { return 0; } if (flags & TDB_LOCK_MARK_ONLY) { return 0; } ret = allrecord_mutex_lock(m, waitflag); if (!waitflag && (ret == EBUSY)) { errno = EAGAIN; tdb->ecode = TDB_ERR_LOCK; return -1; } if (ret != 0) { if (!(flags & TDB_LOCK_PROBE)) { TDB_LOG((tdb, TDB_DEBUG_TRACE, "allrecord_mutex_lock() failed: %s\n", strerror(ret))); } tdb->ecode = TDB_ERR_LOCK; return -1; } if (m->allrecord_lock != F_UNLCK) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); goto fail_unlock_allrecord_mutex; } m->allrecord_lock = (ltype == F_RDLCK) ? F_RDLCK : F_WRLCK; for (i=0; ihash_size; i++) { /* ignore hashchains[0], the freelist */ pthread_mutex_t *chain = &m->hashchains[i+1]; ret = chain_mutex_lock(chain, waitflag); if (!waitflag && (ret == EBUSY)) { errno = EAGAIN; goto fail_unroll_allrecord_lock; } if (ret != 0) { if (!(flags & TDB_LOCK_PROBE)) { TDB_LOG((tdb, TDB_DEBUG_TRACE, "chain_mutex_lock() failed: %s\n", strerror(ret))); } errno = ret; goto fail_unroll_allrecord_lock; } ret = pthread_mutex_unlock(chain); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(chainlock) failed: %s\n", strerror(ret))); errno = ret; goto fail_unroll_allrecord_lock; } } /* * We leave this routine with m->allrecord_mutex locked */ return 0; fail_unroll_allrecord_lock: m->allrecord_lock = F_UNLCK; fail_unlock_allrecord_mutex: saved_errno = errno; ret = pthread_mutex_unlock(&m->allrecord_mutex); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(allrecord_mutex) failed: %s\n", strerror(ret))); } errno = saved_errno; tdb->ecode = TDB_ERR_LOCK; return -1; } int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) { struct tdb_mutexes *m = tdb->mutexes; int ret; uint32_t i; if (tdb->flags & TDB_NOLOCK) { return 0; } /* * Our only caller tdb_allrecord_upgrade() * garantees that we already own the allrecord lock. * * Which means m->allrecord_mutex is still locked by us. */ if (m->allrecord_lock != F_RDLCK) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); return -1; } m->allrecord_lock = F_WRLCK; for (i=0; ihash_size; i++) { /* ignore hashchains[0], the freelist */ pthread_mutex_t *chain = &m->hashchains[i+1]; ret = chain_mutex_lock(chain, true); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_lock" "(chainlock) failed: %s\n", strerror(ret))); goto fail_unroll_allrecord_lock; } ret = pthread_mutex_unlock(chain); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(chainlock) failed: %s\n", strerror(ret))); goto fail_unroll_allrecord_lock; } } return 0; fail_unroll_allrecord_lock: m->allrecord_lock = F_RDLCK; tdb->ecode = TDB_ERR_LOCK; return -1; } void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) { struct tdb_mutexes *m = tdb->mutexes; /* * Our only caller tdb_allrecord_upgrade() (in the error case) * garantees that we already own the allrecord lock. * * Which means m->allrecord_mutex is still locked by us. */ if (m->allrecord_lock != F_WRLCK) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); return; } m->allrecord_lock = F_RDLCK; return; } int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) { struct tdb_mutexes *m = tdb->mutexes; short old; int ret; if (tdb->flags & TDB_NOLOCK) { return 0; } /* * Our only callers tdb_allrecord_unlock() and * tdb_allrecord_lock() (in the error path) * garantee that we already own the allrecord lock. * * Which means m->allrecord_mutex is still locked by us. */ if ((m->allrecord_lock != F_RDLCK) && (m->allrecord_lock != F_WRLCK)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", (int)m->allrecord_lock)); return -1; } old = m->allrecord_lock; m->allrecord_lock = F_UNLCK; ret = pthread_mutex_unlock(&m->allrecord_mutex); if (ret != 0) { m->allrecord_lock = old; TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" "(allrecord_mutex) failed: %s\n", strerror(ret))); return -1; } return 0; } int tdb_mutex_init(struct tdb_context *tdb) { struct tdb_mutexes *m; pthread_mutexattr_t ma; int i, ret; ret = tdb_mutex_mmap(tdb); if (ret == -1) { return -1; } m = tdb->mutexes; ret = pthread_mutexattr_init(&ma); if (ret != 0) { goto fail_munmap; } ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { goto fail; } ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); if (ret != 0) { goto fail; } ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); if (ret != 0) { goto fail; } for (i=0; ihash_size+1; i++) { pthread_mutex_t *chain = &m->hashchains[i]; ret = pthread_mutex_init(chain, &ma); if (ret != 0) { goto fail; } } m->allrecord_lock = F_UNLCK; ret = pthread_mutex_init(&m->allrecord_mutex, &ma); if (ret != 0) { goto fail; } ret = 0; fail: pthread_mutexattr_destroy(&ma); fail_munmap: if (ret == 0) { return 0; } tdb_mutex_munmap(tdb); errno = ret; return -1; } int tdb_mutex_mmap(struct tdb_context *tdb) { size_t len; void *ptr; len = tdb_mutex_size(tdb); if (len == 0) { return 0; } if (tdb->mutexes != NULL) { return 0; } ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE, tdb->fd, 0); if (ptr == MAP_FAILED) { return -1; } tdb->mutexes = (struct tdb_mutexes *)ptr; return 0; } int tdb_mutex_munmap(struct tdb_context *tdb) { size_t len; int ret; len = tdb_mutex_size(tdb); if (len == 0) { return 0; } ret = munmap(tdb->mutexes, len); if (ret == -1) { return -1; } tdb->mutexes = NULL; return 0; } static bool tdb_mutex_locking_cached; static bool tdb_mutex_locking_supported(void) { pthread_mutexattr_t ma; pthread_mutex_t m; int ret; static bool initialized; if (initialized) { return tdb_mutex_locking_cached; } initialized = true; ret = pthread_mutexattr_init(&ma); if (ret != 0) { return false; } ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutex_init(&m, &ma); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutex_lock(&m); if (ret != 0) { goto cleanup_m; } /* * This makes sure we have real mutexes * from a threading library instead of just * stubs from libc. */ ret = pthread_mutex_lock(&m); if (ret != EDEADLK) { goto cleanup_lock; } ret = pthread_mutex_unlock(&m); if (ret != 0) { goto cleanup_m; } tdb_mutex_locking_cached = true; goto cleanup_m; cleanup_lock: pthread_mutex_unlock(&m); cleanup_m: pthread_mutex_destroy(&m); cleanup_ma: pthread_mutexattr_destroy(&ma); return tdb_mutex_locking_cached; } static void (*tdb_robust_mutext_old_handler)(int) = SIG_ERR; static pid_t tdb_robust_mutex_pid = -1; static bool tdb_robust_mutex_setup_sigchild(void (*handler)(int), void (**p_old_handler)(int)) { #ifdef HAVE_SIGACTION struct sigaction act; struct sigaction oldact; memset(&act, '\0', sizeof(act)); act.sa_handler = handler; #ifdef SA_RESTART act.sa_flags = SA_RESTART; #endif sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGCHLD); sigaction(SIGCHLD, &act, &oldact); if (p_old_handler) { *p_old_handler = oldact.sa_handler; } return true; #else /* !HAVE_SIGACTION */ return false; #endif } static void tdb_robust_mutex_handler(int sig) { pid_t child_pid = tdb_robust_mutex_pid; if (child_pid != -1) { pid_t pid; pid = waitpid(child_pid, NULL, WNOHANG); if (pid == -1) { switch (errno) { case ECHILD: tdb_robust_mutex_pid = -1; return; default: return; } } if (pid == child_pid) { tdb_robust_mutex_pid = -1; return; } } if (tdb_robust_mutext_old_handler == SIG_DFL) { return; } if (tdb_robust_mutext_old_handler == SIG_IGN) { return; } if (tdb_robust_mutext_old_handler == SIG_ERR) { return; } tdb_robust_mutext_old_handler(sig); } static void tdb_robust_mutex_wait_for_child(pid_t *child_pid) { int options = WNOHANG; if (*child_pid == -1) { return; } while (tdb_robust_mutex_pid > 0) { pid_t pid; /* * First we try with WNOHANG, as the process might not exist * anymore. Once we've sent SIGKILL we block waiting for the * exit. */ pid = waitpid(*child_pid, NULL, options); if (pid == -1) { if (errno == EINTR) { continue; } else if (errno == ECHILD) { break; } else { abort(); } } if (pid == *child_pid) { break; } kill(*child_pid, SIGKILL); options = 0; } tdb_robust_mutex_pid = -1; *child_pid = -1; } _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) { void *ptr = NULL; pthread_mutex_t *m = NULL; pthread_mutexattr_t ma; int ret = 1; int pipe_down[2] = { -1, -1 }; int pipe_up[2] = { -1, -1 }; ssize_t nread; char c = 0; bool ok; static bool initialized; pid_t saved_child_pid = -1; bool cleanup_ma = false; if (initialized) { return tdb_mutex_locking_cached; } initialized = true; ok = tdb_mutex_locking_supported(); if (!ok) { return false; } tdb_mutex_locking_cached = false; ptr = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1 /* fd */, 0); if (ptr == MAP_FAILED) { return false; } ret = pipe(pipe_down); if (ret != 0) { goto cleanup; } ret = pipe(pipe_up); if (ret != 0) { goto cleanup; } ret = pthread_mutexattr_init(&ma); if (ret != 0) { goto cleanup; } cleanup_ma = true; ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { goto cleanup; } ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); if (ret != 0) { goto cleanup; } ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); if (ret != 0) { goto cleanup; } ret = pthread_mutex_init(ptr, &ma); if (ret != 0) { goto cleanup; } m = (pthread_mutex_t *)ptr; if (tdb_robust_mutex_setup_sigchild(tdb_robust_mutex_handler, &tdb_robust_mutext_old_handler) == false) { goto cleanup; } tdb_robust_mutex_pid = fork(); saved_child_pid = tdb_robust_mutex_pid; if (tdb_robust_mutex_pid == 0) { size_t nwritten; close(pipe_down[1]); close(pipe_up[0]); ret = pthread_mutex_lock(m); nwritten = write(pipe_up[1], &ret, sizeof(ret)); if (nwritten != sizeof(ret)) { _exit(1); } if (ret != 0) { _exit(1); } nread = read(pipe_down[0], &c, 1); if (nread != 1) { _exit(1); } /* leave locked */ _exit(0); } if (tdb_robust_mutex_pid == -1) { goto cleanup; } close(pipe_down[0]); pipe_down[0] = -1; close(pipe_up[1]); pipe_up[1] = -1; nread = read(pipe_up[0], &ret, sizeof(ret)); if (nread != sizeof(ret)) { goto cleanup; } ret = pthread_mutex_trylock(m); if (ret != EBUSY) { if (ret == 0) { pthread_mutex_unlock(m); } goto cleanup; } if (write(pipe_down[1], &c, 1) != 1) { goto cleanup; } nread = read(pipe_up[0], &c, 1); if (nread != 0) { goto cleanup; } tdb_robust_mutex_wait_for_child(&saved_child_pid); ret = pthread_mutex_trylock(m); if (ret != EOWNERDEAD) { if (ret == 0) { pthread_mutex_unlock(m); } goto cleanup; } ret = pthread_mutex_consistent(m); if (ret != 0) { goto cleanup; } ret = pthread_mutex_trylock(m); if (ret != EDEADLK && ret != EBUSY) { pthread_mutex_unlock(m); goto cleanup; } ret = pthread_mutex_unlock(m); if (ret != 0) { goto cleanup; } tdb_mutex_locking_cached = true; cleanup: /* * Note that we don't reset the signal handler we just reset * tdb_robust_mutex_pid to -1. This is ok as this code path is only * called once per process. * * Leaving our signal handler avoids races with other threads potentialy * setting up their SIGCHLD handlers. * * The worst thing that can happen is that the other newer signal * handler will get the SIGCHLD signal for our child and/or reap the * child with a wait() function. tdb_robust_mutex_wait_for_child() * handles the case where waitpid returns ECHILD. */ tdb_robust_mutex_wait_for_child(&saved_child_pid); if (m != NULL) { pthread_mutex_destroy(m); } if (cleanup_ma) { pthread_mutexattr_destroy(&ma); } if (pipe_down[0] != -1) { close(pipe_down[0]); } if (pipe_down[1] != -1) { close(pipe_down[1]); } if (pipe_up[0] != -1) { close(pipe_up[0]); } if (pipe_up[1] != -1) { close(pipe_up[1]); } if (ptr != NULL) { munmap(ptr, sizeof(pthread_mutex_t)); } return tdb_mutex_locking_cached; } #else size_t tdb_mutex_size(struct tdb_context *tdb) { return 0; } bool tdb_have_mutexes(struct tdb_context *tdb) { return false; } int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags) { tdb->ecode = TDB_ERR_LOCK; return -1; } int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) { return -1; } int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) { tdb->ecode = TDB_ERR_LOCK; return -1; } void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) { return; } int tdb_mutex_mmap(struct tdb_context *tdb) { errno = ENOSYS; return -1; } int tdb_mutex_munmap(struct tdb_context *tdb) { errno = ENOSYS; return -1; } int tdb_mutex_init(struct tdb_context *tdb) { errno = ENOSYS; return -1; } _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) { return false; } #endif ldb-2.0.8/lib/tdb/common/open.c0000660000000000000000000006055013573675413016156 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ static struct tdb_context *tdbs = NULL; /* We use two hashes to double-check they're using the right hash function. */ void tdb_header_hash(struct tdb_context *tdb, uint32_t *magic1_hash, uint32_t *magic2_hash) { TDB_DATA hash_key; uint32_t tdb_magic = TDB_MAGIC; hash_key.dptr = discard_const_p(unsigned char, TDB_MAGIC_FOOD); hash_key.dsize = sizeof(TDB_MAGIC_FOOD); *magic1_hash = tdb->hash_fn(&hash_key); hash_key.dptr = (unsigned char *)CONVERT(tdb_magic); hash_key.dsize = sizeof(tdb_magic); *magic2_hash = tdb->hash_fn(&hash_key); /* Make sure at least one hash is non-zero! */ if (*magic1_hash == 0 && *magic2_hash == 0) *magic1_hash = 1; } /* initialise a new database with a specified hash size */ static int tdb_new_database(struct tdb_context *tdb, struct tdb_header *header, int hash_size) { struct tdb_header *newdb; size_t size; int ret = -1; /* We make it up in memory, then write it out if not internal */ size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t); if (!(newdb = (struct tdb_header *)calloc(size, 1))) { tdb->ecode = TDB_ERR_OOM; return -1; } /* Fill in the header */ newdb->version = TDB_VERSION; newdb->hash_size = hash_size; tdb_header_hash(tdb, &newdb->magic1_hash, &newdb->magic2_hash); /* Make sure older tdbs (which don't check the magic hash fields) * will refuse to open this TDB. */ if (tdb->flags & TDB_INCOMPATIBLE_HASH) newdb->rwlocks = TDB_HASH_RWLOCK_MAGIC; /* * We create a tdb with TDB_FEATURE_FLAG_MUTEX support, * the flag combination and runtime feature checks * are done by the caller already. */ if (tdb->flags & TDB_MUTEX_LOCKING) { newdb->feature_flags |= TDB_FEATURE_FLAG_MUTEX; } /* * If we have any features we add the FEATURE_FLAG_MAGIC, overwriting the * TDB_HASH_RWLOCK_MAGIC above. */ if (newdb->feature_flags != 0) { newdb->rwlocks = TDB_FEATURE_FLAG_MAGIC; } /* * It's required for some following code pathes * to have the fields on 'tdb' up-to-date. * * E.g. tdb_mutex_size() requires it */ tdb->feature_flags = newdb->feature_flags; tdb->hash_size = newdb->hash_size; if (tdb->flags & TDB_INTERNAL) { tdb->map_size = size; tdb->map_ptr = (char *)newdb; memcpy(header, newdb, sizeof(*header)); /* Convert the `ondisk' version if asked. */ CONVERT(*newdb); return 0; } if (lseek(tdb->fd, 0, SEEK_SET) == -1) goto fail; if (ftruncate(tdb->fd, 0) == -1) goto fail; if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { newdb->mutex_size = tdb_mutex_size(tdb); tdb->hdr_ofs = newdb->mutex_size; } /* This creates an endian-converted header, as if read from disk */ CONVERT(*newdb); memcpy(header, newdb, sizeof(*header)); /* Don't endian-convert the magic food! */ memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); if (!tdb_write_all(tdb->fd, newdb, size)) goto fail; if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { /* * Now we init the mutex area * followed by a second header. */ ret = ftruncate( tdb->fd, newdb->mutex_size + sizeof(struct tdb_header)); if (ret == -1) { goto fail; } ret = tdb_mutex_init(tdb); if (ret == -1) { goto fail; } /* * Write a second header behind the mutexes. That's the area * that will be mmapp'ed. */ ret = lseek(tdb->fd, newdb->mutex_size, SEEK_SET); if (ret == -1) { goto fail; } if (!tdb_write_all(tdb->fd, newdb, size)) { goto fail; } } ret = 0; fail: SAFE_FREE(newdb); return ret; } static int tdb_already_open(dev_t device, ino_t ino) { struct tdb_context *i; for (i = tdbs; i; i = i->next) { if (i->device == device && i->inode == ino) { return 1; } } return 0; } /* open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the database file. A flags value of O_WRONLY is invalid. The hash size is advisory, use zero for a default value. Return is NULL on error, in which case errno is also set. Don't try to call tdb_error or tdb_errname, just do strerror(errno). @param name may be NULL for internal databases. */ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); } /* a default logging function */ static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { } static bool check_header_hash(struct tdb_context *tdb, struct tdb_header *header, bool default_hash, uint32_t *m1, uint32_t *m2) { tdb_header_hash(tdb, m1, m2); if (header->magic1_hash == *m1 && header->magic2_hash == *m2) { return true; } /* If they explicitly set a hash, always respect it. */ if (!default_hash) return false; /* Otherwise, try the other inbuilt hash. */ if (tdb->hash_fn == tdb_old_hash) tdb->hash_fn = tdb_jenkins_hash; else tdb->hash_fn = tdb_old_hash; return check_header_hash(tdb, header, false, m1, m2); } static bool tdb_mutex_open_ok(struct tdb_context *tdb, const struct tdb_header *header) { if (tdb->flags & TDB_NOLOCK) { /* * We don't look at locks, so it does not matter to have a * compatible mutex implementation. Allow the open. */ return true; } if (!(tdb->flags & TDB_MUTEX_LOCKING)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " "Can use mutexes only with " "MUTEX_LOCKING or NOLOCK\n", tdb->name)); return false; } if (tdb_mutex_size(tdb) != header->mutex_size) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " "Mutex size changed from %"PRIu32" to %zu\n.", tdb->name, header->mutex_size, tdb_mutex_size(tdb))); return false; } return true; } _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn) { int orig_errno = errno; struct tdb_header header = { .version = 0, }; struct tdb_context *tdb; struct stat st; int rev = 0; bool locked = false; unsigned char *vp; uint32_t vertest; unsigned v; const char *hash_alg; uint32_t magic1, magic2; int ret; if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { /* Can't log this */ errno = ENOMEM; goto fail; } tdb_io_init(tdb); if (tdb_flags & TDB_INTERNAL) { tdb_flags |= TDB_INCOMPATIBLE_HASH; } if (tdb_flags & TDB_MUTEX_LOCKING) { tdb_flags |= TDB_INCOMPATIBLE_HASH; } tdb->fd = -1; #ifdef TDB_TRACE tdb->tracefd = -1; #endif tdb->name = NULL; tdb->map_ptr = NULL; tdb->flags = tdb_flags; tdb->open_flags = open_flags; if (log_ctx) { tdb->log = *log_ctx; } else { tdb->log.log_fn = null_log_fn; tdb->log.log_private = NULL; } if (name == NULL && (tdb_flags & TDB_INTERNAL)) { name = "__TDB_INTERNAL__"; } if (name == NULL) { tdb->name = discard_const_p(char, "__NULL__"); TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n")); tdb->name = NULL; errno = EINVAL; goto fail; } /* now make a copy of the name, as the caller memory might go away */ if (!(tdb->name = (char *)strdup(name))) { /* * set the name as the given string, so that tdb_name() will * work in case of an error. */ tdb->name = discard_const_p(char, name); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n", name)); tdb->name = NULL; errno = ENOMEM; goto fail; } if (hash_fn) { tdb->hash_fn = hash_fn; hash_alg = "the user defined"; } else { /* This controls what we use when creating a tdb. */ if (tdb->flags & TDB_INCOMPATIBLE_HASH) { tdb->hash_fn = tdb_jenkins_hash; } else { tdb->hash_fn = tdb_old_hash; } hash_alg = "either default"; } /* cache the page size */ tdb->page_size = getpagesize(); if (tdb->page_size <= 0) { tdb->page_size = 0x2000; } tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0; if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", name)); errno = EINVAL; goto fail; } if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE; if ((open_flags & O_ACCMODE) == O_RDONLY) { tdb->read_only = 1; /* read only databases don't do locking or clear if first */ tdb->flags |= TDB_NOLOCK; tdb->flags &= ~(TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING); } if ((tdb->flags & TDB_ALLOW_NESTING) && (tdb->flags & TDB_DISALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "allow_nesting and disallow_nesting are not allowed together!")); errno = EINVAL; goto fail; } if (tdb->flags & TDB_MUTEX_LOCKING) { /* * Here we catch bugs in the callers, * the runtime check for existing tdb's comes later. */ if (tdb->flags & TDB_INTERNAL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING and " "TDB_INTERNAL are not allowed together\n", name)); errno = EINVAL; goto fail; } if (tdb->flags & TDB_NOMMAP) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING and " "TDB_NOMMAP are not allowed together\n", name)); errno = EINVAL; goto fail; } if (tdb->read_only) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING " "not allowed read only\n", name)); errno = EINVAL; goto fail; } /* * The callers should have called * tdb_runtime_check_for_robust_mutexes() * before using TDB_MUTEX_LOCKING! * * This makes sure the caller understands * that the locking may behave a bit differently * than with pure fcntl locking. E.g. multiple * read locks are not supported. */ if (!tdb_runtime_check_for_robust_mutexes()) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "invalid flags for %s - TDB_MUTEX_LOCKING " "requires support for robust_mutexes\n", name)); errno = ENOSYS; goto fail; } } if (getenv("TDB_NO_FSYNC")) { tdb->flags |= TDB_NOSYNC; } /* * TDB_ALLOW_NESTING is the default behavior. * Note: this may change in future versions! */ if (!(tdb->flags & TDB_DISALLOW_NESTING)) { tdb->flags |= TDB_ALLOW_NESTING; } /* internal databases don't mmap or lock, and start off cleared */ if (tdb->flags & TDB_INTERNAL) { tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); tdb->flags &= ~TDB_CLEAR_IF_FIRST; if (tdb_new_database(tdb, &header, hash_size) != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!")); goto fail; } tdb->hash_size = hash_size; goto internal; } if ((tdb->fd = open(name, open_flags, mode)) == -1) { TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n", name, strerror(errno))); goto fail; /* errno set by open(2) */ } /* on exec, don't inherit the fd */ v = fcntl(tdb->fd, F_GETFD, 0); fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); /* ensure there is only one process initialising at once */ if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n", name, strerror(errno))); goto fail; /* errno set by tdb_brlock */ } /* we need to zero database if we are the only one with it open */ if ((tdb_flags & TDB_CLEAR_IF_FIRST) && (!tdb->read_only)) { ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); locked = (ret == 0); if (locked) { ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "tdb_brlock failed for %s: %s\n", name, strerror(errno))); goto fail; } ret = tdb_new_database(tdb, &header, hash_size); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "tdb_new_database failed for " "%s: %s\n", name, strerror(errno))); tdb_unlockall(tdb); goto fail; } ret = tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "tdb_unlockall failed for %s: %s\n", name, strerror(errno))); goto fail; } ret = lseek(tdb->fd, 0, SEEK_SET); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "lseek failed for %s: %s\n", name, strerror(errno))); goto fail; } } } errno = 0; if (read(tdb->fd, &header, sizeof(header)) != sizeof(header) || strcmp(header.magic_food, TDB_MAGIC_FOOD) != 0) { if (!(open_flags & O_CREAT) || tdb_new_database(tdb, &header, hash_size) == -1) { if (errno == 0) { errno = EIO; /* ie bad format or something */ } goto fail; } rev = (tdb->flags & TDB_CONVERT); } else if (header.version != TDB_VERSION && !(rev = (header.version==TDB_BYTEREV(TDB_VERSION)))) { /* wrong version */ errno = EIO; goto fail; } vp = (unsigned char *)&header.version; vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; if (!rev) tdb->flags &= ~TDB_CONVERT; else { tdb->flags |= TDB_CONVERT; tdb_convert(&header, sizeof(header)); } /* * We only use st.st_dev and st.st_ino from the raw fstat() * call, everything else needs to use tdb_fstat() in order * to skip tdb->hdr_ofs! */ if (fstat(tdb->fd, &st) == -1) { goto fail; } tdb->device = st.st_dev; tdb->inode = st.st_ino; ZERO_STRUCT(st); if (header.rwlocks != 0 && header.rwlocks != TDB_FEATURE_FLAG_MAGIC && header.rwlocks != TDB_HASH_RWLOCK_MAGIC) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n")); errno = ENOSYS; goto fail; } if (header.hash_size == 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: invalid database: 0 hash_size\n")); errno = ENOSYS; goto fail; } tdb->hash_size = header.hash_size; if (header.rwlocks == TDB_FEATURE_FLAG_MAGIC) { tdb->feature_flags = header.feature_flags; } if (tdb->feature_flags & ~TDB_SUPPORTED_FEATURE_FLAGS) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: unsupported " "features in tdb %s: 0x%08x (supported: 0x%08x)\n", name, (unsigned)tdb->feature_flags, (unsigned)TDB_SUPPORTED_FEATURE_FLAGS)); errno = ENOSYS; goto fail; } if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { if (!tdb_mutex_open_ok(tdb, &header)) { errno = EINVAL; goto fail; } /* * We need to remember the hdr_ofs * also for the TDB_NOLOCK case * if the current library doesn't support * mutex locking. */ tdb->hdr_ofs = header.mutex_size; if ((!(tdb_flags & TDB_CLEAR_IF_FIRST)) && (!tdb->read_only)) { /* * Open an existing mutexed tdb, but without * CLEAR_IF_FIRST. We need to initialize the * mutex array and keep the CLEAR_IF_FIRST * lock locked. */ ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); locked = (ret == 0); if (locked) { ret = tdb_mutex_init(tdb); if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: tdb_mutex_init " "failed for ""%s: %s\n", name, strerror(errno))); goto fail; } } } } if ((header.magic1_hash == 0) && (header.magic2_hash == 0)) { /* older TDB without magic hash references */ tdb->hash_fn = tdb_old_hash; } else if (!check_header_hash(tdb, &header, !hash_fn, &magic1, &magic2)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " "%s was not created with %s hash function we are using\n" "magic1_hash[0x%08X %s 0x%08X] " "magic2_hash[0x%08X %s 0x%08X]\n", name, hash_alg, header.magic1_hash, (header.magic1_hash == magic1) ? "==" : "!=", magic1, header.magic2_hash, (header.magic2_hash == magic2) ? "==" : "!=", magic2)); errno = EINVAL; goto fail; } /* Is it already in the open list? If so, fail. */ if (tdb_already_open(tdb->device, tdb->inode)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " "%s (%d,%d) is already open in this process\n", name, (int)tdb->device, (int)tdb->inode)); errno = EBUSY; goto fail; } /* * We had tdb_mmap(tdb) here before, * but we need to use tdb_fstat(), * which is triggered from tdb_oob() before calling tdb_mmap(). * As this skips tdb->hdr_ofs. */ tdb->map_size = 0; ret = tdb_oob(tdb, 0, 1, 0); if (ret == -1) { errno = EIO; goto fail; } if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { if (!(tdb->flags & TDB_NOLOCK)) { ret = tdb_mutex_mmap(tdb); if (ret != 0) { goto fail; } } } 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_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: " "failed to release ACTIVE_LOCK on %s: %s\n", name, strerror(errno))); goto fail; } } if (locked || (tdb_flags & TDB_CLEAR_IF_FIRST)) { /* * We always need to do this if the CLEAR_IF_FIRST * flag is set, even if we didn't get the initial * exclusive lock as we need to let all other users * know we're using it. */ ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT); if (ret == -1) { goto fail; } } /* if needed, run recovery */ if (tdb_transaction_recover(tdb) == -1) { goto fail; } #ifdef TDB_TRACE { char tracefile[strlen(name) + 32]; snprintf(tracefile, sizeof(tracefile), "%s.trace.%li", name, (long)getpid()); tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600); if (tdb->tracefd >= 0) { tdb_enable_seqnum(tdb); tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags, open_flags); } else TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile)); } #endif internal: /* Internal (memory-only) databases skip all the code above to * do with disk files, and resume here by releasing their * open lock and hooking into the active list. */ if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) { goto fail; } tdb->next = tdbs; tdbs = tdb; errno = orig_errno; return tdb; fail: { int save_errno = errno; if (!tdb) return NULL; #ifdef TDB_TRACE close(tdb->tracefd); #endif if (tdb->map_ptr) { if (tdb->flags & TDB_INTERNAL) SAFE_FREE(tdb->map_ptr); else tdb_munmap(tdb); } if (tdb->fd != -1) if (close(tdb->fd) != 0) TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); SAFE_FREE(tdb->lockrecs); SAFE_FREE(tdb->name); SAFE_FREE(tdb); errno = save_errno; return NULL; } } /* * Set the maximum number of dead records per hash chain */ _PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) { tdb->max_dead_records = max_dead; } /** * Close a database. * * @returns -1 for error; 0 for success. **/ _PUBLIC_ int tdb_close(struct tdb_context *tdb) { struct tdb_context **i; int ret = 0; if (tdb->transaction) { tdb_transaction_cancel(tdb); } tdb_trace(tdb, "tdb_close"); if (tdb->map_ptr) { if (tdb->flags & TDB_INTERNAL) SAFE_FREE(tdb->map_ptr); else tdb_munmap(tdb); } tdb_mutex_munmap(tdb); SAFE_FREE(tdb->name); if (tdb->fd != -1) { ret = close(tdb->fd); tdb->fd = -1; } SAFE_FREE(tdb->lockrecs); /* Remove from contexts list */ for (i = &tdbs; *i; i = &(*i)->next) { if (*i == tdb) { *i = tdb->next; break; } } #ifdef TDB_TRACE close(tdb->tracefd); #endif memset(tdb, 0, sizeof(*tdb)); SAFE_FREE(tdb); return ret; } /* register a loging function */ _PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx) { tdb->log = *log_ctx; } _PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb) { return tdb->log.log_private; } static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) { #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ !defined(LIBREPLACE_PWRITE_NOT_REPLACED) struct stat st; #endif if (tdb->flags & TDB_INTERNAL) { return 0; /* Nothing to do. */ } if (tdb_have_extra_locks(tdb)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n")); goto fail; } if (tdb->transaction != 0) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n")); goto fail; } /* If we have real pread & pwrite, we can skip reopen. */ #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ !defined(LIBREPLACE_PWRITE_NOT_REPLACED) if (tdb_munmap(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); goto fail; } if (close(tdb->fd) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n")); tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); if (tdb->fd == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno))); goto fail; } /* * We only use st.st_dev and st.st_ino from the raw fstat() * call, everything else needs to use tdb_fstat() in order * to skip tdb->hdr_ofs! */ if (fstat(tdb->fd, &st) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); goto fail; } if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); goto fail; } ZERO_STRUCT(st); /* * We had tdb_mmap(tdb) here before, * but we need to use tdb_fstat(), * which is triggered from tdb_oob() before calling tdb_mmap(). * As this skips tdb->hdr_ofs. */ tdb->map_size = 0; if (tdb_oob(tdb, 0, 1, 0) != 0) { goto fail; } #endif /* fake pread or pwrite */ /* We may still think we hold the active lock. */ tdb->num_lockrecs = 0; SAFE_FREE(tdb->lockrecs); tdb->lockrecs_array_length = 0; if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n")); goto fail; } return 0; fail: tdb_close(tdb); return -1; } /* reopen a tdb - this can be used after a fork to ensure that we have an independent seek pointer from our parent and to re-establish locks */ _PUBLIC_ int tdb_reopen(struct tdb_context *tdb) { bool active_lock; active_lock = (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); return tdb_reopen_internal(tdb, active_lock); } /* reopen all tdb's */ _PUBLIC_ int tdb_reopen_all(int parent_longlived) { struct tdb_context *tdb; for (tdb=tdbs; tdb; tdb = tdb->next) { bool active_lock; active_lock = (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); /* * If the parent is longlived (ie. a * parent daemon architecture), we know * it will keep it's active lock on a * tdb opened with CLEAR_IF_FIRST. Thus * for child processes we don't have to * add an active lock. This is essential * to improve performance on systems that * keep POSIX locks as a non-scalable data * structure in the kernel. */ if (parent_longlived) { /* Ensure no clear-if-first. */ active_lock = false; } if (tdb_reopen_internal(tdb, active_lock) != 0) return -1; } return 0; } ldb-2.0.8/lib/tdb/common/rescue.c0000660000000000000000000002012113573675413016471 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library, rescue attempt code. Copyright (C) Rusty Russell 2012 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" #include struct found { tdb_off_t head; /* 0 -> invalid. */ struct tdb_record rec; TDB_DATA key; bool in_hash; bool in_free; }; struct found_table { /* As an ordered array (by head offset). */ struct found *arr; unsigned int num, max; }; static bool looks_like_valid_record(struct tdb_context *tdb, tdb_off_t off, const struct tdb_record *rec, TDB_DATA *key) { unsigned int hval; if (rec->magic != TDB_MAGIC) return false; if (rec->key_len + rec->data_len > rec->rec_len) return false; if (rec->rec_len % TDB_ALIGNMENT) return false; /* Next pointer must make some sense. */ if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)) return false; if (tdb_oob(tdb, rec->next, sizeof(*rec), 1)) return false; key->dsize = rec->key_len; key->dptr = tdb_alloc_read(tdb, off + sizeof(*rec), key->dsize); if (!key->dptr) return false; hval = tdb->hash_fn(key); if (hval != rec->full_hash) { free(key->dptr); return false; } /* Caller frees up key->dptr */ return true; } static bool add_to_table(struct found_table *found, tdb_off_t off, struct tdb_record *rec, TDB_DATA key) { if (found->num + 1 > found->max) { struct found *new; found->max = (found->max ? found->max * 2 : 128); new = realloc(found->arr, found->max * sizeof(found->arr[0])); if (!new) return false; found->arr = new; } found->arr[found->num].head = off; found->arr[found->num].rec = *rec; found->arr[found->num].key = key; found->arr[found->num].in_hash = false; found->arr[found->num].in_free = false; found->num++; return true; } static bool walk_record(struct tdb_context *tdb, const struct found *f, void (*walk)(TDB_DATA, TDB_DATA, void *private_data), void *private_data) { TDB_DATA data; data.dsize = f->rec.data_len; data.dptr = tdb_alloc_read(tdb, f->head + sizeof(f->rec) + f->rec.key_len, data.dsize); if (!data.dptr) { if (tdb->ecode == TDB_ERR_OOM) return false; /* I/O errors are expected. */ return true; } walk(f->key, data, private_data); free(data.dptr); return true; } /* First entry which has offset >= this one. */ static unsigned int find_entry(struct found_table *found, tdb_off_t off) { unsigned int start = 0, end = found->num; while (start < end) { /* We can't overflow here. */ unsigned int mid = (start + end) / 2; if (off < found->arr[mid].head) { end = mid; } else if (off > found->arr[mid].head) { start = mid + 1; } else { return mid; } } assert(start == end); return end; } static void found_in_hashchain(struct found_table *found, tdb_off_t head) { unsigned int match; match = find_entry(found, head); if (match < found->num && found->arr[match].head == head) { found->arr[match].in_hash = true; } } static void mark_free_area(struct found_table *found, tdb_off_t head, tdb_len_t len) { unsigned int match; match = find_entry(found, head); /* Mark everything within this free entry. */ while (match < found->num) { if (found->arr[match].head >= head + len) { break; } found->arr[match].in_free = true; match++; } } static int cmp_key(const void *a, const void *b) { const struct found *fa = a, *fb = b; if (fa->key.dsize < fb->key.dsize) { return -1; } else if (fa->key.dsize > fb->key.dsize) { return 1; } return memcmp(fa->key.dptr, fb->key.dptr, fa->key.dsize); } static bool key_eq(TDB_DATA a, TDB_DATA b) { return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; } static void free_table(struct found_table *found) { unsigned int i; for (i = 0; i < found->num; i++) { free(found->arr[i].key.dptr); } free(found->arr); } static void logging_suppressed(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { } _PUBLIC_ int tdb_rescue(struct tdb_context *tdb, void (*walk)(TDB_DATA, TDB_DATA, void *private_data), void *private_data) { struct found_table found = { NULL, 0, 0 }; tdb_off_t h, off, i; tdb_log_func oldlog = tdb->log.log_fn; struct tdb_record rec; TDB_DATA key; bool locked; /* Read-only databases use no locking at all: it's best-effort. * We may have a write lock already, so skip that case too. */ if (tdb->read_only || tdb->allrecord_lock.count != 0) { locked = false; } else { if (tdb_lockall_read(tdb) == -1) return -1; locked = true; } /* Make sure we know true size of the underlying file. */ tdb_oob(tdb, tdb->map_size, 1, 1); /* Suppress logging, since we anticipate errors. */ tdb->log.log_fn = logging_suppressed; /* Now walk entire db looking for records. */ for (off = TDB_DATA_START(tdb->hash_size); off < tdb->map_size; off += TDB_ALIGNMENT) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == -1) continue; if (looks_like_valid_record(tdb, off, &rec, &key)) { if (!add_to_table(&found, off, &rec, key)) { goto oom; } } } /* Walk hash chains to positive vet. */ for (h = 0; h < 1+tdb->hash_size; h++) { bool slow_chase = false; tdb_off_t slow_off = FREELIST_TOP + h*sizeof(tdb_off_t); if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), &off) == -1) continue; while (off && off != slow_off) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) != 0) { break; } /* 0 is the free list, rest are hash chains. */ if (h == 0) { /* Don't mark garbage as free. */ if (rec.magic != TDB_FREE_MAGIC) { break; } mark_free_area(&found, off, sizeof(rec) + rec.rec_len); } else { found_in_hashchain(&found, off); } off = rec.next; /* Loop detection using second pointer at half-speed */ if (slow_chase) { /* First entry happens to be next ptr */ tdb_ofs_read(tdb, slow_off, &slow_off); } slow_chase = !slow_chase; } } /* Recovery area: must be marked as free, since it often has old * records in there! */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off) == 0 && off != 0) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == 0) { mark_free_area(&found, off, sizeof(rec) + rec.rec_len); } } /* Now sort by key! */ if (found.arr != NULL) { qsort(found.arr, found.num, sizeof(found.arr[0]), cmp_key); } for (i = 0; (found.arr != NULL) && i < found.num; ) { unsigned int num, num_in_hash = 0; /* How many are identical? */ for (num = 0; num < found.num - i; num++) { if (!key_eq(found.arr[i].key, found.arr[i+num].key)) { break; } if (found.arr[i+num].in_hash) { if (!walk_record(tdb, &found.arr[i+num], walk, private_data)) goto oom; num_in_hash++; } } assert(num); /* If none were in the hash, we print any not in free list. */ if (num_in_hash == 0) { unsigned int j; for (j = i; j < i + num; j++) { if (!found.arr[j].in_free) { if (!walk_record(tdb, &found.arr[j], walk, private_data)) goto oom; } } } i += num; } tdb->log.log_fn = oldlog; if (locked) { tdb_unlockall_read(tdb); } return 0; oom: tdb->log.log_fn = oldlog; tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_rescue: failed allocating\n")); free_table(&found); if (locked) { tdb_unlockall_read(tdb); } return -1; } ldb-2.0.8/lib/tdb/common/summary.c0000660000000000000000000001362213573675413016710 0ustar rootroot00000000000000 /* Trivial Database: human-readable summary code Copyright (C) Rusty Russell 2010 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 . */ #include "tdb_private.h" #define SUMMARY_FORMAT \ "Size of file/data: %llu/%zu\n" \ "Header offset/logical size: %zu/%zu\n" \ "Number of records: %zu\n" \ "Incompatible hash: %s\n" \ "Active/supported feature flags: 0x%08x/0x%08x\n" \ "Robust mutexes locking: %s\n" \ "Smallest/average/largest keys: %zu/%zu/%zu\n" \ "Smallest/average/largest data: %zu/%zu/%zu\n" \ "Smallest/average/largest padding: %zu/%zu/%zu\n" \ "Number of dead records: %zu\n" \ "Smallest/average/largest dead records: %zu/%zu/%zu\n" \ "Number of free records: %zu\n" \ "Smallest/average/largest free records: %zu/%zu/%zu\n" \ "Number of hash chains: %zu\n" \ "Smallest/average/largest hash chains: %zu/%zu/%zu\n" \ "Number of uncoalesced records: %zu\n" \ "Smallest/average/largest uncoalesced runs: %zu/%zu/%zu\n" \ "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: %.0f/%.0f/%.0f/%.0f/%.0f/%.0f/%.0f\n" /* We don't use tally module, to keep upstream happy. */ struct tally { size_t min, max, total; size_t num; }; static void tally_init(struct tally *tally) { tally->total = 0; tally->num = 0; tally->min = tally->max = 0; } static void tally_add(struct tally *tally, size_t len) { if (tally->num == 0) tally->max = tally->min = len; else if (len > tally->max) tally->max = len; else if (len < tally->min) tally->min = len; tally->num++; tally->total += len; } static size_t tally_mean(const struct tally *tally) { if (!tally->num) return 0; return tally->total / tally->num; } static size_t get_hash_length(struct tdb_context *tdb, unsigned int i) { tdb_off_t rec_ptr; struct tdb_chainwalk_ctx chainwalk; size_t count = 0; if (tdb_ofs_read(tdb, TDB_HASH_TOP(i), &rec_ptr) == -1) return 0; tdb_chainwalk_init(&chainwalk, rec_ptr); /* keep looking until we find the right record */ while (rec_ptr) { struct tdb_record r; bool ok; ++count; if (tdb_rec_read(tdb, rec_ptr, &r) == -1) return 0; rec_ptr = r.next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return SIZE_MAX; } } return count; } _PUBLIC_ char *tdb_summary(struct tdb_context *tdb) { off_t file_size; tdb_off_t off, rec_off; struct tally freet, keys, data, dead, extra, hashval, uncoal; struct tdb_record rec; char *ret = NULL; bool locked; size_t unc = 0; int len; struct tdb_record recovery; /* Read-only databases use no locking at all: it's best-effort. * We may have a write lock already, so skip that case too. */ if (tdb->read_only || tdb->allrecord_lock.count != 0) { locked = false; } else { if (tdb_lockall_read(tdb) == -1) return NULL; locked = true; } if (tdb_recovery_area(tdb, tdb->methods, &rec_off, &recovery) != 0) { goto unlock; } tally_init(&freet); tally_init(&keys); tally_init(&data); tally_init(&dead); tally_init(&extra); tally_init(&hashval); tally_init(&uncoal); for (off = TDB_DATA_START(tdb->hash_size); off < tdb->map_size - 1; off += sizeof(rec) + rec.rec_len) { if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()) == -1) goto unlock; switch (rec.magic) { case TDB_MAGIC: tally_add(&keys, rec.key_len); tally_add(&data, rec.data_len); tally_add(&extra, rec.rec_len - (rec.key_len + rec.data_len)); if (unc > 1) tally_add(&uncoal, unc - 1); unc = 0; break; case TDB_FREE_MAGIC: tally_add(&freet, rec.rec_len); unc++; break; /* If we crash after ftruncate, we can get zeroes or fill. */ case TDB_RECOVERY_INVALID_MAGIC: case 0x42424242: unc++; /* If it's a valid recovery, we can trust rec_len. */ if (off != rec_off) { rec.rec_len = tdb_dead_space(tdb, off) - sizeof(rec); } FALL_THROUGH; case TDB_DEAD_MAGIC: tally_add(&dead, rec.rec_len); break; default: TDB_LOG((tdb, TDB_DEBUG_ERROR, "Unexpected record magic 0x%x at offset %u\n", rec.magic, off)); goto unlock; } } if (unc > 1) tally_add(&uncoal, unc - 1); for (off = 0; off < tdb->hash_size; off++) tally_add(&hashval, get_hash_length(tdb, off)); file_size = tdb->hdr_ofs + tdb->map_size; len = asprintf(&ret, SUMMARY_FORMAT, (unsigned long long)file_size, keys.total+data.total, (size_t)tdb->hdr_ofs, (size_t)tdb->map_size, keys.num, (tdb->hash_fn == tdb_jenkins_hash)?"yes":"no", (unsigned)tdb->feature_flags, TDB_SUPPORTED_FEATURE_FLAGS, (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX)?"yes":"no", keys.min, tally_mean(&keys), keys.max, data.min, tally_mean(&data), data.max, extra.min, tally_mean(&extra), extra.max, dead.num, dead.min, tally_mean(&dead), dead.max, freet.num, freet.min, tally_mean(&freet), freet.max, hashval.num, hashval.min, tally_mean(&hashval), hashval.max, uncoal.total, uncoal.min, tally_mean(&uncoal), uncoal.max, keys.total * 100.0 / file_size, data.total * 100.0 / file_size, extra.total * 100.0 / file_size, freet.total * 100.0 / file_size, dead.total * 100.0 / file_size, (keys.num + freet.num + dead.num) * (sizeof(struct tdb_record) + sizeof(uint32_t)) * 100.0 / file_size, tdb->hash_size * sizeof(tdb_off_t) * 100.0 / file_size); if (len == -1) { goto unlock; } unlock: if (locked) { tdb_unlockall_read(tdb); } return ret; } ldb-2.0.8/lib/tdb/common/tdb.c0000660000000000000000000007562213573675413015774 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" _PUBLIC_ TDB_DATA tdb_null; /* non-blocking increment of the tdb sequence number if the tdb has been opened using the TDB_SEQNUM flag */ _PUBLIC_ void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) { tdb_off_t seqnum=0; if (!(tdb->flags & TDB_SEQNUM)) { return; } /* we ignore errors from this, as we have no sane way of dealing with them. */ tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); seqnum++; tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); } /* increment the tdb sequence number if the tdb has been opened using the TDB_SEQNUM flag */ static void tdb_increment_seqnum(struct tdb_context *tdb) { if (!(tdb->flags & TDB_SEQNUM)) { return; } if (tdb->transaction != NULL) { tdb_increment_seqnum_nonblock(tdb); return; } if (tdb_nest_lock(tdb, TDB_SEQNUM_OFS, F_WRLCK, TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) { return; } tdb_increment_seqnum_nonblock(tdb); tdb_nest_unlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, false); } static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) { return memcmp(data.dptr, key.dptr, data.dsize); } void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr) { *ctx = (struct tdb_chainwalk_ctx) { .slow_ptr = ptr }; } bool tdb_chainwalk_check(struct tdb_context *tdb, struct tdb_chainwalk_ctx *ctx, tdb_off_t next_ptr) { int ret; if (ctx->slow_chase) { ret = tdb_ofs_read(tdb, ctx->slow_ptr, &ctx->slow_ptr); if (ret == -1) { return false; } } ctx->slow_chase = !ctx->slow_chase; if (next_ptr == ctx->slow_ptr) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_chainwalk_check: circular chain\n")); return false; } return true; } /* Returns 0 on fail. On success, return offset of record, and fills in rec */ static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, struct tdb_record *r) { tdb_off_t rec_ptr; struct tdb_chainwalk_ctx chainwalk; /* read in the hash top */ if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) return 0; tdb_chainwalk_init(&chainwalk, rec_ptr); /* keep looking until we find the right record */ while (rec_ptr) { bool ok; if (tdb_rec_read(tdb, rec_ptr, r) == -1) return 0; if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), r->key_len, tdb_key_compare, NULL) == 0) { return rec_ptr; } rec_ptr = r->next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return 0; } } tdb->ecode = TDB_ERR_NOEXIST; return 0; } /* As tdb_find, but if you succeed, keep the lock */ tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, struct tdb_record *rec) { uint32_t rec_ptr; if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) return 0; if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) tdb_unlock(tdb, BUCKET(hash), locktype); return rec_ptr; } static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key); struct tdb_update_hash_state { const TDB_DATA *dbufs; int num_dbufs; tdb_len_t dbufs_len; }; static int tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data) { struct tdb_update_hash_state *state = private_data; unsigned char *dptr = data.dptr; int i; if (state->dbufs_len != data.dsize) { return -1; } for (i=0; inum_dbufs; i++) { TDB_DATA dbuf = state->dbufs[i]; if( dbuf.dsize > 0) { int ret; ret = memcmp(dptr, dbuf.dptr, dbuf.dsize); if (ret != 0) { return -1; } dptr += dbuf.dsize; } } return 0; } /* update an entry in place - this only works if the new data size is <= the old data size and the key exists. on failure return -1. */ static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, const TDB_DATA *dbufs, int num_dbufs, tdb_len_t dbufs_len) { struct tdb_record rec; tdb_off_t rec_ptr, ofs; int i; /* find entry */ if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) return -1; /* it could be an exact duplicate of what is there - this is * surprisingly common (eg. with a ldb re-index). */ if (rec.data_len == dbufs_len) { struct tdb_update_hash_state state = { .dbufs = dbufs, .num_dbufs = num_dbufs, .dbufs_len = dbufs_len }; int ret; ret = tdb_parse_record(tdb, key, tdb_update_hash_cmp, &state); if (ret == 0) { return 0; } } /* must be long enough key, data and tailer */ if (rec.rec_len < key.dsize + dbufs_len + sizeof(tdb_off_t)) { tdb->ecode = TDB_SUCCESS; /* Not really an error */ return -1; } ofs = rec_ptr + sizeof(rec) + rec.key_len; for (i=0; imethods->tdb_write(tdb, ofs, dbuf.dptr, dbuf.dsize); if (ret == -1) { return -1; } ofs += dbuf.dsize; } if (dbufs_len != rec.data_len) { /* update size */ rec.data_len = dbufs_len; return tdb_rec_write(tdb, rec_ptr, &rec); } return 0; } /* find an entry in the database given a key */ /* If an entry doesn't exist tdb_err will be set to * TDB_ERR_NOEXIST. If a key has no data attached * then the TDB_DATA will have zero length but * a non-zero pointer */ static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key) { tdb_off_t rec_ptr; struct tdb_record rec; TDB_DATA ret; uint32_t hash; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) return tdb_null; ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, rec.data_len); ret.dsize = rec.data_len; tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return ret; } _PUBLIC_ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) { TDB_DATA ret = _tdb_fetch(tdb, key); tdb_trace_1rec_retrec(tdb, "tdb_fetch", key, ret); return ret; } /* * Find an entry in the database and hand the record's data to a parsing * function. The parsing function is executed under the chain read lock, so it * should be fast and should not block on other syscalls. * * DON'T CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS. * * For mmapped tdb's that do not have a transaction open it points the parsing * function directly at the mmap area, it avoids the malloc/memcpy in this * case. If a transaction is open or no mmap is available, it has to do * malloc/read/parse/free. * * This is interesting for all readers of potentially large data structures in * the tdb records, ldb indexes being one example. * * Return -1 if the record was not found. */ _PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { tdb_off_t rec_ptr; struct tdb_record rec; int ret; uint32_t hash; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { /* record not found */ tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, -1); tdb->ecode = TDB_ERR_NOEXIST; return -1; } tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, 0); ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, rec.data_len, parser, private_data); tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return ret; } /* check if an entry in the database exists note that 1 is returned if the key is found and 0 is returned if not found this doesn't match the conventions in the rest of this module, but is compatible with gdbm */ static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) { struct tdb_record rec; if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) return 0; tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return 1; } _PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) { uint32_t hash = tdb->hash_fn(&key); int ret; ret = tdb_exists_hash(tdb, key, hash); tdb_trace_1rec_ret(tdb, "tdb_exists", key, ret); return ret; } /* * Move a dead record to the freelist. The hash chain and freelist * must be locked. */ static int tdb_del_dead(struct tdb_context *tdb, uint32_t last_ptr, uint32_t rec_ptr, struct tdb_record *rec, bool *deleted) { int ret; ret = tdb_write_lock_record(tdb, rec_ptr); if (ret == -1) { /* Someone traversing here: Just leave it dead */ return 0; } ret = tdb_write_unlock_record(tdb, rec_ptr); if (ret == -1) { return -1; } ret = tdb_ofs_write(tdb, last_ptr, &rec->next); if (ret == -1) { return -1; } *deleted = true; ret = tdb_free(tdb, rec_ptr, rec); return ret; } /* * Walk the hash chain and leave tdb->max_dead_records around. Move * the rest of dead records to the freelist. */ int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash) { struct tdb_chainwalk_ctx chainwalk; struct tdb_record rec; tdb_off_t last_ptr, rec_ptr; bool locked_freelist = false; int num_dead = 0; int ret; last_ptr = TDB_HASH_TOP(hash); /* * Init chainwalk with the pointer to the hash top. It might * be that the very first record in the chain is a dead one * that we have to delete. */ tdb_chainwalk_init(&chainwalk, last_ptr); ret = tdb_ofs_read(tdb, last_ptr, &rec_ptr); if (ret == -1) { return -1; } while (rec_ptr != 0) { bool deleted = false; uint32_t next; ret = tdb_rec_read(tdb, rec_ptr, &rec); if (ret == -1) { goto fail; } /* * Make a copy of rec.next: Further down we might * delete and put the record on the freelist. Make * sure that modifications in that code path can't * break the chainwalk here. */ next = rec.next; if (rec.magic == TDB_DEAD_MAGIC) { num_dead += 1; if (num_dead > tdb->max_dead_records) { if (!locked_freelist) { /* * Lock the freelist only if * it's really required. */ ret = tdb_lock(tdb, -1, F_WRLCK); if (ret == -1) { goto fail; }; locked_freelist = true; } ret = tdb_del_dead( tdb, last_ptr, rec_ptr, &rec, &deleted); if (ret == -1) { goto fail; } } } /* * Don't do the chainwalk check if "rec_ptr" was * deleted. We reduced the chain, and the chainwalk * check might catch up early. Imagine a valid chain * with just dead records: We never can bump the * "slow" pointer in chainwalk_check, as there isn't * anything left to jump to and compare. */ if (!deleted) { bool ok; last_ptr = rec_ptr; ok = tdb_chainwalk_check(tdb, &chainwalk, next); if (!ok) { ret = -1; goto fail; } } rec_ptr = next; } ret = 0; fail: if (locked_freelist) { tdb_unlock(tdb, -1, F_WRLCK); } return ret; } /* delete an entry in the database given a key */ static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) { tdb_off_t rec_ptr; struct tdb_record rec; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec); if (rec_ptr == 0) { return -1; } /* * Mark the record dead */ rec.magic = TDB_DEAD_MAGIC; ret = tdb_rec_write(tdb, rec_ptr, &rec); if (ret == -1) { goto done; } tdb_increment_seqnum(tdb); ret = tdb_trim_dead(tdb, hash); done: if (tdb_unlock(tdb, BUCKET(hash), F_WRLCK) != 0) TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); return ret; } _PUBLIC_ int tdb_delete(struct tdb_context *tdb, TDB_DATA key) { uint32_t hash = tdb->hash_fn(&key); int ret; ret = tdb_delete_hash(tdb, key, hash); tdb_trace_1rec_ret(tdb, "tdb_delete", key, ret); return ret; } /* * See if we have a dead record around with enough space */ tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, struct tdb_record *r, tdb_len_t length, tdb_off_t *p_last_ptr) { tdb_off_t rec_ptr, last_ptr; struct tdb_chainwalk_ctx chainwalk; tdb_off_t best_rec_ptr = 0; tdb_off_t best_last_ptr = 0; struct tdb_record best = { .rec_len = UINT32_MAX }; length += sizeof(tdb_off_t); /* tailer */ last_ptr = TDB_HASH_TOP(hash); /* read in the hash top */ if (tdb_ofs_read(tdb, last_ptr, &rec_ptr) == -1) return 0; tdb_chainwalk_init(&chainwalk, rec_ptr); /* keep looking until we find the right record */ while (rec_ptr) { bool ok; if (tdb_rec_read(tdb, rec_ptr, r) == -1) return 0; if (TDB_DEAD(r) && (r->rec_len >= length) && (r->rec_len < best.rec_len)) { best_rec_ptr = rec_ptr; best_last_ptr = last_ptr; best = *r; } last_ptr = rec_ptr; rec_ptr = r->next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { return 0; } } if (best.rec_len == UINT32_MAX) { return 0; } *r = best; *p_last_ptr = best_last_ptr; return best_rec_ptr; } static int _tdb_storev(struct tdb_context *tdb, TDB_DATA key, const TDB_DATA *dbufs, int num_dbufs, int flag, uint32_t hash) { struct tdb_record rec; tdb_off_t rec_ptr, ofs; tdb_len_t rec_len, dbufs_len; int i; int ret = -1; dbufs_len = 0; for (i=0; iecode = TDB_ERR_EINVAL; goto fail; } dbufs_len += dsize; if (dbufs_len < dsize) { tdb->ecode = TDB_ERR_OOM; goto fail; } } rec_len = key.dsize + dbufs_len; if ((rec_len < key.dsize) || (rec_len < dbufs_len)) { tdb->ecode = TDB_ERR_OOM; goto fail; } /* check for it existing, on insert. */ if (flag == TDB_INSERT) { if (tdb_exists_hash(tdb, key, hash)) { tdb->ecode = TDB_ERR_EXISTS; goto fail; } } else { /* first try in-place update, on modify or replace. */ if (tdb_update_hash(tdb, key, hash, dbufs, num_dbufs, dbufs_len) == 0) { goto done; } if (tdb->ecode == TDB_ERR_NOEXIST && flag == TDB_MODIFY) { /* if the record doesn't exist and we are in TDB_MODIFY mode then we should fail the store */ goto fail; } } /* reset the error code potentially set by the tdb_update_hash() */ tdb->ecode = TDB_SUCCESS; /* delete any existing record - if it doesn't exist we don't care. Doing this first reduces fragmentation, and avoids coalescing with `allocated' block before it's updated. */ if (flag != TDB_INSERT) tdb_delete_hash(tdb, key, hash); /* we have to allocate some space */ rec_ptr = tdb_allocate(tdb, hash, rec_len, &rec); if (rec_ptr == 0) { goto fail; } /* Read hash top into next ptr */ if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) goto fail; rec.key_len = key.dsize; rec.data_len = dbufs_len; rec.full_hash = hash; rec.magic = TDB_MAGIC; ofs = rec_ptr; /* write out and point the top of the hash chain at it */ ret = tdb_rec_write(tdb, ofs, &rec); if (ret == -1) { goto fail; } ofs += sizeof(rec); ret = tdb->methods->tdb_write(tdb, ofs, key.dptr, key.dsize); if (ret == -1) { goto fail; } ofs += key.dsize; for (i=0; imethods->tdb_write(tdb, ofs, dbufs[i].dptr, dbufs[i].dsize); if (ret == -1) { goto fail; } ofs += dbufs[i].dsize; } ret = tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr); if (ret == -1) { /* Need to tdb_unallocate() here */ goto fail; } done: ret = 0; fail: if (ret == 0) { tdb_increment_seqnum(tdb); } return ret; } static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag, uint32_t hash) { return _tdb_storev(tdb, key, &dbuf, 1, flag, hash); } /* store an element in the database, replacing any existing element with the same key return 0 on success, -1 on failure */ _PUBLIC_ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) { uint32_t hash; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, -1); return -1; } /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; ret = _tdb_store(tdb, key, dbuf, flag, hash); tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, ret); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); return ret; } _PUBLIC_ int tdb_storev(struct tdb_context *tdb, TDB_DATA key, const TDB_DATA *dbufs, int num_dbufs, int flag) { uint32_t hash; int ret; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, dbufs, num_dbufs, flag, -1); return -1; } /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; ret = _tdb_storev(tdb, key, dbufs, num_dbufs, flag, hash); tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, dbufs, num_dbufs, flag, -1); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); return ret; } /* Append to an entry. Create if not exist. */ _PUBLIC_ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) { uint32_t hash; TDB_DATA dbufs[2]; int ret = -1; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; dbufs[0] = _tdb_fetch(tdb, key); dbufs[1] = new_dbuf; ret = _tdb_storev(tdb, key, dbufs, 2, 0, hash); tdb_trace_2rec_retrec(tdb, "tdb_append", key, dbufs[0], dbufs[1]); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); SAFE_FREE(dbufs[0].dptr); return ret; } /* return the name of the current tdb file useful for external logging functions */ _PUBLIC_ const char *tdb_name(struct tdb_context *tdb) { return tdb->name; } /* return the underlying file descriptor being used by tdb, or -1 useful for external routines that want to check the device/inode of the fd */ _PUBLIC_ int tdb_fd(struct tdb_context *tdb) { return tdb->fd; } /* return the current logging function useful for external tdb routines that wish to log tdb errors */ _PUBLIC_ tdb_log_func tdb_log_fn(struct tdb_context *tdb) { return tdb->log.log_fn; } /* get the tdb sequence number. Only makes sense if the writers opened with TDB_SEQNUM set. Note that this sequence number will wrap quite quickly, so it should only be used for a 'has something changed' test, not for code that relies on the count of the number of changes made. If you want a counter then use a tdb record. The aim of this sequence number is to allow for a very lightweight test of a possible tdb change. */ _PUBLIC_ int tdb_get_seqnum(struct tdb_context *tdb) { tdb_off_t seqnum=0; tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); return seqnum; } _PUBLIC_ int tdb_hash_size(struct tdb_context *tdb) { return tdb->hash_size; } _PUBLIC_ size_t tdb_map_size(struct tdb_context *tdb) { return tdb->map_size; } _PUBLIC_ int tdb_get_flags(struct tdb_context *tdb) { return tdb->flags; } _PUBLIC_ void tdb_add_flags(struct tdb_context *tdb, unsigned flags) { if ((flags & TDB_ALLOW_NESTING) && (flags & TDB_DISALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_add_flags: " "allow_nesting and disallow_nesting are not allowed together!")); return; } if (flags & TDB_ALLOW_NESTING) { tdb->flags &= ~TDB_DISALLOW_NESTING; } if (flags & TDB_DISALLOW_NESTING) { tdb->flags &= ~TDB_ALLOW_NESTING; } tdb->flags |= flags; } _PUBLIC_ void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) { if ((flags & TDB_ALLOW_NESTING) && (flags & TDB_DISALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " "allow_nesting and disallow_nesting are not allowed together!")); return; } if ((flags & TDB_NOLOCK) && (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) && (tdb->mutexes == NULL)) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " "Can not remove NOLOCK flag on mutexed databases")); return; } if (flags & TDB_ALLOW_NESTING) { tdb->flags |= TDB_DISALLOW_NESTING; } if (flags & TDB_DISALLOW_NESTING) { tdb->flags |= TDB_ALLOW_NESTING; } tdb->flags &= ~flags; } /* enable sequence number handling on an open tdb */ _PUBLIC_ void tdb_enable_seqnum(struct tdb_context *tdb) { tdb->flags |= TDB_SEQNUM; } /* add a region of the file to the freelist. Length is the size of the region in bytes, which includes the free list header that needs to be added */ static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) { struct tdb_record rec; if (length <= sizeof(rec)) { /* the region is not worth adding */ return 0; } if (length + offset > tdb->map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); return -1; } memset(&rec,'\0',sizeof(rec)); rec.rec_len = length - sizeof(rec); if (tdb_free(tdb, offset, &rec) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n")); return -1; } return 0; } /* wipe the entire database, deleting all records. This can be done very fast by using a allrecord lock. The entire data portion of the file becomes a single entry in the freelist. This code carefully steps around the recovery area, leaving it alone */ _PUBLIC_ int tdb_wipe_all(struct tdb_context *tdb) { uint32_t i; tdb_off_t offset = 0; ssize_t data_len; tdb_off_t recovery_head; tdb_len_t recovery_size = 0; if (tdb_lockall(tdb) != 0) { return -1; } tdb_trace(tdb, "tdb_wipe_all"); /* see if the tdb has a recovery area, and remember its size if so. We don't want to lose this as otherwise each tdb_wipe_all() in a transaction will increase the size of the tdb by the size of the recovery area */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n")); goto failed; } if (recovery_head != 0) { struct tdb_record rec; if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); return -1; } recovery_size = rec.rec_len + sizeof(rec); } /* wipe the hashes */ for (i=0;ihash_size;i++) { if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); goto failed; } } /* wipe the freelist */ if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); goto failed; } /* add all the rest of the file to the freelist, possibly leaving a gap for the recovery area */ if (recovery_size == 0) { /* the simple case - the whole file can be used as a freelist */ data_len = (tdb->map_size - TDB_DATA_START(tdb->hash_size)); if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { goto failed; } } else { /* we need to add two freelist entries - one on either side of the recovery area Note that we cannot shift the recovery area during this operation. Only the transaction.c code may move the recovery area or we risk subtle data corruption */ data_len = (recovery_head - TDB_DATA_START(tdb->hash_size)); if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { goto failed; } /* and the 2nd free list entry after the recovery area - if any */ data_len = tdb->map_size - (recovery_head+recovery_size); if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { goto failed; } } tdb_increment_seqnum_nonblock(tdb); if (tdb_unlockall(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); goto failed; } return 0; failed: tdb_unlockall(tdb); return -1; } struct traverse_state { bool error; struct tdb_context *dest_db; }; /* traverse function for repacking */ static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { struct traverse_state *state = (struct traverse_state *)private_data; if (tdb_store(state->dest_db, key, data, TDB_INSERT) != 0) { state->error = true; return -1; } return 0; } /* repack a tdb */ _PUBLIC_ int tdb_repack(struct tdb_context *tdb) { struct tdb_context *tmp_db; struct traverse_state state; tdb_trace(tdb, "tdb_repack"); if (tdb_transaction_start(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to start transaction\n")); return -1; } tmp_db = tdb_open("tmpdb", tdb_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0); if (tmp_db == NULL) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to create tmp_db\n")); tdb_transaction_cancel(tdb); return -1; } state.error = false; state.dest_db = tmp_db; if (tdb_traverse_read(tdb, repack_traverse, &state) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying out\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } if (state.error) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during traversal\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } if (tdb_wipe_all(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to wipe database\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } state.error = false; state.dest_db = tdb; if (tdb_traverse_read(tmp_db, repack_traverse, &state) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying back\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } if (state.error) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during second traversal\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); return -1; } tdb_close(tmp_db); if (tdb_transaction_commit(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to commit\n")); return -1; } return 0; } /* Even on files, we can get partial writes due to signals. */ bool tdb_write_all(int fd, const void *buf, size_t count) { while (count) { ssize_t ret; ret = write(fd, buf, count); if (ret < 0) return false; buf = (const char *)buf + ret; count -= ret; } return true; } bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret) { tdb_off_t ret = a + b; if ((ret < a) || (ret < b)) { return false; } *pret = ret; return true; } #ifdef TDB_TRACE static void tdb_trace_write(struct tdb_context *tdb, const char *str) { if (!tdb_write_all(tdb->tracefd, str, strlen(str))) { close(tdb->tracefd); tdb->tracefd = -1; } } static void tdb_trace_start(struct tdb_context *tdb) { tdb_off_t seqnum=0; char msg[sizeof(tdb_off_t) * 4 + 1]; tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); snprintf(msg, sizeof(msg), "%u ", seqnum); tdb_trace_write(tdb, msg); } static void tdb_trace_end(struct tdb_context *tdb) { tdb_trace_write(tdb, "\n"); } static void tdb_trace_end_ret(struct tdb_context *tdb, int ret) { char msg[sizeof(ret) * 4 + 4]; snprintf(msg, sizeof(msg), " = %i\n", ret); tdb_trace_write(tdb, msg); } static void tdb_trace_record(struct tdb_context *tdb, TDB_DATA rec) { char msg[20 + rec.dsize*2], *p; unsigned int i; /* We differentiate zero-length records from non-existent ones. */ if (rec.dptr == NULL) { tdb_trace_write(tdb, " NULL"); return; } /* snprintf here is purely cargo-cult programming. */ p = msg; p += snprintf(p, sizeof(msg), " %zu:", rec.dsize); for (i = 0; i < rec.dsize; i++) p += snprintf(p, 2, "%02x", rec.dptr[i]); tdb_trace_write(tdb, msg); } void tdb_trace(struct tdb_context *tdb, const char *op) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_end(tdb); } void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op) { char msg[sizeof(tdb_off_t) * 4 + 1]; snprintf(msg, sizeof(msg), "%u ", seqnum); tdb_trace_write(tdb, msg); tdb_trace_write(tdb, op); tdb_trace_end(tdb); } void tdb_trace_open(struct tdb_context *tdb, const char *op, unsigned hash_size, unsigned tdb_flags, unsigned open_flags) { char msg[128]; snprintf(msg, sizeof(msg), "%s %u 0x%x 0x%x", op, hash_size, tdb_flags, open_flags); tdb_trace_start(tdb); tdb_trace_write(tdb, msg); tdb_trace_end(tdb); } void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_end_ret(tdb, ret); } void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_write(tdb, " ="); tdb_trace_record(tdb, ret); tdb_trace_end(tdb); } void tdb_trace_1rec(struct tdb_context *tdb, const char *op, TDB_DATA rec) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); tdb_trace_end(tdb); } void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, int ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); tdb_trace_end_ret(tdb, ret); } void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, TDB_DATA rec, TDB_DATA ret) { tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); tdb_trace_write(tdb, " ="); tdb_trace_record(tdb, ret); tdb_trace_end(tdb); } void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec1, TDB_DATA rec2, unsigned flag, int ret) { char msg[1 + sizeof(ret) * 4]; snprintf(msg, sizeof(msg), " %#x", flag); tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec1); tdb_trace_record(tdb, rec2); tdb_trace_write(tdb, msg); tdb_trace_end_ret(tdb, ret); } void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, const TDB_DATA *recs, int num_recs, unsigned flag, int ret) { char msg[1 + sizeof(ret) * 4]; int i; snprintf(msg, sizeof(msg), " %#x", flag); tdb_trace_start(tdb); tdb_trace_write(tdb, op); tdb_trace_record(tdb, rec); for (i=0; if) #endif #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION (0x26011967 + 6) #define TDB_MAGIC (0x26011999U) #define TDB_FREE_MAGIC (~TDB_MAGIC) #define TDB_DEAD_MAGIC (0xFEE1DEAD) #define TDB_RECOVERY_MAGIC (0xf53bc0e7U) #define TDB_RECOVERY_INVALID_MAGIC (0x0) #define TDB_HASH_RWLOCK_MAGIC (0xbad1a51U) #define TDB_FEATURE_FLAG_MAGIC (0xbad1a52U) #define TDB_ALIGNMENT 4 #define DEFAULT_HASH_SIZE 131 #define FREELIST_TOP (sizeof(struct tdb_header)) #define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) #define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) #define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) #define TDB_HASHTABLE_SIZE(tdb) ((tdb->hash_size+1)*sizeof(tdb_off_t)) #define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) #define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) #define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) #define TDB_PAD_BYTE 0x42 #define TDB_PAD_U32 0x42424242 #define TDB_FEATURE_FLAG_MUTEX 0x00000001 #define TDB_SUPPORTED_FEATURE_FLAGS ( \ TDB_FEATURE_FLAG_MUTEX | \ 0) /* NB assumes there is a local variable called "tdb" that is the * current context, also takes doubly-parenthesized print-style * argument. */ #define TDB_LOG(x) tdb->log.log_fn x #ifdef TDB_TRACE void tdb_trace(struct tdb_context *tdb, const char *op); void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op); void tdb_trace_open(struct tdb_context *tdb, const char *op, unsigned hash_size, unsigned tdb_flags, unsigned open_flags); void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret); void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret); void tdb_trace_1rec(struct tdb_context *tdb, const char *op, TDB_DATA rec); void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, int ret); void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, TDB_DATA rec, TDB_DATA ret); void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec1, TDB_DATA rec2, unsigned flag, int ret); void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, TDB_DATA rec, const TDB_DATA *recs, int num_recs, unsigned flag, int ret); void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op, TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret); #else #define tdb_trace(tdb, op) #define tdb_trace_seqnum(tdb, seqnum, op) #define tdb_trace_open(tdb, op, hash_size, tdb_flags, open_flags) #define tdb_trace_ret(tdb, op, ret) #define tdb_trace_retrec(tdb, op, ret) #define tdb_trace_1rec(tdb, op, rec) #define tdb_trace_1rec_ret(tdb, op, rec, ret) #define tdb_trace_1rec_retrec(tdb, op, rec, ret) #define tdb_trace_2rec_flag_ret(tdb, op, rec1, rec2, flag, ret) #define tdb_trace_1plusn_rec_flag_ret(tdb, op, rec, recs, num_recs, flag, ret); #define tdb_trace_2rec_retrec(tdb, op, rec1, rec2, ret) #endif /* !TDB_TRACE */ /* lock offsets */ #define OPEN_LOCK 0 #define ACTIVE_LOCK 4 #define TRANSACTION_LOCK 8 /* free memory if the pointer is valid and zero the pointer */ #ifndef SAFE_FREE #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) #endif /* * Note: the BUCKET macro is broken as it returns an unexpected result when * called as BUCKET(-1) for the freelist: * * -1 is sign converted to an unsigned int 4294967295 and then the modulo * tdb->hashtable_size is computed. So with a hashtable_size of 10 the result * is * * 4294967295 % hashtable_size = 5. * * where it should be -1 (C uses symmetric modulo). * * As all callers will lock the same wrong list consistently locking is still * consistent. We can not change this without an incompatible on-disk format * change, otherwise different tdb versions would use incompatible locking. */ #define BUCKET(hash) ((hash) % tdb->hash_size) #define DOCONV() (tdb->flags & TDB_CONVERT) #define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) /* the body of the database is made of one tdb_record for the free space plus a separate data list for each hash value */ struct tdb_record { tdb_off_t next; /* offset of the next record in the list */ tdb_len_t rec_len; /* total byte length of record */ tdb_len_t key_len; /* byte length of key */ tdb_len_t data_len; /* byte length of data */ uint32_t full_hash; /* the full 32 bit hash of the key */ uint32_t magic; /* try to catch errors */ /* the following union is implied: union { char record[rec_len]; struct { char key[key_len]; char data[data_len]; } uint32_t totalsize; (tailer) } */ }; /* this is stored at the front of every database */ struct tdb_header { char magic_food[32]; /* for /etc/magic */ uint32_t version; /* version of the code */ uint32_t hash_size; /* number of hash entries */ tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ tdb_off_t recovery_start; /* offset of transaction recovery region */ tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */ uint32_t magic2_hash; /* hash of TDB_MAGIC. */ uint32_t feature_flags; tdb_len_t mutex_size; /* set if TDB_FEATURE_FLAG_MUTEX is set */ tdb_off_t reserved[25]; }; struct tdb_lock_type { uint32_t off; uint32_t count; uint32_t ltype; }; struct tdb_chainwalk_ctx { tdb_off_t slow_ptr; bool slow_chase; }; struct tdb_traverse_lock { struct tdb_traverse_lock *next; uint32_t off; uint32_t list; int lock_rw; }; void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr); bool tdb_chainwalk_check(struct tdb_context *tdb, struct tdb_chainwalk_ctx *ctx, tdb_off_t next_ptr); enum tdb_lock_flags { /* WAIT == F_SETLKW, NOWAIT == F_SETLK */ TDB_LOCK_NOWAIT = 0, TDB_LOCK_WAIT = 1, /* If set, don't log an error on failure. */ TDB_LOCK_PROBE = 2, /* If set, don't actually lock at all. */ TDB_LOCK_MARK_ONLY = 4, }; struct tdb_methods { int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); void (*next_hash_chain)(struct tdb_context *, uint32_t *); int (*tdb_oob)(struct tdb_context *, tdb_off_t , tdb_len_t, int ); int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); }; struct tdb_mutexes; struct tdb_context { char *name; /* the name of the database */ void *map_ptr; /* where it is currently mapped */ int fd; /* open file descriptor for the database */ tdb_len_t map_size; /* how much space has been mapped */ int read_only; /* opened read-only */ int traverse_read; /* read-only traversal */ int traverse_write; /* read-write traversal */ struct tdb_lock_type allrecord_lock; /* .offset == upgradable */ int num_lockrecs; struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ int lockrecs_array_length; tdb_off_t hdr_ofs; /* this is 0 or header.mutex_size */ struct tdb_mutexes *mutexes; /* mmap of the mutex area */ enum TDB_ERROR ecode; /* error code for last tdb error */ uint32_t hash_size; uint32_t feature_flags; uint32_t flags; /* the flags passed to tdb_open */ struct tdb_traverse_lock travlocks; /* current traversal locks */ struct tdb_context *next; /* all tdbs to avoid multiple opens */ dev_t device; /* uniquely identifies this tdb */ ino_t inode; /* uniquely identifies this tdb */ struct tdb_logging_context log; unsigned int (*hash_fn)(TDB_DATA *key); int open_flags; /* flags used in the open - needed by reopen */ const struct tdb_methods *methods; struct tdb_transaction *transaction; int page_size; int max_dead_records; #ifdef TDB_TRACE int tracefd; #endif volatile sig_atomic_t *interrupt_sig_ptr; }; /* internal prototypes */ int tdb_munmap(struct tdb_context *tdb); int tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, enum tdb_lock_flags flags); int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, bool mark_lock); int tdb_unlock(struct tdb_context *tdb, int list, int ltype); int tdb_brlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len, enum tdb_lock_flags flags); int tdb_brunlock(struct tdb_context *tdb, int rw_type, tdb_off_t offset, size_t len); bool tdb_have_extra_locks(struct tdb_context *tdb); void tdb_release_transaction_locks(struct tdb_context *tdb); int tdb_transaction_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags lockflags); int tdb_transaction_unlock(struct tdb_context *tdb, int ltype); int tdb_recovery_area(struct tdb_context *tdb, const struct tdb_methods *methods, tdb_off_t *recovery_offset, struct tdb_record *rec); int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable); int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock); int tdb_allrecord_upgrade(struct tdb_context *tdb); int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); void *tdb_convert(void *buf, uint32_t size); int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, struct tdb_record *rec); int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe); static inline int tdb_oob( struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { if (likely((off + len >= off) && (off + len <= tdb->map_size))) { return 0; } return _tdb_oob(tdb, off, len, probe); } int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); bool tdb_needs_recovery(struct tdb_context *tdb); int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, tdb_off_t offset, tdb_len_t len, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, struct tdb_record *rec); tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, struct tdb_record *r, tdb_len_t length, tdb_off_t *p_last_ptr); int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash); void tdb_io_init(struct tdb_context *tdb); int tdb_expand(struct tdb_context *tdb, tdb_off_t size); tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size); int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec); bool tdb_write_all(int fd, const void *buf, size_t count); int tdb_transaction_recover(struct tdb_context *tdb); void tdb_header_hash(struct tdb_context *tdb, uint32_t *magic1_hash, uint32_t *magic2_hash); unsigned int tdb_old_hash(TDB_DATA *key); size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off); bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret); /* tdb_off_t and tdb_len_t right now are both uint32_t */ #define tdb_add_len_t tdb_add_off_t size_t tdb_mutex_size(struct tdb_context *tdb); bool tdb_have_mutexes(struct tdb_context *tdb); int tdb_mutex_init(struct tdb_context *tdb); int tdb_mutex_mmap(struct tdb_context *tdb); int tdb_mutex_munmap(struct tdb_context *tdb); bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, bool waitflag, int *pret); bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, int *pret); int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags); int tdb_mutex_allrecord_unlock(struct tdb_context *tdb); int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb); void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb); #endif /* TDB_PRIVATE_H */ ldb-2.0.8/lib/tdb/common/transaction.c0000660000000000000000000011616513573675413017546 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 2005 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" /* transaction design: - only allow a single transaction at a time per database. This makes using the transaction API simpler, as otherwise the caller would have to cope with temporary failures in transactions that conflict with other current transactions - keep the transaction recovery information in the same file as the database, using a special 'transaction recovery' record pointed at by the header. This removes the need for extra journal files as used by some other databases - dynamically allocated the transaction recover record, re-using it for subsequent transactions. If a larger record is needed then tdb_free() the old record to place it on the normal tdb freelist before allocating the new record - during transactions, keep a linked list of all writes that have been performed by intercepting all tdb_write() calls. The hooked transaction versions of tdb_read() and tdb_write() check this linked list and try to use the elements of the list in preference to the real database. - don't allow any locks to be held when a transaction starts, otherwise we can end up with deadlock (plus lack of lock nesting in posix locks would mean the lock is lost) - if the caller gains a lock during the transaction but doesn't release it then fail the commit - allow for nested calls to tdb_transaction_start(), re-using the existing transaction record. If the inner transaction is cancelled then a subsequent commit will fail - keep a mirrored copy of the tdb hash chain heads to allow for the fast hash heads scan on traverse, updating the mirrored copy in the transaction version of tdb_write - allow callers to mix transaction and non-transaction use of tdb, although once a transaction is started then an exclusive lock is gained until the transaction is committed or cancelled - the commit stategy involves first saving away all modified data into a linearised buffer in the transaction recovery area, then marking the transaction recovery area with a magic value to indicate a valid recovery record. In total 4 fsync/msync calls are needed per commit to prevent race conditions. It might be possible to reduce this to 3 or even 2 with some more work. - check for a valid recovery record on open of the tdb, while the open lock is held. Automatically recover from the transaction recovery area if needed, then continue with the open as usual. This allows for smooth crash recovery with no administrator intervention. - if TDB_NOSYNC is passed to flags in tdb_open then transactions are still available, but no fsync/msync calls are made. This means we are still proof against a process dying during transaction commit, but not against machine reboot. - if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using tdb_add_flags() transaction nesting is enabled. It resets the TDB_DISALLOW_NESTING flag, as both cannot be used together. The default is that transaction nesting is allowed. Note: this default may change in future versions of tdb. Beware. when transactions are nested a transaction successfully completed with tdb_transaction_commit() can be silently unrolled later. - if TDB_DISALLOW_NESTING is passed to flags in tdb open, or added using tdb_add_flags() transaction nesting is disabled. It resets the TDB_ALLOW_NESTING flag, as both cannot be used together. An attempt create a nested transaction will fail with TDB_ERR_NESTING. The default is that transaction nesting is allowed. Note: this default may change in future versions of tdb. */ /* hold the context of any current transaction */ struct tdb_transaction { /* we keep a mirrored copy of the tdb hash heads here so tdb_next_hash_chain() can operate efficiently */ uint32_t *hash_heads; /* the original io methods - used to do IOs to the real db */ const struct tdb_methods *io_methods; /* the list of transaction blocks. When a block is first written to, it gets created in this list */ uint8_t **blocks; uint32_t num_blocks; uint32_t block_size; /* bytes in each block */ uint32_t last_block_size; /* number of valid bytes in the last block */ /* non-zero when an internal transaction error has occurred. All write operations will then fail until the transaction is ended */ int transaction_error; /* when inside a transaction we need to keep track of any nested tdb_transaction_start() calls, as these are allowed, but don't create a new transaction */ int nesting; /* set when a prepare has already occurred */ bool prepared; tdb_off_t magic_offset; /* old file size before transaction */ tdb_len_t old_map_size; /* did we expand in this transaction */ bool expanded; }; /* read while in a transaction. We need to check first if the data is in our list of transaction elements, then if not do a real read */ static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { uint32_t blk; /* break it down into block sized ops */ while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); if (transaction_read(tdb, off, buf, len2, cv) != 0) { return -1; } len -= len2; off += len2; buf = (void *)(len2 + (char *)buf); } if (len == 0) { return 0; } blk = off / tdb->transaction->block_size; /* see if we have it in the block list */ if (tdb->transaction->num_blocks <= blk || tdb->transaction->blocks[blk] == NULL) { /* nope, do a real read */ if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { goto fail; } return 0; } /* it is in the block list. Now check for the last block */ if (blk == tdb->transaction->num_blocks-1) { if (len > tdb->transaction->last_block_size) { goto fail; } } /* now copy it out of this block */ memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); if (cv) { tdb_convert(buf, len); } return 0; fail: TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%u len=%u\n", off, len)); tdb->ecode = TDB_ERR_IO; tdb->transaction->transaction_error = 1; return -1; } /* write while in a transaction */ static int transaction_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { uint32_t blk; if (buf == NULL) { return -1; } /* Only a commit is allowed on a prepared transaction */ if (tdb->transaction->prepared) { tdb->ecode = TDB_ERR_EINVAL; TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: transaction already prepared, write not allowed\n")); tdb->transaction->transaction_error = 1; return -1; } /* if the write is to a hash head, then update the transaction hash heads */ if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) { uint32_t chain = (off-FREELIST_TOP) / sizeof(tdb_off_t); memcpy(&tdb->transaction->hash_heads[chain], buf, len); } /* break it up into block sized chunks */ while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); if (transaction_write(tdb, off, buf, len2) != 0) { return -1; } len -= len2; off += len2; buf = (const void *)(len2 + (const char *)buf); } if (len == 0) { return 0; } blk = off / tdb->transaction->block_size; off = off % tdb->transaction->block_size; if (tdb->transaction->num_blocks <= blk) { uint8_t **new_blocks; /* expand the blocks array */ new_blocks = (uint8_t **)realloc(tdb->transaction->blocks, (blk+1)*sizeof(uint8_t *)); if (new_blocks == NULL) { tdb->ecode = TDB_ERR_OOM; goto fail; } memset(&new_blocks[tdb->transaction->num_blocks], 0, (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); tdb->transaction->blocks = new_blocks; tdb->transaction->num_blocks = blk+1; tdb->transaction->last_block_size = 0; } /* allocate and fill a block? */ if (tdb->transaction->blocks[blk] == NULL) { tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); if (tdb->transaction->blocks[blk] == NULL) { tdb->ecode = TDB_ERR_OOM; tdb->transaction->transaction_error = 1; return -1; } if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size; if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); } if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, tdb->transaction->blocks[blk], len2, 0) != 0) { SAFE_FREE(tdb->transaction->blocks[blk]); tdb->ecode = TDB_ERR_IO; goto fail; } if (blk == tdb->transaction->num_blocks-1) { tdb->transaction->last_block_size = len2; } } } /* overwrite part of an existing block */ memcpy(tdb->transaction->blocks[blk] + off, buf, len); if (blk == tdb->transaction->num_blocks-1) { if (len + off > tdb->transaction->last_block_size) { tdb->transaction->last_block_size = len + off; } } return 0; fail: TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%u len=%u\n", (blk*tdb->transaction->block_size) + off, len)); tdb->transaction->transaction_error = 1; return -1; } /* write while in a transaction - this variant never expands the transaction blocks, it only updates existing blocks. This means it cannot change the recovery size */ static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { uint32_t blk; /* break it up into block sized chunks */ while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); if (transaction_write_existing(tdb, off, buf, len2) != 0) { return -1; } len -= len2; off += len2; if (buf != NULL) { buf = (const void *)(len2 + (const char *)buf); } } if (len == 0 || buf == NULL) { return 0; } blk = off / tdb->transaction->block_size; off = off % tdb->transaction->block_size; if (tdb->transaction->num_blocks <= blk || tdb->transaction->blocks[blk] == NULL) { return 0; } if (blk == tdb->transaction->num_blocks-1 && off + len > tdb->transaction->last_block_size) { if (off >= tdb->transaction->last_block_size) { return 0; } len = tdb->transaction->last_block_size - off; } /* overwrite part of an existing block */ memcpy(tdb->transaction->blocks[blk] + off, buf, len); return 0; } /* accelerated hash chain head search, using the cached hash heads */ static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) { uint32_t h = *chain; for (;h < tdb->hash_size;h++) { /* the +1 takes account of the freelist */ if (0 != tdb->transaction->hash_heads[h+1]) { break; } } (*chain) = h; } /* out of bounds check during a transaction */ static int transaction_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) { /* * This duplicates functionality from tdb_oob(). Don't remove: * we still have direct callers of tdb->methods->tdb_oob() * inside transaction.c. */ if (off + len >= off && off + len <= tdb->map_size) { return 0; } tdb->ecode = TDB_ERR_IO; return -1; } /* transaction version of tdb_expand(). */ static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { const char buf_zero[8192] = {0}; size_t buf_len = sizeof(buf_zero); while (addition > 0) { size_t n = MIN(addition, buf_len); int ret; ret = transaction_write(tdb, size, buf_zero, n); if (ret != 0) { return ret; } addition -= n; size += n; } tdb->transaction->expanded = true; return 0; } static const struct tdb_methods transaction_methods = { transaction_read, transaction_write, transaction_next_hash_chain, transaction_oob, transaction_expand_file, }; /* * Is a transaction currently active on this context? * */ _PUBLIC_ bool tdb_transaction_active(struct tdb_context *tdb) { return (tdb->transaction != NULL); } /* start a tdb transaction. No token is returned, as only a single transaction is allowed to be pending per tdb_context */ static int _tdb_transaction_start(struct tdb_context *tdb, enum tdb_lock_flags lockflags) { /* some sanity checks */ if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n")); tdb->ecode = TDB_ERR_EINVAL; return -1; } /* cope with nested tdb_transaction_start() calls */ if (tdb->transaction != NULL) { if (!(tdb->flags & TDB_ALLOW_NESTING)) { tdb->ecode = TDB_ERR_NESTING; return -1; } tdb->transaction->nesting++; TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", tdb->transaction->nesting)); return 0; } if (tdb_have_extra_locks(tdb)) { /* the caller must not have any locks when starting a transaction as otherwise we'll be screwed by lack of nested locks in posix */ TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n")); tdb->ecode = TDB_ERR_LOCK; return -1; } if (tdb->travlocks.next != NULL) { /* you cannot use transactions inside a traverse (although you can use traverse inside a transaction) as otherwise you can end up with deadlock */ TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n")); tdb->ecode = TDB_ERR_LOCK; return -1; } tdb->transaction = (struct tdb_transaction *) calloc(sizeof(struct tdb_transaction), 1); if (tdb->transaction == NULL) { tdb->ecode = TDB_ERR_OOM; return -1; } /* a page at a time seems like a reasonable compromise between compactness and efficiency */ tdb->transaction->block_size = tdb->page_size; /* get the transaction write lock. This is a blocking lock. As discussed with Volker, there are a number of ways we could make this async, which we will probably do in the future */ if (tdb_transaction_lock(tdb, F_WRLCK, lockflags) == -1) { SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction); if ((lockflags & TDB_LOCK_WAIT) == 0) { tdb->ecode = TDB_ERR_NOLOCK; } else { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: " "failed to get transaction lock\n")); } return -1; } /* get a read lock from the freelist to the end of file. This is upgraded to a write lock during the commit */ if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, true) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n")); goto fail_allrecord_lock; } /* setup a copy of the hash table heads so the hash scan in traverse can be fast */ tdb->transaction->hash_heads = (uint32_t *) calloc(tdb->hash_size+1, sizeof(uint32_t)); if (tdb->transaction->hash_heads == NULL) { tdb->ecode = TDB_ERR_OOM; goto fail; } if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads, TDB_HASHTABLE_SIZE(tdb), 0) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n")); tdb->ecode = TDB_ERR_IO; goto fail; } /* make sure we know about any file expansions already done by anyone else */ tdb_oob(tdb, tdb->map_size, 1, 1); tdb->transaction->old_map_size = tdb->map_size; /* finally hook the io methods, replacing them with transaction specific methods */ tdb->transaction->io_methods = tdb->methods; tdb->methods = &transaction_methods; /* Trace at the end, so we get sequence number correct. */ tdb_trace(tdb, "tdb_transaction_start"); return 0; fail: tdb_allrecord_unlock(tdb, F_RDLCK, false); fail_allrecord_lock: tdb_transaction_unlock(tdb, F_WRLCK); SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return -1; } _PUBLIC_ int tdb_transaction_start(struct tdb_context *tdb) { return _tdb_transaction_start(tdb, TDB_LOCK_WAIT); } _PUBLIC_ int tdb_transaction_start_nonblock(struct tdb_context *tdb) { return _tdb_transaction_start(tdb, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); } /* sync to disk */ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) { if (tdb->flags & TDB_NOSYNC) { return 0; } #ifdef HAVE_FDATASYNC if (fdatasync(tdb->fd) != 0) { #else if (fsync(tdb->fd) != 0) { #endif tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); return -1; } #ifdef HAVE_MMAP if (tdb->map_ptr) { tdb_off_t moffset = offset & ~(tdb->page_size-1); if (msync(moffset + (char *)tdb->map_ptr, length + (offset - moffset), MS_SYNC) != 0) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", strerror(errno))); return -1; } } #endif return 0; } static int _tdb_transaction_cancel(struct tdb_context *tdb) { uint32_t i; int ret = 0; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); return -1; } if (tdb->transaction->nesting != 0) { tdb->transaction->transaction_error = 1; tdb->transaction->nesting--; return 0; } tdb->map_size = tdb->transaction->old_map_size; /* free all the transaction blocks */ for (i=0;itransaction->num_blocks;i++) { if ((tdb->transaction->blocks != NULL) && tdb->transaction->blocks[i] != NULL) { free(tdb->transaction->blocks[i]); } } SAFE_FREE(tdb->transaction->blocks); if (tdb->transaction->magic_offset) { const struct tdb_methods *methods = tdb->transaction->io_methods; const uint32_t invalid = TDB_RECOVERY_INVALID_MAGIC; /* remove the recovery marker */ if (methods->tdb_write(tdb, tdb->transaction->magic_offset, &invalid, 4) == -1 || transaction_sync(tdb, tdb->transaction->magic_offset, 4) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_cancel: failed to remove recovery magic\n")); ret = -1; } } /* This also removes the OPEN_LOCK, if we have it. */ tdb_release_transaction_locks(tdb); /* restore the normal io methods */ tdb->methods = tdb->transaction->io_methods; SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return ret; } /* cancel the current transaction */ _PUBLIC_ int tdb_transaction_cancel(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_transaction_cancel"); return _tdb_transaction_cancel(tdb); } /* work out how much space the linearised recovery data will consume */ static bool tdb_recovery_size(struct tdb_context *tdb, tdb_len_t *result) { tdb_len_t recovery_size = 0; uint32_t i; recovery_size = sizeof(uint32_t); for (i=0;itransaction->num_blocks;i++) { tdb_len_t block_size; if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { break; } if (tdb->transaction->blocks[i] == NULL) { continue; } if (!tdb_add_len_t(recovery_size, 2*sizeof(tdb_off_t), &recovery_size)) { return false; } if (i == tdb->transaction->num_blocks-1) { block_size = tdb->transaction->last_block_size; } else { block_size = tdb->transaction->block_size; } if (!tdb_add_len_t(recovery_size, block_size, &recovery_size)) { return false; } } *result = recovery_size; return true; } int tdb_recovery_area(struct tdb_context *tdb, const struct tdb_methods *methods, tdb_off_t *recovery_offset, struct tdb_record *rec) { int ret; if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, recovery_offset) == -1) { return -1; } if (*recovery_offset == 0) { rec->rec_len = 0; return 0; } if (methods->tdb_read(tdb, *recovery_offset, rec, sizeof(*rec), DOCONV()) == -1) { return -1; } /* ignore invalid recovery regions: can happen in crash */ if (rec->magic != TDB_RECOVERY_MAGIC && rec->magic != TDB_RECOVERY_INVALID_MAGIC) { *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; } /* allocate the recovery area, or use an existing recovery area if it is large enough */ static int tdb_recovery_allocate(struct tdb_context *tdb, tdb_len_t *recovery_size, tdb_off_t *recovery_offset, tdb_len_t *recovery_max_size) { struct tdb_record rec; const struct tdb_methods *methods = tdb->transaction->io_methods; tdb_off_t recovery_head, new_end; if (tdb_recovery_area(tdb, methods, &recovery_head, &rec) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); return -1; } if (!tdb_recovery_size(tdb, recovery_size)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " "overflow recovery size\n")); return -1; } /* Existing recovery area? */ if (recovery_head != 0 && *recovery_size <= rec.rec_len) { /* it fits in the existing area */ *recovery_max_size = rec.rec_len; *recovery_offset = recovery_head; return 0; } /* If recovery area in middle of file, we need a new one. */ if (recovery_head == 0 || recovery_head + sizeof(rec) + rec.rec_len != tdb->map_size) { /* we need to free up the old recovery area, then allocate a new one at the end of the file. Note that we cannot use tdb_allocate() to allocate the new one as that might return us an area that is being currently used (as of the start of the transaction) */ if (recovery_head) { if (tdb_free(tdb, recovery_head, &rec) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to" " free previous recovery area\n")); return -1; } /* the tdb_free() call might have increased * the recovery size */ if (!tdb_recovery_size(tdb, recovery_size)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " "overflow recovery size\n")); return -1; } } /* New head will be at end of file. */ recovery_head = tdb->map_size; } /* Now we know where it will be. */ *recovery_offset = recovery_head; /* Expand by more than we need, so we don't do it often. */ *recovery_max_size = tdb_expand_adjust(tdb->map_size, *recovery_size, tdb->page_size) - sizeof(rec); if (!tdb_add_off_t(recovery_head, sizeof(rec), &new_end) || !tdb_add_off_t(new_end, *recovery_max_size, &new_end)) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " "overflow recovery area\n")); return -1; } if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, new_end - tdb->transaction->old_map_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); return -1; } /* remap the file (if using mmap) */ methods->tdb_oob(tdb, tdb->map_size, 1, 1); /* we have to reset the old map size so that we don't try to expand the file again in the transaction commit, which would destroy the recovery area */ tdb->transaction->old_map_size = tdb->map_size; /* write the recovery header offset and sync - we can sync without a race here as the magic ptr in the recovery record has not been set */ CONVERT(recovery_head); if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; } if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; } return 0; } /* setup the recovery data that will be used on a crash during commit */ static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t *magic_offset) { tdb_len_t recovery_size; unsigned char *data, *p; const struct tdb_methods *methods = tdb->transaction->io_methods; struct tdb_record *rec; 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; /* check that the recovery area has enough space */ if (tdb_recovery_allocate(tdb, &recovery_size, &recovery_offset, &recovery_max_size) == -1) { return -1; } rec = malloc(recovery_size + sizeof(*rec)); if (rec == NULL) { tdb->ecode = TDB_ERR_OOM; return -1; } memset(rec, 0, sizeof(*rec)); rec->magic = TDB_RECOVERY_INVALID_MAGIC; rec->data_len = recovery_size; rec->rec_len = recovery_max_size; 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); for (i=0;itransaction->num_blocks;i++) { tdb_off_t offset; tdb_len_t length; if (tdb->transaction->blocks[i] == NULL) { continue; } offset = i * tdb->transaction->block_size; length = tdb->transaction->block_size; if (i == tdb->transaction->num_blocks-1) { length = tdb->transaction->last_block_size; } if (offset >= old_map_size) { continue; } if (offset + length > tdb->transaction->old_map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); free(data); tdb->ecode = TDB_ERR_CORRUPT; return -1; } memcpy(p, &offset, 4); memcpy(p+4, &length, 4); if (DOCONV()) { tdb_convert(p, 8); } /* the recovery area contains the old data, not the new data, so we have to call the original tdb_read method to get it */ if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { free(data); tdb->ecode = TDB_ERR_IO; return -1; } p += 8 + length; } /* and the tailer */ tailer = sizeof(*rec) + recovery_max_size; memcpy(p, &tailer, 4); if (DOCONV()) { tdb_convert(p, 4); } /* write the recovery data to the recovery area */ if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n")); free(data); tdb->ecode = TDB_ERR_IO; return -1; } if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); free(data); tdb->ecode = TDB_ERR_IO; return -1; } /* as we don't have ordered writes, we have to sync the recovery data before we update the magic to indicate that the recovery data is present */ if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { free(data); return -1; } free(data); magic = TDB_RECOVERY_MAGIC; CONVERT(magic); *magic_offset = recovery_offset + offsetof(struct tdb_record, magic); if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); tdb->ecode = TDB_ERR_IO; return -1; } /* ensure the recovery magic marker is on disk */ if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { return -1; } return 0; } static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) { const struct tdb_methods *methods; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: no transaction\n")); return -1; } if (tdb->transaction->prepared) { tdb->ecode = TDB_ERR_EINVAL; _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction already prepared\n")); return -1; } if (tdb->transaction->transaction_error) { tdb->ecode = TDB_ERR_IO; _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction error pending\n")); return -1; } if (tdb->transaction->nesting != 0) { return 0; } /* check for a null transaction */ if (tdb->transaction->blocks == NULL) { return 0; } methods = tdb->transaction->io_methods; /* if there are any locks pending then the caller has not nested their locks properly, so fail the transaction */ if (tdb_have_extra_locks(tdb)) { tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: locks pending on commit\n")); _tdb_transaction_cancel(tdb); return -1; } /* upgrade the main transaction lock region to a write lock */ if (tdb_allrecord_upgrade(tdb) == -1) { if (tdb->ecode == TDB_ERR_RDONLY && tdb->read_only) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: " "failed to upgrade hash locks: " "database is read only\n")); } else if (tdb->ecode == TDB_ERR_RDONLY && tdb->traverse_read) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: " "failed to upgrade hash locks: " "a database traverse is in progress\n")); } else { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: " "failed to upgrade hash locks: %s\n", tdb_errorstr(tdb))); } _tdb_transaction_cancel(tdb); return -1; } /* get the open lock - this prevents new users attaching to the database during the commit */ if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to get open lock\n")); _tdb_transaction_cancel(tdb); return -1; } /* write the recovery data to the end of the file */ if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: failed to setup recovery data\n")); _tdb_transaction_cancel(tdb); return -1; } tdb->transaction->prepared = true; /* expand the file to the new size if needed */ if (tdb->map_size != tdb->transaction->old_map_size) { if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, tdb->map_size - tdb->transaction->old_map_size) == -1) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: expansion failed\n")); _tdb_transaction_cancel(tdb); return -1; } tdb->map_size = tdb->transaction->old_map_size; methods->tdb_oob(tdb, tdb->map_size, 1, 1); } /* Keep the open lock until the actual commit */ return 0; } /* prepare to commit the current transaction */ _PUBLIC_ int tdb_transaction_prepare_commit(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_transaction_prepare_commit"); return _tdb_transaction_prepare_commit(tdb); } /* A repack is worthwhile if the largest is less than half total free. */ static bool repack_worthwhile(struct tdb_context *tdb) { tdb_off_t ptr; struct tdb_record rec; tdb_len_t total = 0, largest = 0; if (tdb_ofs_read(tdb, FREELIST_TOP, &ptr) == -1) { return false; } while (ptr != 0 && tdb_rec_free_read(tdb, ptr, &rec) == 0) { total += rec.rec_len; if (rec.rec_len > largest) { largest = rec.rec_len; } ptr = rec.next; } return total > largest * 2; } /* commit the current transaction */ _PUBLIC_ int tdb_transaction_commit(struct tdb_context *tdb) { const struct tdb_methods *methods; uint32_t i; bool need_repack = false; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); return -1; } tdb_trace(tdb, "tdb_transaction_commit"); if (tdb->transaction->transaction_error) { tdb->ecode = TDB_ERR_IO; _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n")); return -1; } if (tdb->transaction->nesting != 0) { tdb->transaction->nesting--; return 0; } /* check for a null transaction */ if (tdb->transaction->blocks == NULL) { _tdb_transaction_cancel(tdb); return 0; } if (!tdb->transaction->prepared) { int ret = _tdb_transaction_prepare_commit(tdb); if (ret) return ret; } methods = tdb->transaction->io_methods; /* perform all the writes */ for (i=0;itransaction->num_blocks;i++) { tdb_off_t offset; tdb_len_t length; if (tdb->transaction->blocks[i] == NULL) { continue; } offset = i * tdb->transaction->block_size; length = tdb->transaction->block_size; if (i == tdb->transaction->num_blocks-1) { length = tdb->transaction->last_block_size; } if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); /* we've overwritten part of the data and possibly expanded the file, so we need to run the crash recovery code */ tdb->methods = methods; tdb_transaction_recover(tdb); _tdb_transaction_cancel(tdb); TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); return -1; } SAFE_FREE(tdb->transaction->blocks[i]); } /* Do this before we drop lock or blocks. */ if (tdb->transaction->expanded) { need_repack = repack_worthwhile(tdb); } SAFE_FREE(tdb->transaction->blocks); tdb->transaction->num_blocks = 0; /* ensure the new data is on disk */ if (transaction_sync(tdb, 0, tdb->map_size) == -1) { return -1; } /* TODO: maybe write to some dummy hdr field, or write to magic offset without mmap, before the last sync, instead of the utime() call */ /* on some systems (like Linux 2.6.x) changes via mmap/msync don't change the mtime of the file, this means the file may not be backed up (as tdb rounding to block sizes means that file size changes are quite rare too). The following forces mtime changes when a transaction completes */ #ifdef HAVE_UTIME utime(tdb->name, NULL); #endif /* use a transaction cancel to free memory and remove the transaction locks */ _tdb_transaction_cancel(tdb); if (need_repack) { int ret = tdb_repack(tdb); if (ret != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to repack database (not fatal)\n")); } /* * Ignore the error. * * Why? * * We just committed to the DB above, so anything * written during the transaction is committed, the * caller needs to know that the long-term state was * successfully modified. * * tdb_repack is an optimization that can fail for * reasons like lock ordering and we cannot recover * the transaction lock at this point, having released * it above. * * If we return a failure the caller thinks the * transaction was rolled back. */ } return 0; } /* recover from an aborted transaction. Must be called with exclusive database write access already established (including the open lock to prevent new processes attaching) */ int tdb_transaction_recover(struct tdb_context *tdb) { tdb_off_t recovery_head, recovery_eof; unsigned char *data, *p; uint32_t zero = 0; struct tdb_record rec; /* find the recovery area */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (recovery_head == 0) { /* we have never allocated a recovery record */ return 0; } /* read the recovery record */ if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (rec.magic != TDB_RECOVERY_MAGIC) { /* there is no valid recovery data */ return 0; } if (tdb->read_only) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n")); tdb->ecode = TDB_ERR_CORRUPT; return -1; } recovery_eof = rec.key_len; data = (unsigned char *)malloc(rec.data_len); if (data == NULL) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); tdb->ecode = TDB_ERR_OOM; return -1; } /* read the full recovery data */ if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, rec.data_len, 0) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); tdb->ecode = TDB_ERR_IO; return -1; } /* recover the file data */ p = data; while (p+8 < data + rec.data_len) { uint32_t ofs, len; if (DOCONV()) { tdb_convert(p, 8); } memcpy(&ofs, p, 4); memcpy(&len, p+4, 4); if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) { free(data); TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %u bytes at offset %u\n", len, ofs)); tdb->ecode = TDB_ERR_IO; return -1; } p += 8 + len; } free(data); if (transaction_sync(tdb, 0, tdb->map_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n")); tdb->ecode = TDB_ERR_IO; return -1; } /* if the recovery area is after the recovered eof then remove it */ if (recovery_eof <= recovery_head) { if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); tdb->ecode = TDB_ERR_IO; return -1; } } /* remove the recovery magic */ if (tdb_ofs_write(tdb, recovery_head + offsetof(struct tdb_record, magic), &zero) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); tdb->ecode = TDB_ERR_IO; return -1; } if (transaction_sync(tdb, 0, recovery_eof) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n")); tdb->ecode = TDB_ERR_IO; return -1; } TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %u byte database\n", recovery_eof)); /* all done */ return 0; } /* Any I/O failures we say "needs recovery". */ bool tdb_needs_recovery(struct tdb_context *tdb) { tdb_off_t recovery_head; struct tdb_record rec; /* find the recovery area */ if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { return true; } if (recovery_head == 0) { /* we have never allocated a recovery record */ return false; } /* read the recovery record */ if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { return true; } return (rec.magic == TDB_RECOVERY_MAGIC); } ldb-2.0.8/lib/tdb/common/traverse.c0000660000000000000000000003312613573675413017047 0ustar rootroot00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2005 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include "tdb_private.h" #define TDB_NEXT_LOCK_ERR ((tdb_off_t)-1) /* Uses traverse lock: 0 = finish, TDB_NEXT_LOCK_ERR = error, other = record offset */ static tdb_off_t tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock, struct tdb_record *rec) { int want_next = (tlock->off != 0); /* Lock each chain from the start one. */ for (; tlock->list < tdb->hash_size; tlock->list++) { if (!tlock->off && tlock->list != 0) { /* this is an optimisation for the common case where the hash chain is empty, which is particularly common for the use of tdb with ldb, where large hashes are used. In that case we spend most of our time in tdb_brlock(), locking empty hash chains. To avoid this, we do an unlocked pre-check to see if the hash chain is empty before starting to look inside it. If it is empty then we can avoid that hash chain. If it isn't empty then we can't believe the value we get back, as we read it without a lock, so instead we get the lock and re-fetch the value below. Notice that not doing this optimisation on the first hash chain is critical. We must guarantee that we have done at least one fcntl lock at the start of a search to guarantee that memory is coherent on SMP systems. If records are added by others during the search then thats OK, and we could possibly miss those with this trick, but we could miss them anyway without this trick, so the semantics don't change. With a non-indexed ldb search this trick gains us a factor of around 80 in speed on a linux 2.6.x system (testing using ldbtest). */ tdb->methods->next_hash_chain(tdb, &tlock->list); if (tlock->list == tdb->hash_size) { continue; } } if (tdb_lock(tdb, tlock->list, tlock->lock_rw) == -1) return TDB_NEXT_LOCK_ERR; /* No previous record? Start at top of chain. */ if (!tlock->off) { if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->list), &tlock->off) == -1) goto fail; } else { /* Otherwise unlock the previous record. */ if (tdb_unlock_record(tdb, tlock->off) != 0) goto fail; } if (want_next) { /* We have offset of old record: grab next */ if (tdb_rec_read(tdb, tlock->off, rec) == -1) goto fail; tlock->off = rec->next; } /* Iterate through chain */ while( tlock->off) { if (tdb_rec_read(tdb, tlock->off, rec) == -1) goto fail; /* Detect infinite loops. From "Shlomi Yaakobovich" . */ if (tlock->off == rec->next) { tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n")); goto fail; } if (!TDB_DEAD(rec)) { /* Woohoo: we found one! */ if (tdb_lock_record(tdb, tlock->off) != 0) goto fail; return tlock->off; } tlock->off = rec->next; } tdb_unlock(tdb, tlock->list, tlock->lock_rw); want_next = 0; } /* We finished iteration without finding anything */ tdb->ecode = TDB_SUCCESS; return 0; fail: tlock->off = 0; if (tdb_unlock(tdb, tlock->list, tlock->lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n")); return TDB_NEXT_LOCK_ERR; } /* traverse the entire database - calling fn(tdb, key, data) on each element. return -1 on error or the record count traversed if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop */ static int tdb_traverse_internal(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data, struct tdb_traverse_lock *tl) { TDB_DATA key, dbuf; struct tdb_record rec; int ret = 0, count = 0; tdb_off_t off; size_t recbuf_len; recbuf_len = 4096; key.dptr = malloc(recbuf_len); if (key.dptr == NULL) { return -1; } /* This was in the initialization, above, but the IRIX compiler * did not like it. crh */ tl->next = tdb->travlocks.next; /* fcntl locks don't stack: beware traverse inside traverse */ tdb->travlocks.next = tl; /* 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; 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; /* * No realloc, we don't need the old data and thus can * do without the memcpy */ free(key.dptr); key.dptr = malloc(recbuf_len); if (key.dptr == NULL) { ret = -1; if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) { goto out; } if (tdb_unlock_record(tdb, tl->off) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: malloc " "failed and unlock_record " "failed!\n")); } goto out; } } count++; /* now read the full record */ nread = tdb->methods->tdb_read(tdb, tl->off + sizeof(rec), key.dptr, full_len, 0); if (nread == -1) { ret = -1; if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) goto out; if (tdb_unlock_record(tdb, tl->off) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); goto out; } key.dsize = rec.key_len; dbuf.dptr = key.dptr + rec.key_len; dbuf.dsize = rec.data_len; tdb_trace_1rec_retrec(tdb, "traverse", key, dbuf); /* Drop chain lock, call out */ if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) { ret = -1; goto out; } if (fn && fn(tdb, key, dbuf, private_data)) { /* They want us to terminate traversal */ tdb_trace_ret(tdb, "tdb_traverse_end", count); if (tdb_unlock_record(tdb, tl->off) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; ret = -1; } goto out; } } tdb_trace(tdb, "tdb_traverse_end"); out: SAFE_FREE(key.dptr); tdb->travlocks.next = tl->next; if (ret < 0) return -1; else return count; } /* a read style traverse - temporarily marks each record read only */ _PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; int ret; tdb->traverse_read++; tdb_trace(tdb, "tdb_traverse_read_start"); ret = tdb_traverse_internal(tdb, fn, private_data, &tl); tdb->traverse_read--; return ret; } /* a write style traverse - needs to get the transaction lock to prevent deadlocks WARNING: The data buffer given to the callback fn does NOT meet the alignment guarantees malloc gives you. */ _PUBLIC_ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; enum tdb_lock_flags lock_flags; int ret; if (tdb->read_only || tdb->traverse_read) { return tdb_traverse_read(tdb, fn, private_data); } lock_flags = TDB_LOCK_WAIT; if (tdb->allrecord_lock.count != 0) { /* * This avoids a deadlock between tdb_lockall() and * tdb_traverse(). See * https://bugzilla.samba.org/show_bug.cgi?id=11381 */ lock_flags = TDB_LOCK_NOWAIT; } if (tdb_transaction_lock(tdb, F_WRLCK, lock_flags)) { return -1; } tdb->traverse_write++; tdb_trace(tdb, "tdb_traverse_start"); ret = tdb_traverse_internal(tdb, fn, private_data, &tl); tdb->traverse_write--; tdb_transaction_unlock(tdb, F_WRLCK); return ret; } /* find the first entry in the database and return its key */ _PUBLIC_ TDB_DATA tdb_firstkey(struct tdb_context *tdb) { TDB_DATA key; struct tdb_record rec; tdb_off_t off; /* release any old lock */ if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) return tdb_null; tdb->travlocks.off = tdb->travlocks.list = 0; tdb->travlocks.lock_rw = F_RDLCK; /* Grab first record: locks chain and returned record. */ off = tdb_next_lock(tdb, &tdb->travlocks, &rec); if (off == 0 || off == TDB_NEXT_LOCK_ERR) { tdb_trace_retrec(tdb, "tdb_firstkey", tdb_null); return tdb_null; } /* now read the key */ key.dsize = rec.key_len; key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); tdb_trace_retrec(tdb, "tdb_firstkey", key); /* Unlock the hash chain of the record we just read. */ if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); return key; } /* find the next entry in the database, returning its key */ _PUBLIC_ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) { uint32_t oldlist; TDB_DATA key = tdb_null; struct tdb_record rec; unsigned char *k = NULL; tdb_off_t off; /* Is locked key the old key? If so, traverse will be reliable. */ if (tdb->travlocks.off) { if (tdb_lock(tdb,tdb->travlocks.list,tdb->travlocks.lock_rw)) return tdb_null; if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), rec.key_len)) || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { /* No, it wasn't: unlock it and start from scratch */ if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) { tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, tdb_null); SAFE_FREE(k); return tdb_null; } if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) { SAFE_FREE(k); return tdb_null; } tdb->travlocks.off = 0; } SAFE_FREE(k); } if (!tdb->travlocks.off) { /* No previous element: do normal find, and lock record */ tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); if (!tdb->travlocks.off) { tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, tdb_null); return tdb_null; } tdb->travlocks.list = BUCKET(rec.full_hash); if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); return tdb_null; } } oldlist = tdb->travlocks.list; /* Grab next record: locks chain and returned record, unlocks old record */ off = tdb_next_lock(tdb, &tdb->travlocks, &rec); if (off != TDB_NEXT_LOCK_ERR && off != 0) { key.dsize = rec.key_len; key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), key.dsize); /* Unlock the chain of this new record */ if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); } /* Unlock the chain of old record */ if (tdb_unlock(tdb, oldlist, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, key); return key; } _PUBLIC_ int tdb_traverse_chain(struct tdb_context *tdb, unsigned chain, tdb_traverse_func fn, void *private_data) { tdb_off_t rec_ptr; struct tdb_chainwalk_ctx chainwalk; int count = 0; int ret; if (chain >= tdb->hash_size) { tdb->ecode = TDB_ERR_EINVAL; return -1; } if (tdb->traverse_read != 0) { tdb->ecode = TDB_ERR_LOCK; return -1; } ret = tdb_lock(tdb, chain, F_RDLCK); if (ret == -1) { return -1; } tdb->traverse_read += 1; ret = tdb_ofs_read(tdb, TDB_HASH_TOP(chain), &rec_ptr); if (ret == -1) { goto fail; } tdb_chainwalk_init(&chainwalk, rec_ptr); while (rec_ptr != 0) { struct tdb_record rec; bool ok; ret = tdb_rec_read(tdb, rec_ptr, &rec); if (ret == -1) { goto fail; } if (!TDB_DEAD(&rec)) { /* no overflow checks, tdb_rec_read checked it */ tdb_off_t key_ofs = rec_ptr + sizeof(rec); size_t full_len = rec.key_len + rec.data_len; uint8_t *buf = NULL; TDB_DATA key = { .dsize = rec.key_len }; TDB_DATA data = { .dsize = rec.data_len }; if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { ret = tdb_oob(tdb, key_ofs, full_len, 0); if (ret == -1) { goto fail; } key.dptr = (uint8_t *)tdb->map_ptr + key_ofs; } else { buf = tdb_alloc_read(tdb, key_ofs, full_len); if (buf == NULL) { goto fail; } key.dptr = buf; } data.dptr = key.dptr + key.dsize; ret = fn(tdb, key, data, private_data); free(buf); count += 1; if (ret != 0) { break; } } rec_ptr = rec.next; ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); if (!ok) { goto fail; } } tdb->traverse_read -= 1; tdb_unlock(tdb, chain, F_RDLCK); return count; fail: tdb->traverse_read -= 1; tdb_unlock(tdb, chain, F_RDLCK); return -1; } _PUBLIC_ int tdb_traverse_key_chain(struct tdb_context *tdb, TDB_DATA key, tdb_traverse_func fn, void *private_data) { uint32_t hash, chain; int ret; hash = tdb->hash_fn(&key); chain = BUCKET(hash); ret = tdb_traverse_chain(tdb, chain, fn, private_data); return ret; } ldb-2.0.8/lib/tdb/configure0000770000000000000000000000066013573675413015463 0ustar rootroot00000000000000#!/bin/sh PREVPATH=`dirname $0` if [ -f $PREVPATH/../../buildtools/bin/waf ]; then WAF=../../buildtools/bin/waf elif [ -f $PREVPATH/buildtools/bin/waf ]; then WAF=./buildtools/bin/waf else echo "replace: Unable to find waf" exit 1 fi # using JOBS=1 gives maximum compatibility with # systems like AIX which have broken threading in python JOBS=1 export JOBS cd . || exit 1 $PYTHON $WAF configure "$@" || exit 1 cd $PREVPATH ldb-2.0.8/lib/tdb/docs/README0000660000000000000000000002446013573675413015371 0ustar rootroot00000000000000tdb - a trivial database system tridge@linuxcare.com December 1999 ================================== This is a simple database API. It was inspired by the realisation that in Samba we have several ad-hoc bits of code that essentially implement small databases for sharing structures between parts of Samba. As I was about to add another I realised that a generic database module was called for to replace all the ad-hoc bits. I based the interface on gdbm. I couldn't use gdbm as we need to be able to have multiple writers to the databases at one time. Compilation ----------- add HAVE_MMAP=1 to use mmap instead of read/write add NOLOCK=1 to disable locking code Testing ------- Compile tdbtest.c and link with gdbm for testing. tdbtest will perform identical operations via tdb and gdbm then make sure the result is the same Also included is tdbtool, which allows simple database manipulation on the commandline. tdbtest and tdbtool are not built as part of Samba, but are included for completeness. Interface --------- The interface is very similar to gdbm except for the following: - different open interface. The tdb_open call is more similar to a traditional open() - no tdbm_reorganise() function - no tdbm_sync() function. No operations are cached in the library anyway - added a tdb_traverse() function for traversing the whole database - added transactions support A general rule for using tdb is that the caller frees any returned TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA return value called p. This is the same as gdbm. here is a full list of tdb functions with brief descriptions. ---------------------------------------------------------------------- TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the database file. A flags value of O_WRONLY is invalid The hash size is advisory, use zero for a default value. return is NULL on error possible tdb_flags are: TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open TDB_INTERNAL - don't use a file, instead store the data in memory. The filename is ignored in this case. TDB_NOLOCK - don't do any locking TDB_NOMMAP - don't use mmap TDB_NOSYNC - don't synchronise transactions to disk TDB_SEQNUM - maintain a sequence number TDB_VOLATILE - activate the per-hashchain freelist, default 5 TDB_ALLOW_NESTING - allow transactions to nest TDB_DISALLOW_NESTING - disallow transactions to nest ---------------------------------------------------------------------- TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn) This is like tdb_open(), but allows you to pass an initial logging and hash function. Be careful when passing a hash function - all users of the database must use the same hash function or you will get data corruption. ---------------------------------------------------------------------- char *tdb_error(TDB_CONTEXT *tdb); return a error string for the last tdb error ---------------------------------------------------------------------- int tdb_close(TDB_CONTEXT *tdb); close a database ---------------------------------------------------------------------- TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); fetch an entry in the database given a key if the return value has a null dptr then a error occurred caller must free the resulting data ---------------------------------------------------------------------- int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); Hand a record to a parser function without allocating it. This function is meant as a fast tdb_fetch alternative for large records that are frequently read. The "key" and "data" arguments point directly into the tdb shared memory, they are not aligned at any boundary. WARNING: The parser is called while tdb holds a lock on the record. DO NOT call other tdb routines from within the parser. Also, for good performance you should make the parser fast to allow parallel operations. tdb_parse_record returns -1 if the record was not found. If the record was found, the return value of "parser" is passed up to the caller. ---------------------------------------------------------------------- int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); check if an entry in the database exists note that 1 is returned if the key is found and 0 is returned if not found this doesn't match the conventions in the rest of this module, but is compatible with gdbm ---------------------------------------------------------------------- int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state), void *state); traverse the entire database - calling fn(tdb, key, data, state) on each element. return -1 on error or the record count traversed if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop. Traversal callbacks may not start transactions. WARNING: The data buffer given to the callback fn does NOT meet the alignment restrictions malloc gives you. ---------------------------------------------------------------------- int tdb_traverse_read(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state), void *state); traverse the entire database - calling fn(tdb, key, data, state) on each element, but marking the database read only during the traversal, so any write operations will fail. This allows tdb to use read locks, which increases the parallelism possible during the traversal. return -1 on error or the record count traversed if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop. Traversal callbacks may not start transactions. ---------------------------------------------------------------------- TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); find the first entry in the database and return its key the caller must free the returned data ---------------------------------------------------------------------- TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); find the next entry in the database, returning its key the caller must free the returned data ---------------------------------------------------------------------- int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); delete an entry in the database given a key ---------------------------------------------------------------------- int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); store an element in the database, replacing any existing element with the same key If flag==TDB_INSERT then don't overwrite an existing entry If flag==TDB_MODIFY then don't create a new entry return 0 on success, -1 on failure ---------------------------------------------------------------------- int tdb_writelock(TDB_CONTEXT *tdb); lock the database. If we already have it locked then don't do anything ---------------------------------------------------------------------- int tdb_writeunlock(TDB_CONTEXT *tdb); unlock the database ---------------------------------------------------------------------- int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); lock one hash chain. This is meant to be used to reduce locking contention - it cannot guarantee how many records will be locked ---------------------------------------------------------------------- int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); unlock one hash chain ---------------------------------------------------------------------- int tdb_transaction_start(TDB_CONTEXT *tdb) start a transaction. All operations after the transaction start can either be committed with tdb_transaction_commit() or cancelled with tdb_transaction_cancel(). If you call tdb_transaction_start() again on the same tdb context while a transaction is in progress, then the same transaction buffer is re-used. The number of tdb_transaction_{commit,cancel} operations must match the number of successful tdb_transaction_start() calls. Note that transactions are by default disk synchronous, and use a recover area in the database to automatically recover the database on the next open if the system crashes during a transaction. You can disable the synchronous transaction recovery setup using the TDB_NOSYNC flag, which will greatly speed up operations at the risk of corrupting your database if the system crashes. Operations made within a transaction are not visible to other users of the database until a successful commit. ---------------------------------------------------------------------- int tdb_transaction_cancel(TDB_CONTEXT *tdb) cancel a current transaction, discarding all write and lock operations that have been made since the transaction started. ---------------------------------------------------------------------- int tdb_transaction_commit(TDB_CONTEXT *tdb) commit a current transaction, updating the database and releasing the transaction locks. ---------------------------------------------------------------------- int tdb_transaction_prepare_commit(TDB_CONTEXT *tdb) prepare to commit a current transaction, for two-phase commits. Once prepared for commit, the only allowed calls are tdb_transaction_commit() or tdb_transaction_cancel(). Preparing allocates disk space for the pending updates, so a subsequent commit should succeed (barring any hardware failures). ---------------------------------------------------------------------- int tdb_check(TDB_CONTEXT *tdb, int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data);) check the consistency of the database, calling back the check function (if non-NULL) with each record. If some consistency check fails, or the supplied check function returns -1, tdb_check returns -1, otherwise 0. Note that logging function (if set) will be called with additional information on the corruption found. ldb-2.0.8/lib/tdb/docs/mainpage.dox0000660000000000000000000000362712406075657017006 0ustar rootroot00000000000000/** @mainpage This is a simple database API. It was inspired by the realisation that in Samba we have several ad-hoc bits of code that essentially implement small databases for sharing structures between parts of Samba. The interface is based on gdbm. gdbm couldn't be use as we needed to be able to have multiple writers to the databases at one time. @section tdb_download Download You can download the latest releases of tdb from the tdb directory on the samba public source archive. You can download the latest code either via git or rsync. To fetch via git see the following guide: Using Git for Samba Development Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory. To fetch via rsync use these commands:
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
and build in tdb. It will find the replace library in the directory above automatically. @section tdb_bugs Discussion and bug reports tdb does not currently have its own mailing list or bug tracking system. For now, please use the samba-technical mailing list, and the Samba bugzilla bug tracking system. @section tdb_compilation Compilation add HAVE_MMAP=1 to use mmap instead of read/write add NOLOCK=1 to disable locking code @section tdb_testing Testing Compile tdbtest.c and link with gdbm for testing. tdbtest will perform identical operations via tdb and gdbm then make sure the result is the same Also included is tdbtool, which allows simple database manipulation on the commandline. tdbtest and tdbtool are not built as part of Samba, but are included for completeness. */ ldb-2.0.8/lib/tdb/docs/mutex.txt0000660000000000000000000001630312632255624016402 0ustar rootroot00000000000000Tdb is a hashtable database with multiple concurrent writer and external record lock support. For speed reasons, wherever possible tdb uses a shared memory mapped area for data access. In its currently released form, it uses fcntl byte-range locks to coordinate access to the data itself. The tdb data is organized as a hashtable. Hash collisions are dealt with by forming a linked list of records that share a hash value. The individual linked lists are protected across processes with 1-byte fcntl locks on the starting pointer of the linked list representing a hash value. The external locking API of tdb allows one to lock individual records. Instead of really locking individual records, the tdb API locks a complete linked list with a fcntl lock. The external locking API of tdb also allows one to lock the complete database, and ctdb uses this facility to freeze databases during a recovery. While the so-called allrecord lock is held, all linked lists and all individual records are frozen alltogether. Tdb achieves this by locking the complete file range with a single fcntl lock. Individual 1-byte locks for the linked lists conflict with this. Access to records is prevented by the one large fnctl byte range lock. Fcntl locks have been chosen for tdb for two reasons: First they are portable across all current unixes. Secondly they provide auto-cleanup. If a process dies while holding a fcntl lock, the lock is given up as if it was explicitly unlocked. Thus fcntl locks provide a very robust locking scheme, if a process dies for any reason the database will not stay blocked until reboot. This robustness is very important for long-running services, a reboot is not an option for most users of tdb. Unfortunately, during stress testing, fcntl locks have turned out to be a major problem for performance. The particular problem that was seen happens when ctdb on a busy server does a recovery. A recovery means that ctdb has to freeze all tdb databases for some time, usually a few seconds. This is done with the allrecord lock. During the recovery phase on a busy server many smbd processes try to access the tdb file with blocking fcntl calls. The specific test in question easily reproduces 7,000 processes piling up waiting for 1-byte fcntl locks. When ctdb is done with the recovery, it gives up the allrecord lock, covering the whole file range. All 7,000 processes waiting for 1-byte fcntl locks are woken up, trying to acquire their lock. The special implementation of fcntl locks in Linux (up to 2013-02-12 at least) protects all fcntl lock operations with a single system-wide spinlock. If 7,000 process waiting for the allrecord lock to become released this leads to a thundering herd condition, all CPUs are spinning on that single spinlock. Functionally the kernel is fine, eventually the thundering herd slows down and every process correctly gets his share and locking range, but the performance of the system while the herd is active is worse than expected. The thundering herd is only the worst case scenario for fcntl lock use. The single spinlock for fcntl operations is also a performance penalty for normal operations. In the cluster case, every read and write SMB request has to do two fcntl calls to provide correct SMB mandatory locks. The single spinlock is one source of serialization for the SMB read/write requests, limiting the parallelism that can be achieved in a multi-core system. While trying to tune his servers, Ira Cooper, Samba Team member, found fcntl locks to be a problem on Solaris as well. Ira pointed out that there is a potential alternative locking mechanism that might be more scalable: Process shared robust mutexes, as defined by Posix 2008 for example via http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html Pthread mutexes provide one of the core mechanisms in posix threads to protect in-process data structures from concurrent access by multiple threads. In the Linux implementation, a pthread_mutex_t is represented by a data structure in user space that requires no kernel calls in the uncontended case for locking and unlocking. Locking and unlocking in the uncontended case is implemented purely in user space with atomic CPU instructions and thus are very fast. The setpshared functions indicate to the kernel that the mutex is about to be shared between processes in a common shared memory area. The process shared posix mutexes have the potential to replace fcntl locking to coordinate mmap access for tdbs. However, they are missing the criticial auto-cleanup property that fcntl provides when a process dies. A process that dies hard while holding a shared mutex has no chance to clean up the protected data structures and unlock the shared mutex. Thus with a pure process shared mutex the mutex will remain locked forever until the data structures are re-initialized from scratch. With the robust mutexes defined by Posix the process shared mutexes have been extended with a limited auto-cleanup property. If a mutex has been declared robust, when a process exits while holding that mutex, the next process trying to lock the mutex will get the special error message EOWNERDEAD. This informs the caller that the data structures the mutex protects are potentially corrupt and need to be cleaned up. The error message EOWNERDEAD when trying to lock a mutex is an extension over the fcntl functionality. A process that does a blocking fcntl lock call is not informed about whether the lock was explicitly freed by a process still alive or due to an unplanned process exit. At the time of this writing (February 2013), at least Linux and OpenSolaris also implement the robustness feature of process-shared mutexes. Converting the tdb locking mechanism from fcntl to mutexes has to take care of both types of locks that are used on tdb files. The easy part is to use mutexes to replace the 1-byte linked list locks covering the individual hashes. Those can be represented by a mutex each. Covering the allrecord lock is more difficult. The allrecord lock uses a fcntl lock spanning all hash list locks simultaneously. This basic functionality is not easily possible with mutexes. A mutex carries 1 bit of information, a fcntl lock can carry an arbitrary amount of information. In order to support the allrecord lock, we have an allrecord_lock variable protected by an allrecord_mutex. The coordination between the allrecord lock and the chainlocks works like this: - Getting a chain lock works like this: 1. get chain mutex 2. return success if allrecord_lock is F_UNLCK (not locked) 3. return success if allrecord_lock is F_RDLCK (locked readonly) and we only need a read lock. 4. release chain mutex 5. wait for allrecord_mutex 6. unlock allrecord_mutex 7. goto 1. - Getting the allrecord lock: 1. get the allrecord mutex 2. return error if allrecord_lock is not F_UNLCK (it's locked) 3. set allrecord_lock to the desired value. 4. in a loop: lock(blocking) / unlock each chain mutex. 5. return success. - allrecord lock upgrade: 1. check we already have the allrecord lock with F_RDLCK. 3. set allrecord_lock to F_WRLCK 4. in a loop: lock(blocking) / unlock each chain mutex. 5. return success. ldb-2.0.8/lib/tdb/docs/tdb.magic0000660000000000000000000000053112406075657016253 0ustar rootroot00000000000000# Magic file(1) information about tdb files. # # Install this into /etc/magic or the corresponding location for your # system, or pass as a -m argument to file(1). # You may use and redistribute this file without restriction. 0 string TDB\ file TDB database >32 lelong =0x2601196D version 6, little-endian >>36 lelong x hash size %d bytes ldb-2.0.8/lib/tdb/docs/tracing.txt0000660000000000000000000000356412406075657016701 0ustar rootroot00000000000000How And Why To Use TDB Tracing ============================== You can trace all TDB operations, using TDB_TRACE. It is not complete (error conditions which expect to the logged will not always be traced correctly, so you should set up a logging function too), but is designed to collect benchmark-style traces to allow us to optimize TDB. Note: tracing is not efficient, and the trace files are huge: a traverse of the database is particularly large! But they compress very well with rzip (http://rzip.samba.org) How to gather trace files: -------------------------- 1) Uncomment /* #define TDB_TRACE 1 */ in tdb_private.h. 2) Rebuild TDB, and everything that uses it. 3) Run something. Your trace files will be called .trace.. These files will not be overwritten: if the same process reopens the same TDB, an error will be logged and tracing will be disabled. How to replay trace files: -------------------------- 1) For benchmarking, remember to rebuild tdb with #define TDB_TRACE commented out again! 2) Grab the latest "replace_trace.c" from CCAN's tdb module (tools/ dir): http://ccan.ozlabs.org/tarballs/tdb.tar.bz2 3) Compile up replay_trace, munging as necessary. 4) Run replay_trace ... If given more than one trace file (presumably from the same tdb) replay_trace will try to figure out the dependencies between the operations and fire off a child to run each trace. Occasionally it gets stuck, in which case it will add another dependency and retry. Eventually it will give a speed value. replay_trace can intuit the existence of previous data in the tdb (ie. activity prior to the trace(s) supplied) and will prepopulate as neccessary. You can run --quiet for straight benchmark results, and -n to run multiple times (this saves time, since it need only calculate dependencies once). Good luck! Rusty Russell ldb-2.0.8/lib/tdb/doxy.config0000660000000000000000000021316112406075657015727 0ustar rootroot00000000000000# Doxyfile 1.7.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = tdb # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 1.2.9 # Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = docs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = include \ docs # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [0,1..20]) # that doxygen will group on one line in the generated HTML documentation. # Note that a value of 0 will completely suppress the enum values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NONE # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN \ PRINTF_ATTRIBUTE(x,y)= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called Helvetica to the output # directory and reference it in all dot files that doxygen generates. # When you want a differently looking font you can specify the font name # using DOT_FONTNAME. You need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, svg, gif or svg. # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES ldb-2.0.8/lib/tdb/include/tdb.h0000660000000000000000000010203513573675413016121 0ustar rootroot00000000000000#ifndef __TDB_H__ #define __TDB_H__ /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2004 ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #ifdef __cplusplus extern "C" { #endif #include #include /** * @defgroup tdb The tdb API * * tdb is a Trivial database. In concept, it is very much like GDBM, and BSD's * DB except that it allows multiple simultaneous writers and uses locking * internally to keep writers from trampling on each other. tdb is also * extremely small. * * @section tdb_interface Interface * * The interface is very similar to gdbm except for the following: * *
    *
  • different open interface. The tdb_open call is more similar to a * traditional open()
  • *
  • no tdbm_reorganise() function
  • *
  • no tdbm_sync() function. No operations are cached in the library * anyway
  • *
  • added a tdb_traverse() function for traversing the whole database
  • *
  • added transactions support
  • *
* * A general rule for using tdb is that the caller frees any returned TDB_DATA * structures. Just call free(p.dptr) to free a TDB_DATA return value called p. * This is the same as gdbm. * * @{ */ /** Flags to tdb_store() */ #define TDB_REPLACE 1 /** Unused */ #define TDB_INSERT 2 /** Don't overwrite an existing entry */ #define TDB_MODIFY 3 /** Don't create an existing entry */ /** Flags for tdb_open() */ #define TDB_DEFAULT 0 /** just a readability place holder */ #define TDB_CLEAR_IF_FIRST 1 /** If this is the first open, wipe the db */ #define TDB_INTERNAL 2 /** Don't store on disk */ #define TDB_NOLOCK 4 /** Don't do any locking */ #define TDB_NOMMAP 8 /** Don't use mmap */ #define TDB_CONVERT 16 /** Convert endian (internal use) */ #define TDB_BIGENDIAN 32 /** Header is big-endian (internal use) */ #define TDB_NOSYNC 64 /** Don't use synchronous transactions */ #define TDB_SEQNUM 128 /** Maintain a sequence number */ #define TDB_VOLATILE 256 /** Activate the per-hashchain freelist, default 5 */ #define TDB_ALLOW_NESTING 512 /** Allow transactions to nest */ #define TDB_DISALLOW_NESTING 1024 /** Disallow transactions to nest */ #define TDB_INCOMPATIBLE_HASH 2048 /** Better hashing: can't be opened by tdb < 1.2.6. */ #define TDB_MUTEX_LOCKING 4096 /** optimized locking using robust mutexes if supported, only with tdb >= 1.3.0 and TDB_CLEAR_IF_FIRST after checking tdb_runtime_check_for_robust_mutexes() */ /** The tdb error codes */ enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY, TDB_ERR_NESTING}; /** Debugging uses one of the following levels */ enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; /** The tdb data structure */ typedef struct TDB_DATA { unsigned char *dptr; size_t dsize; } TDB_DATA; #ifndef PRINTF_ATTRIBUTE #if (__GNUC__ >= 3) /** Use gcc attribute to check printf fns. a1 is the 1-based index of * the parameter containing the format, and a2 the index of the first * argument. Note that some gcc 2.x versions don't handle this * properly **/ #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) #else #define PRINTF_ATTRIBUTE(a1, a2) #endif #endif /** This is the context structure that is returned from a db open. */ typedef struct tdb_context TDB_CONTEXT; typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4); typedef unsigned int (*tdb_hash_func)(TDB_DATA *key); struct tdb_logging_context { tdb_log_func log_fn; void *log_private; }; /** * @brief Open the database and creating it if necessary. * * @param[in] name The name of the db to open. * * @param[in] hash_size The hash size is advisory, use zero for a default * value. * * @param[in] tdb_flags The flags to use to open the db:\n\n * TDB_CLEAR_IF_FIRST - Clear database if we are the * only one with it open\n * TDB_INTERNAL - Don't use a file, instead store the * data in memory. The filename is * ignored in this case.\n * TDB_NOLOCK - Don't do any locking\n * TDB_NOMMAP - Don't use mmap\n * TDB_NOSYNC - Don't synchronise transactions to disk\n * TDB_SEQNUM - Maintain a sequence number\n * TDB_VOLATILE - activate the per-hashchain freelist, * default 5.\n * TDB_ALLOW_NESTING - Allow transactions to nest.\n * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, * can't be opened by tdb < 1.3.0. * Only valid in combination with TDB_CLEAR_IF_FIRST * after checking tdb_runtime_check_for_robust_mutexes()\n * * @param[in] open_flags Flags for the open(2) function. * * @param[in] mode The mode for the open(2) function. * * @return A tdb context structure, NULL on error. */ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); /** * @brief Open the database and creating it if necessary. * * This is like tdb_open(), but allows you to pass an initial logging and * hash function. Be careful when passing a hash function - all users of the * database must use the same hash function or you will get data corruption. * * @param[in] name The name of the db to open. * * @param[in] hash_size The hash size is advisory, use zero for a default * value. * * @param[in] tdb_flags The flags to use to open the db:\n\n * TDB_CLEAR_IF_FIRST - Clear database if we are the * only one with it open\n * TDB_INTERNAL - Don't use a file, instead store the * data in memory. The filename is * ignored in this case.\n * TDB_NOLOCK - Don't do any locking\n * TDB_NOMMAP - Don't use mmap\n * TDB_NOSYNC - Don't synchronise transactions to disk\n * TDB_SEQNUM - Maintain a sequence number\n * TDB_VOLATILE - activate the per-hashchain freelist, * default 5.\n * TDB_ALLOW_NESTING - Allow transactions to nest.\n * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, * can't be opened by tdb < 1.3.0. * Only valid in combination with TDB_CLEAR_IF_FIRST * after checking tdb_runtime_check_for_robust_mutexes()\n * * @param[in] open_flags Flags for the open(2) function. * * @param[in] mode The mode for the open(2) function. * * @param[in] log_ctx The logging function to use. * * @param[in] hash_fn The hash function you want to use. * * @return A tdb context structure, NULL on error. * * @see tdb_open() */ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn); /** * @brief Set the maximum number of dead records per hash chain. * * @param[in] tdb The database handle to set the maximum. * * @param[in] max_dead The maximum number of dead records per hash chain. */ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); /** * @brief Reopen a tdb. * * This can be used after a fork to ensure that we have an independent seek * pointer from our parent and to re-establish locks. * * @param[in] tdb The database to reopen. It will be free'd on error! * * @return 0 on success, -1 on error. * * @note Don't call tdb_error() after this function cause the tdb context will * be freed on error. */ int tdb_reopen(struct tdb_context *tdb); /** * @brief Reopen all tdb's * * If the parent is longlived (ie. a parent daemon architecture), we know it * will keep it's active lock on a tdb opened with CLEAR_IF_FIRST. Thus for * child processes we don't have to add an active lock. This is essential to * improve performance on systems that keep POSIX locks as a non-scalable data * structure in the kernel. * * @param[in] parent_longlived Whether the parent is longlived or not. * * @return 0 on success, -1 on error. */ int tdb_reopen_all(int parent_longlived); /** * @brief Set a different tdb logging function. * * @param[in] tdb The tdb to set the logging function. * * @param[in] log_ctx The logging function to set. */ void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); /** * @brief Get the tdb last error code. * * @param[in] tdb The tdb to get the error code from. * * @return A TDB_ERROR code. * * @see TDB_ERROR */ enum TDB_ERROR tdb_error(struct tdb_context *tdb); /** * @brief Get a error string for the last tdb error * * @param[in] tdb The tdb to get the error code from. * * @return An error string. */ const char *tdb_errorstr(struct tdb_context *tdb); /** * @brief Fetch an entry in the database given a key. * * The caller must free the resulting data. * * @param[in] tdb The tdb to fetch the key. * * @param[in] key The key to fetch. * * @return The key entry found in the database, NULL on error with * TDB_ERROR set. * * @see tdb_error() * @see tdb_errorstr() */ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); /** * @brief Hand a record to a parser function without allocating it. * * This function is meant as a fast tdb_fetch alternative for large records * that are frequently read. The "key" and "data" arguments point directly * into the tdb shared memory, they are not aligned at any boundary. * * @warning The parser is called while tdb holds a lock on the record. DO NOT * call other tdb routines from within the parser. Also, for good performance * you should make the parser fast to allow parallel operations. * * @param[in] tdb The tdb to parse the record. * * @param[in] key The key to parse. * * @param[in] parser The parser to use to parse the data. * * @param[in] private_data A private data pointer which is passed to the parser * function. * * @return -1 if the record was not found. If the record was found, * the return value of "parser" is passed up to the caller. */ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); /** * @brief Delete an entry in the database given a key. * * @param[in] tdb The tdb to delete the key. * * @param[in] key The key to delete. * * @return 0 on success, -1 if the key doesn't exist. */ int tdb_delete(struct tdb_context *tdb, TDB_DATA key); /** * @brief Store an element in the database. * * This replaces any existing element with the same key. * * @param[in] tdb The tdb to store the entry. * * @param[in] key The key to use to store the entry. * * @param[in] dbuf The data to store under the key. * * @param[in] flag The flags to store the key:\n\n * TDB_INSERT: Don't overwrite an existing entry.\n * TDB_MODIFY: Don't create a new entry\n * * @return 0 on success, -1 on error with error code set. * * @see tdb_error() * @see tdb_errorstr() */ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); /** * @brief Store an element in the database. * * This replaces any existing element with the same key. * * @param[in] tdb The tdb to store the entry. * * @param[in] key The key to use to store the entry. * * @param[in] dbufs A vector of memory chunks to write * * @param[in] num_dbufs Length of the dbufs vector * * @param[in] flag The flags to store the key:\n\n * TDB_INSERT: Don't overwrite an existing entry.\n * TDB_MODIFY: Don't create a new entry\n * * @return 0 on success, -1 on error with error code set. * * @see tdb_error() * @see tdb_errorstr() */ int tdb_storev(struct tdb_context *tdb, TDB_DATA key, const TDB_DATA *dbufs, int num_dbufs, int flag); /** * @brief Append data to an entry. * * If the entry doesn't exist, it will create a new one. * * @param[in] tdb The database to use. * * @param[in] key The key to append the data. * * @param[in] new_dbuf The data to append to the key. * * @return 0 on success, -1 on error with error code set. * * @see tdb_error() * @see tdb_errorstr() */ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); /** * @brief Close a database. * * @param[in] tdb The database to close. The context will be free'd. * * @return 0 for success, -1 on error. * * @note Don't call tdb_error() after this function cause the tdb context will * be freed on error. */ int tdb_close(struct tdb_context *tdb); /** * @brief Find the first entry in the database and return its key. * * The caller must free the returned data. * * @param[in] tdb The database to use. * * @return The first entry of the database, an empty TDB_DATA entry * if the database is empty. */ TDB_DATA tdb_firstkey(struct tdb_context *tdb); /** * @brief Find the next entry in the database, returning its key. * * The caller must free the returned data. * * @param[in] tdb The database to use. * * @param[in] key The key from which you want the next key. * * @return The next entry of the current key, an empty TDB_DATA * entry if there is no entry. */ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); /** * @brief Traverse the entire database. * * While traversing the function fn(tdb, key, data, state) is called on each * element. If fn is NULL then it is not called. A non-zero return value from * fn() indicates that the traversal should stop. Traversal callbacks may not * start transactions. * * @warning The data buffer given to the callback fn does NOT meet the alignment * restrictions malloc gives you. * * @param[in] tdb The database to traverse. * * @param[in] fn The function to call on each entry. * * @param[in] private_data The private data which should be passed to the * traversing function. * * @return The record count traversed, -1 on error. */ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); /** * @brief Traverse the entire database. * * While traversing the database the function fn(tdb, key, data, state) is * called on each element, but marking the database read only during the * traversal, so any write operations will fail. This allows tdb to use read * locks, which increases the parallelism possible during the traversal. * * @param[in] tdb The database to traverse. * * @param[in] fn The function to call on each entry. * * @param[in] private_data The private data which should be passed to the * traversing function. * * @return The record count traversed, -1 on error. */ int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); /** * @brief Traverse a single hash chain * * Traverse a single hash chain under a single lock operation. No * database modification is possible in the callback. * * This exists for background cleanup of databases. In normal * operations, traversing a complete database can be much too * expensive. Databases can have many chains, which will all have to * be looked at before tdb_traverse finishes. Also tdb_traverse does a * lot of fcntl activity to protect against concurrent record deletes. * * With this you can walk a fraction of the whole tdb, collect the * entries you want to prune, leave the traverse, and then modify or * delete the records in a subsequent step. * * To walk the entire database, call this function tdb_hash_size() * times, with 0<=chain 2015-04-25 tdbbackup 8 Samba System Administration tools 3.6 tdbbackup tool for backing up and for validating the integrity of samba .tdb files tdbbackup -s suffix -v -h -n hashsize -l DESCRIPTION This tool is part of the samba 1 suite. tdbbackup is a tool that may be used to backup samba .tdb files. This tool may also be used to verify the integrity of the .tdb files prior to samba startup or during normal operation. If it finds file damage and it finds a prior backup the backup file will be restored. OPTIONS -h Get help information. -s suffix The -s option allows the administrator to specify a file backup extension. This way it is possible to keep a history of tdb backup files by using a new suffix for each backup. -v The -v will check the database for damages (corrupt data) which if detected causes the backup to be restored. -n hashsize The -n option sets the hash size for the new backup tdb. -l This options disables any locking, by passing TDB_NOLOCK to tdb_open_ex(). Only use this for database files which are not used by any other process! And also only if it is otherwise not possible to open the database, e.g. databases which were created with mutex locking. COMMANDS GENERAL INFORMATION The tdbbackup utility can safely be run at any time. It was designed so that it can be used at any time to validate the integrity of tdb files, even during Samba operation. Typical usage for the command will be: tdbbackup [-s suffix] *.tdb Before restarting samba the following command may be run to validate .tdb files: tdbbackup -v [-s suffix] *.tdb Samba .tdb files are stored in various locations, be sure to run backup all .tdb file on the system. Important files includes: secrets.tdb - usual location is in the /usr/local/samba/private directory, or on some systems in /etc/samba. passdb.tdb - usual location is in the /usr/local/samba/private directory, or on some systems in /etc/samba. *.tdb located in the /usr/local/samba/var directory or on some systems in the /var/cache or /var/lib/samba directories. VERSION This man page is correct for version 3 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. The tdbbackup man page was written by John H Terpstra. ldb-2.0.8/lib/tdb/man/tdbdump.8.xml0000660000000000000000000000470412520121120016626 0ustar rootroot00000000000000 2015-04-25 tdbdump 8 Samba System Administration tools 3.6 tdbdump tool for printing the contents of a TDB file tdbdump -k keyname -e -h filename DESCRIPTION This tool is part of the samba 1 suite. tdbdump is a very simple utility that 'dumps' the contents of a TDB (Trivial DataBase) file to standard output in a human-readable format. This tool can be used when debugging problems with TDB files. It is intended for those who are somewhat familiar with Samba internals. OPTIONS -h Get help information. -k keyname The -k option restricts dumping to a single key, if found. -e The -e tries to dump out from a corrupt database. Naturally, such a dump is unreliable, at best. VERSION This man page is correct for version 3 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. The tdbdump man page was written by Jelmer Vernooij. ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml0000660000000000000000000000367312520121120017350 0ustar rootroot00000000000000 2015-04-25 tdbrestore 8 Samba System Administration tools 3.6 tdbrestore tool for creating a TDB file out of a tdbdump output tdbrestore tdbfilename DESCRIPTION This tool is part of the samba 1 suite. tdbrestore is a very simple utility that 'restores' the contents of dump file into TDB (Trivial DataBase) file. The dump file is obtained from the tdbdump command. This tool wait on the standard input for the content of the dump and will write the tdb in the tdbfilename parameter. This tool can be used for unpacking the content of tdb as backup mean. VERSION This man page is correct for version 3 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. This tool was initially written by Volker Lendecke based on an idea by Simon McVittie. The tdbrestore man page was written by Matthieu Patou. ldb-2.0.8/lib/tdb/man/tdbtool.8.xml0000660000000000000000000001466713100601766016665 0ustar rootroot00000000000000 2015-04-25 tdbtool 8 Samba System Administration tools 4.0 tdbtool manipulate the contents TDB files tdbtool tdbtool -l TDBFILE COMMANDS DESCRIPTION This tool is part of the samba 1 suite. tdbtool a tool for displaying and altering the contents of Samba TDB (Trivial DataBase) files. Each of the commands listed below can be entered interactively or provided on the command line. OPTIONS -l This options disables any locking, by passing TDB_NOLOCK to tdb_open_ex(). Only use this for database files which are not used by any other process! And also only if it is otherwise not possible to open the database, e.g. databases which were created with mutex locking. COMMANDS TDBFILE Create a new database named TDBFILE. TDBFILE Open an existing database named TDBFILE. Erase the current database. Dump the current database as strings. Dump the current database as connection records. Dump the current database keys as strings. Dump the current database keys as hex values. Print summary information about the current database. KEY DATA Insert a record into the current database. KEY TDBFILE Move a record from the current database into TDBFILE. KEY DATA Store (replace) a record in the current database. KEY DATA Store (replace) a record in the current database where key and data are in hex format. KEY Show a record by key. KEY Delete a record by key. Print the current database hash table and free list. Print the current database and free list. COMMAND Execute the given system command. Print the first record in the current database. Print the next record in the current database. Check the integrity of the current database. Repack a database using a temporary file to remove fragmentation. Exit tdbtool. CAVEATS The contents of the Samba TDB files are private to the implementation and should not be altered with tdbtool. VERSION This man page is correct for version 3.6 of the Samba suite. AUTHOR The original Samba software and related utilities were created by Andrew Tridgell. Samba is now developed by the Samba Team as an Open Source project similar to the way the Linux kernel is developed. ldb-2.0.8/lib/tdb/pytdb.c0000660000000000000000000005153213573675413015047 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python interface to tdb. Copyright (C) 2004-2006 Tim Potter Copyright (C) 2007-2008 Jelmer Vernooij ** NOTE! The following LGPL license applies to the tdb ** 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 . */ #include #include "replace.h" #include "system/filesys.h" /* Include tdb headers */ #include #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #define PyInt_Check PyLong_Check #define PyInt_AsLong PyLong_AsLong #define Py_TPFLAGS_HAVE_ITER 0 #endif /* discard signature of 'func' in favour of 'target_sig' */ #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func typedef struct { PyObject_HEAD TDB_CONTEXT *ctx; bool closed; } PyTdbObject; static PyTypeObject PyTdb; static void PyErr_SetTDBError(TDB_CONTEXT *tdb) { PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue("(i,s)", tdb_error(tdb), tdb_errorstr(tdb))); } static TDB_DATA PyBytes_AsTDB_DATA(PyObject *data) { TDB_DATA ret; ret.dptr = (unsigned char *)PyBytes_AsString(data); ret.dsize = PyBytes_Size(data); return ret; } static PyObject *PyBytes_FromTDB_DATA(TDB_DATA data) { if (data.dptr == NULL && data.dsize == 0) { Py_RETURN_NONE; } else { PyObject *ret = PyBytes_FromStringAndSize((const char *)data.dptr, data.dsize); free(data.dptr); return ret; } } #define PyErr_TDB_ERROR_IS_ERR_RAISE(ret, tdb) \ if (ret != 0) { \ PyErr_SetTDBError(tdb); \ return NULL; \ } #define PyErr_TDB_RAISE_IF_CLOSED(self) \ if (self->closed) { \ PyErr_SetObject(PyExc_RuntimeError, \ Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ return NULL; \ } #define PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self) \ if (self->closed) { \ PyErr_SetObject(PyExc_RuntimeError, \ Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ return -1; \ } static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) { char *name = NULL; int hash_size = 0, tdb_flags = TDB_DEFAULT, flags = O_RDWR, mode = 0600; TDB_CONTEXT *ctx; PyTdbObject *ret; const char *_kwnames[] = { "name", "hash_size", "tdb_flags", "flags", "mode", NULL }; char **kwnames = discard_const_p(char *, _kwnames); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|siiii", kwnames, &name, &hash_size, &tdb_flags, &flags, &mode)) return NULL; if (name == NULL) { tdb_flags |= TDB_INTERNAL; } ctx = tdb_open(name, hash_size, tdb_flags, flags, mode); if (ctx == NULL) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } ret = PyObject_New(PyTdbObject, &PyTdb); if (!ret) { tdb_close(ctx); return NULL; } ret->ctx = ctx; ret->closed = false; return (PyObject *)ret; } static PyObject *obj_transaction_cancel(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_cancel(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_transaction_commit(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_commit(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_transaction_prepare_commit(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_prepare_commit(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_transaction_start(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_transaction_start(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_reopen(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_reopen(self->ctx); if (ret != 0) { self->closed = true; PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue("(i,s)", TDB_ERR_IO, "Failed to reopen database")); return NULL; } Py_RETURN_NONE; } static PyObject *obj_lockall(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_lockall(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_unlockall(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_unlockall(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_lockall_read(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_lockall_read(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_unlockall_read(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret = tdb_unlockall_read(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_close(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; if (self->closed) Py_RETURN_NONE; ret = tdb_close(self->ctx); self->closed = true; if (ret != 0) { PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue("(i,s)", TDB_ERR_IO, "Failed to close database")); return NULL; } Py_RETURN_NONE; } static PyObject *obj_get(PyTdbObject *self, PyObject *args) { TDB_DATA key; PyObject *py_key; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; return PyBytes_FromTDB_DATA(tdb_fetch(self->ctx, key)); } static PyObject *obj_append(PyTdbObject *self, PyObject *args) { TDB_DATA key, data; PyObject *py_key, *py_data; int ret; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; data = PyBytes_AsTDB_DATA(py_data); if (!data.dptr) return NULL; ret = tdb_append(self->ctx, key, data); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_firstkey(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyBytes_FromTDB_DATA(tdb_firstkey(self->ctx)); } static PyObject *obj_nextkey(PyTdbObject *self, PyObject *args) { TDB_DATA key; PyObject *py_key; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; return PyBytes_FromTDB_DATA(tdb_nextkey(self->ctx, key)); } static PyObject *obj_delete(PyTdbObject *self, PyObject *args) { TDB_DATA key; PyObject *py_key; int ret; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; ret = tdb_delete(self->ctx, key); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static int obj_contains(PyTdbObject *self, PyObject *py_key) { TDB_DATA key; int ret; PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) { PyErr_BadArgument(); return -1; } ret = tdb_exists(self->ctx, key); if (ret) return 1; return 0; } #if PY_MAJOR_VERSION < 3 static PyObject *obj_has_key(PyTdbObject *self, PyObject *args) { int ret; PyObject *py_key; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; ret = obj_contains(self, py_key); if (ret == -1) return NULL; if (ret) Py_RETURN_TRUE; Py_RETURN_FALSE; } #endif static PyObject *obj_store(PyTdbObject *self, PyObject *args) { TDB_DATA key, value; int ret; int flag = TDB_REPLACE; PyObject *py_key, *py_value; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "OO|i", &py_key, &py_value, &flag)) return NULL; key = PyBytes_AsTDB_DATA(py_key); if (!key.dptr) return NULL; value = PyBytes_AsTDB_DATA(py_value); if (!value.dptr) return NULL; ret = tdb_store(self->ctx, key, value, flag); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_add_flags(PyTdbObject *self, PyObject *args) { unsigned flags; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "I", &flags)) return NULL; tdb_add_flags(self->ctx, flags); Py_RETURN_NONE; } static PyObject *obj_remove_flags(PyTdbObject *self, PyObject *args) { unsigned flags; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "I", &flags)) return NULL; tdb_remove_flags(self->ctx, flags); Py_RETURN_NONE; } typedef struct { PyObject_HEAD TDB_DATA current; PyTdbObject *iteratee; } PyTdbIteratorObject; static PyObject *tdb_iter_next(PyTdbIteratorObject *self) { TDB_DATA current; PyObject *ret; if (self->current.dptr == NULL && self->current.dsize == 0) return NULL; current = self->current; self->current = tdb_nextkey(self->iteratee->ctx, self->current); ret = PyBytes_FromTDB_DATA(current); return ret; } static void tdb_iter_dealloc(PyTdbIteratorObject *self) { Py_DECREF(self->iteratee); PyObject_Del(self); } PyTypeObject PyTdbIterator = { .tp_name = "Iterator", .tp_basicsize = sizeof(PyTdbIteratorObject), .tp_iternext = (iternextfunc)tdb_iter_next, .tp_dealloc = (destructor)tdb_iter_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_iter = PyObject_SelfIter, }; static PyObject *tdb_object_iter(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyTdbIteratorObject *ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = PyObject_New(PyTdbIteratorObject, &PyTdbIterator); if (!ret) return NULL; ret->current = tdb_firstkey(self->ctx); ret->iteratee = self; Py_INCREF(self); return (PyObject *)ret; } static PyObject *obj_clear(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_wipe_all(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_repack(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_repack(self->ctx); PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); Py_RETURN_NONE; } static PyObject *obj_enable_seqnum(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_TDB_RAISE_IF_CLOSED(self); tdb_enable_seqnum(self->ctx); Py_RETURN_NONE; } static PyObject *obj_increment_seqnum_nonblock(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_TDB_RAISE_IF_CLOSED(self); tdb_increment_seqnum_nonblock(self->ctx); Py_RETURN_NONE; } static PyMethodDef tdb_object_methods[] = { { "transaction_cancel", (PyCFunction)obj_transaction_cancel, METH_NOARGS, "S.transaction_cancel() -> None\n" "Cancel the currently active transaction." }, { "transaction_commit", (PyCFunction)obj_transaction_commit, METH_NOARGS, "S.transaction_commit() -> None\n" "Commit the currently active transaction." }, { "transaction_prepare_commit", (PyCFunction)obj_transaction_prepare_commit, METH_NOARGS, "S.transaction_prepare_commit() -> None\n" "Prepare to commit the currently active transaction" }, { "transaction_start", (PyCFunction)obj_transaction_start, METH_NOARGS, "S.transaction_start() -> None\n" "Start a new transaction." }, { "reopen", (PyCFunction)obj_reopen, METH_NOARGS, "Reopen this file." }, { "lock_all", (PyCFunction)obj_lockall, METH_NOARGS, NULL }, { "unlock_all", (PyCFunction)obj_unlockall, METH_NOARGS, NULL }, { "read_lock_all", (PyCFunction)obj_lockall_read, METH_NOARGS, NULL }, { "read_unlock_all", (PyCFunction)obj_unlockall_read, METH_NOARGS, NULL }, { "close", (PyCFunction)obj_close, METH_NOARGS, NULL }, { "get", (PyCFunction)obj_get, METH_VARARGS, "S.get(key) -> value\n" "Fetch a value." }, { "append", (PyCFunction)obj_append, METH_VARARGS, "S.append(key, value) -> None\n" "Append data to an existing key." }, { "firstkey", (PyCFunction)obj_firstkey, METH_NOARGS, "S.firstkey() -> data\n" "Return the first key in this database." }, { "nextkey", (PyCFunction)obj_nextkey, METH_VARARGS, "S.nextkey(key) -> data\n" "Return the next key in this database." }, { "delete", (PyCFunction)obj_delete, METH_VARARGS, "S.delete(key) -> None\n" "Delete an entry." }, #if PY_MAJOR_VERSION < 3 { "has_key", (PyCFunction)obj_has_key, METH_VARARGS, "S.has_key(key) -> None\n" "Check whether key exists in this database." }, #endif { "store", (PyCFunction)obj_store, METH_VARARGS, "S.store(key, data, flag=REPLACE) -> None" "Store data." }, { "add_flags", (PyCFunction)obj_add_flags, METH_VARARGS, "S.add_flags(flags) -> None" }, { "remove_flags", (PyCFunction)obj_remove_flags, METH_VARARGS, "S.remove_flags(flags) -> None" }, #if PY_MAJOR_VERSION >= 3 { "keys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, #else { "iterkeys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, #endif { "clear", (PyCFunction)obj_clear, METH_NOARGS, "S.clear() -> None\n" "Wipe the entire database." }, { "repack", (PyCFunction)obj_repack, METH_NOARGS, "S.repack() -> None\n" "Repack the entire database." }, { "enable_seqnum", (PyCFunction)obj_enable_seqnum, METH_NOARGS, "S.enable_seqnum() -> None" }, { "increment_seqnum_nonblock", (PyCFunction)obj_increment_seqnum_nonblock, METH_NOARGS, "S.increment_seqnum_nonblock() -> None" }, { NULL } }; static PyObject *obj_get_hash_size(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_hash_size(self->ctx)); } static int obj_set_max_dead(PyTdbObject *self, PyObject *max_dead, void *closure) { PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); if (!PyInt_Check(max_dead)) return -1; tdb_set_max_dead(self->ctx, PyInt_AsLong(max_dead)); return 0; } static PyObject *obj_get_map_size(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_map_size(self->ctx)); } static PyObject *obj_get_freelist_size(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_freelist_size(self->ctx)); } static PyObject *obj_get_flags(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_get_flags(self->ctx)); } static PyObject *obj_get_filename(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyBytes_FromString(tdb_name(self->ctx)); } static PyObject *obj_get_seqnum(PyTdbObject *self, void *closure) { PyErr_TDB_RAISE_IF_CLOSED(self); return PyInt_FromLong(tdb_get_seqnum(self->ctx)); } static PyObject *obj_get_text(PyTdbObject *self, void *closure) { PyObject *mod, *cls, *inst; mod = PyImport_ImportModule("_tdb_text"); if (mod == NULL) return NULL; cls = PyObject_GetAttrString(mod, "TdbTextWrapper"); if (cls == NULL) { Py_DECREF(mod); return NULL; } inst = PyObject_CallFunction(cls, discard_const_p(char, "O"), self); Py_DECREF(mod); Py_DECREF(cls); return inst; } static PyGetSetDef tdb_object_getsetters[] = { { .name = discard_const_p(char, "hash_size"), .get = (getter)obj_get_hash_size, }, { .name = discard_const_p(char, "map_size"), .get = (getter)obj_get_map_size, }, { .name = discard_const_p(char, "freelist_size"), .get = (getter)obj_get_freelist_size, }, { .name = discard_const_p(char, "flags"), .get = (getter)obj_get_flags, }, { .name = discard_const_p(char, "max_dead"), .set = (setter)obj_set_max_dead, }, { .name = discard_const_p(char, "filename"), .get = (getter)obj_get_filename, .doc = discard_const_p(char, "The filename of this TDB file."), }, { .name = discard_const_p(char, "seqnum"), .get = (getter)obj_get_seqnum, }, { .name = discard_const_p(char, "text"), .get = (getter)obj_get_text, }, { .name = NULL } }; static PyObject *tdb_object_repr(PyTdbObject *self) { PyErr_TDB_RAISE_IF_CLOSED(self); if (tdb_get_flags(self->ctx) & TDB_INTERNAL) { return PyUnicode_FromString("Tdb()"); } else { return PyUnicode_FromFormat("Tdb('%s')", tdb_name(self->ctx)); } } static void tdb_object_dealloc(PyTdbObject *self) { if (!self->closed) tdb_close(self->ctx); Py_TYPE(self)->tp_free(self); } static PyObject *obj_getitem(PyTdbObject *self, PyObject *key) { TDB_DATA tkey, val; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyBytes_Check(key)) { PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); return NULL; } tkey.dptr = (unsigned char *)PyBytes_AsString(key); tkey.dsize = PyBytes_Size(key); val = tdb_fetch(self->ctx, tkey); if (val.dptr == NULL) { /* * if the key doesn't exist raise KeyError(key) to be * consistent with python dict */ PyErr_SetObject(PyExc_KeyError, key); return NULL; } else { return PyBytes_FromTDB_DATA(val); } } static int obj_setitem(PyTdbObject *self, PyObject *key, PyObject *value) { TDB_DATA tkey, tval; int ret; PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); if (!PyBytes_Check(key)) { PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); return -1; } tkey = PyBytes_AsTDB_DATA(key); if (value == NULL) { ret = tdb_delete(self->ctx, tkey); } else { if (!PyBytes_Check(value)) { PyErr_SetString(PyExc_TypeError, "Expected string as value"); return -1; } tval = PyBytes_AsTDB_DATA(value); ret = tdb_store(self->ctx, tkey, tval, TDB_REPLACE); } if (ret != 0) { PyErr_SetTDBError(self->ctx); return -1; } return ret; } static PyMappingMethods tdb_object_mapping = { .mp_subscript = (binaryfunc)obj_getitem, .mp_ass_subscript = (objobjargproc)obj_setitem, }; static PySequenceMethods tdb_object_seq = { .sq_contains = (objobjproc)obj_contains, }; static PyTypeObject PyTdb = { .tp_name = "tdb.Tdb", .tp_basicsize = sizeof(PyTdbObject), .tp_methods = tdb_object_methods, .tp_getset = tdb_object_getsetters, .tp_new = py_tdb_open, .tp_doc = "A TDB file", .tp_repr = (reprfunc)tdb_object_repr, .tp_dealloc = (destructor)tdb_object_dealloc, .tp_as_mapping = &tdb_object_mapping, .tp_as_sequence = &tdb_object_seq, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, .tp_iter = PY_DISCARD_FUNC_SIG(getiterfunc,tdb_object_iter), }; static PyMethodDef tdb_methods[] = { { .ml_name = "open", .ml_meth = PY_DISCARD_FUNC_SIG(PyCFunction, py_tdb_open), .ml_flags = METH_VARARGS|METH_KEYWORDS, .ml_doc = "open(name, hash_size=0, tdb_flags=TDB_DEFAULT, " "flags=O_RDWR, mode=0600)\nOpen a TDB file." }, { .ml_name = NULL } }; #define MODULE_DOC "simple key-value database that supports multiple writers." #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, .m_name = "tdb", .m_doc = MODULE_DOC, .m_size = -1, .m_methods = tdb_methods, }; #endif PyObject* module_init(void); PyObject* module_init(void) { PyObject *m; if (PyType_Ready(&PyTdb) < 0) return NULL; if (PyType_Ready(&PyTdbIterator) < 0) return NULL; #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); #else m = Py_InitModule3("tdb", tdb_methods, MODULE_DOC); #endif if (m == NULL) return NULL; PyModule_AddIntConstant(m, "REPLACE", TDB_REPLACE); PyModule_AddIntConstant(m, "INSERT", TDB_INSERT); PyModule_AddIntConstant(m, "MODIFY", TDB_MODIFY); PyModule_AddIntConstant(m, "DEFAULT", TDB_DEFAULT); PyModule_AddIntConstant(m, "CLEAR_IF_FIRST", TDB_CLEAR_IF_FIRST); PyModule_AddIntConstant(m, "INTERNAL", TDB_INTERNAL); PyModule_AddIntConstant(m, "NOLOCK", TDB_NOLOCK); PyModule_AddIntConstant(m, "NOMMAP", TDB_NOMMAP); PyModule_AddIntConstant(m, "CONVERT", TDB_CONVERT); PyModule_AddIntConstant(m, "BIGENDIAN", TDB_BIGENDIAN); PyModule_AddIntConstant(m, "NOSYNC", TDB_NOSYNC); PyModule_AddIntConstant(m, "SEQNUM", TDB_SEQNUM); PyModule_AddIntConstant(m, "VOLATILE", TDB_VOLATILE); PyModule_AddIntConstant(m, "ALLOW_NESTING", TDB_ALLOW_NESTING); PyModule_AddIntConstant(m, "DISALLOW_NESTING", TDB_DISALLOW_NESTING); PyModule_AddIntConstant(m, "INCOMPATIBLE_HASH", TDB_INCOMPATIBLE_HASH); PyModule_AddStringConstant(m, "__docformat__", "restructuredText"); PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); Py_INCREF(&PyTdb); PyModule_AddObject(m, "Tdb", (PyObject *)&PyTdb); Py_INCREF(&PyTdbIterator); return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit_tdb(void); PyMODINIT_FUNC PyInit_tdb(void) { return module_init(); } #else void inittdb(void); void inittdb(void) { module_init(); } #endif ldb-2.0.8/lib/tdb/python/tdbdump.py0000660000000000000000000000051413573675413017105 0ustar rootroot00000000000000#!/usr/bin/env python3 # Trivial reimplementation of tdbdump in Python from __future__ import print_function import tdb, sys if len(sys.argv) < 2: print("Usage: tdbdump.py ") 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)) ldb-2.0.8/lib/tdb/python/tests/simple.py0000660000000000000000000002173313573675413020107 0ustar rootroot00000000000000#!/usr/bin/env python3 # Some simple tests for the Python bindings for TDB # Note that this tests the interface of the Python bindings # It does not test tdb itself. # # Copyright (C) 2007-2008 Jelmer Vernooij # Published under the GNU LGPLv3 or later import sys import os import tempfile from unittest import TestCase import tdb class OpenTdbTests(TestCase): def test_nonexistent_read(self): self.assertRaises(IOError, tdb.Tdb, "/some/nonexistent/file", 0, tdb.DEFAULT, os.O_RDWR) class CloseTdbTests(TestCase): def test_double_close(self): self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) # ensure that double close does not crash python self.tdb.close() self.tdb.close() # Check that further operations do not crash python self.assertRaises(RuntimeError, lambda: self.tdb.transaction_start()) self.assertRaises(RuntimeError, lambda: self.tdb["bar"]) class InternalTdbTests(TestCase): def test_repr(self): self.tdb = tdb.Tdb() # repr used to crash on internal db self.assertEqual(repr(self.tdb), "Tdb()") class CommonTdbTests(TestCase): """Tests common to both the text & bytes interfaces""" use_text = False def setUp(self): super(CommonTdbTests, self).setUp() self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) if self.use_text: self.tdb = self.tdb.text def test_lockall(self): self.tdb.lock_all() def test_max_dead(self): self.tdb.max_dead = 20 def test_unlockall(self): self.tdb.lock_all() self.tdb.unlock_all() def test_lockall_read(self): self.tdb.read_lock_all() self.tdb.read_unlock_all() def test_reopen(self): self.tdb.reopen() def test_hash_size(self): self.tdb.hash_size def test_map_size(self): self.tdb.map_size def test_freelist_size(self): self.tdb.freelist_size def test_name(self): self.tdb.filename def test_add_flags(self): self.tdb.add_flags(tdb.NOMMAP) self.tdb.remove_flags(tdb.NOMMAP) class TextCommonTdbTests(CommonTdbTests): use_text = True class SimpleTdbTests(TestCase): def setUp(self): super(SimpleTdbTests, self).setUp() self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) def test_repr(self): self.assertTrue(repr(self.tdb).startswith("Tdb('")) def test_store(self): self.tdb.store(b"bar", b"bla") self.assertEqual(b"bla", self.tdb.get(b"bar")) def test_getitem(self): self.tdb[b"bar"] = b"foo" self.tdb.reopen() self.assertEqual(b"foo", self.tdb[b"bar"]) def test_delete(self): self.tdb[b"bar"] = b"foo" del self.tdb[b"bar"] self.assertRaises(KeyError, lambda: self.tdb[b"bar"]) def test_contains(self): self.tdb[b"bla"] = b"bloe" self.assertTrue(b"bla" in self.tdb) self.assertFalse(b"qwertyuiop" in self.tdb) if sys.version_info < (3, 0): self.assertTrue(self.tdb.has_key(b"bla")) self.assertFalse(self.tdb.has_key(b"qwertyuiop")) def test_keyerror(self): self.assertRaises(KeyError, lambda: self.tdb[b"bla"]) def test_iterator(self): self.tdb[b"bla"] = b"1" self.tdb[b"brainslug"] = b"2" l = list(self.tdb) l.sort() self.assertEqual([b"bla", b"brainslug"], l) def test_transaction_cancel(self): self.tdb[b"bloe"] = b"2" self.tdb.transaction_start() self.tdb[b"bloe"] = b"1" self.tdb.transaction_cancel() self.assertEqual(b"2", self.tdb[b"bloe"]) def test_transaction_commit(self): self.tdb[b"bloe"] = b"2" self.tdb.transaction_start() self.tdb[b"bloe"] = b"1" self.tdb.transaction_commit() self.assertEqual(b"1", self.tdb[b"bloe"]) def test_transaction_prepare_commit(self): self.tdb[b"bloe"] = b"2" self.tdb.transaction_start() self.tdb[b"bloe"] = b"1" self.tdb.transaction_prepare_commit() self.tdb.transaction_commit() self.assertEqual(b"1", self.tdb[b"bloe"]) def test_iterkeys(self): self.tdb[b"bloe"] = b"2" self.tdb[b"bla"] = b"25" if sys.version_info >= (3, 0): i = self.tdb.keys() else: i = self.tdb.iterkeys() self.assertEqual(set([b"bloe", b"bla"]), set([next(i), next(i)])) def test_clear(self): self.tdb[b"bloe"] = b"2" self.tdb[b"bla"] = b"25" self.assertEqual(2, len(list(self.tdb))) self.tdb.clear() self.assertEqual(0, len(list(self.tdb))) def test_repack(self): self.tdb[b"foo"] = b"abc" self.tdb[b"bar"] = b"def" del self.tdb[b"foo"] self.tdb.repack() def test_seqnum(self): self.tdb.enable_seqnum() seq1 = self.tdb.seqnum self.tdb.increment_seqnum_nonblock() seq2 = self.tdb.seqnum self.assertEqual(seq2-seq1, 1) def test_len(self): self.assertEqual(0, len(list(self.tdb))) self.tdb[b"entry"] = b"value" self.assertEqual(1, len(list(self.tdb))) class TdbTextTests(TestCase): def setUp(self): super(TdbTextTests, self).setUp() self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) def test_repr(self): self.assertTrue(repr(self.tdb).startswith("Tdb('")) def test_store(self): self.tdb.text.store("bar", "bla") self.assertEqual("bla", self.tdb.text.get("bar")) def test_getitem(self): self.tdb.text["bar"] = "foo" self.tdb.reopen() self.assertEqual("foo", self.tdb.text["bar"]) def test_delete(self): self.tdb.text["bar"] = "foo" del self.tdb.text["bar"] self.assertRaises(KeyError, lambda: self.tdb.text["bar"]) def test_contains(self): self.tdb.text["bla"] = "bloe" self.assertTrue("bla" in self.tdb.text) self.assertFalse("qwertyuiop" in self.tdb.text) if sys.version_info < (3, 0): self.assertTrue(self.tdb.text.has_key("bla")) self.assertFalse(self.tdb.text.has_key("qwertyuiop")) def test_keyerror(self): self.assertRaises(KeyError, lambda: self.tdb.text["bla"]) def test_iterator(self): self.tdb.text["bla"] = "1" self.tdb.text["brainslug"] = "2" l = list(self.tdb.text) l.sort() self.assertEqual(["bla", "brainslug"], l) def test_transaction_cancel(self): self.tdb.text["bloe"] = "2" self.tdb.transaction_start() self.tdb.text["bloe"] = "1" self.tdb.transaction_cancel() self.assertEqual("2", self.tdb.text["bloe"]) def test_transaction_commit(self): self.tdb.text["bloe"] = "2" self.tdb.transaction_start() self.tdb.text["bloe"] = "1" self.tdb.transaction_commit() self.assertEqual("1", self.tdb.text["bloe"]) def test_transaction_prepare_commit(self): self.tdb.text["bloe"] = "2" self.tdb.transaction_start() self.tdb.text["bloe"] = "1" self.tdb.transaction_prepare_commit() self.tdb.transaction_commit() self.assertEqual("1", self.tdb.text["bloe"]) def test_iterkeys(self): self.tdb.text["bloe"] = "2" self.tdb.text["bla"] = "25" if sys.version_info >= (3, 0): i = self.tdb.text.keys() else: i = self.tdb.text.iterkeys() self.assertEqual(set(["bloe", "bla"]), set([next(i), next(i)])) def test_clear(self): self.tdb.text["bloe"] = "2" self.tdb.text["bla"] = "25" self.assertEqual(2, len(list(self.tdb))) self.tdb.clear() self.assertEqual(0, len(list(self.tdb))) def test_repack(self): self.tdb.text["foo"] = "abc" self.tdb.text["bar"] = "def" del self.tdb.text["foo"] self.tdb.repack() def test_len(self): self.assertEqual(0, len(list(self.tdb.text))) self.tdb.text["entry"] = "value" self.assertEqual(1, len(list(self.tdb.text))) def test_text_and_binary(self): text = u'\xfa\u0148\xef\xe7\xf8\xf0\xea' bytestr = text.encode('utf-8') self.tdb[b"entry"] = bytestr self.tdb.text[u"entry2"] = text self.assertEqual(self.tdb.text["entry"], text) self.assertEqual(self.tdb[b"entry2"], bytestr) assert self.tdb.text.raw == self.tdb class VersionTests(TestCase): def test_present(self): self.assertTrue(isinstance(tdb.__version__, str)) if __name__ == '__main__': import unittest unittest.TestProgram() ldb-2.0.8/lib/tdb/tdb.pc.in0000660000000000000000000000036012406075657015252 0ustar rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: tdb Description: A trivial database Version: @PACKAGE_VERSION@ Libs: @LIB_RPATH@ -L${libdir} -ltdb Cflags: -I${includedir} URL: http://tdb.samba.org/ ldb-2.0.8/lib/tdb/test/circular_chain.tdb0000660000000000000000000000042013573675413020167 0ustar rootroot00000000000000TDB file m& Ÿ}ö ùþ:ðÐérJ ™&ab °¿׌™&cd Е¬c™&ef ldb-2.0.8/lib/tdb/test/circular_freelist.tdb0000660000000000000000000000062013573675413020724 0ustar rootroot00000000000000TDB file m& Ÿ}ö ùþ:PpérJ ™&aa PTÁKfæþÙbb °¿׌™&cc Ð*^ÎfæþÙdd ð•¬c™&ee û)RfæþÙff 0kIð“™&gg ldb-2.0.8/lib/tdb/test/external-agent.c0000660000000000000000000001167412702766507017623 0ustar rootroot00000000000000#include "external-agent.h" #include "lock-tracking.h" #include "logging.h" #include #include #include #include #include #include #include #include #include "../common/tdb_private.h" #include "tap-interface.h" #include #include static struct tdb_context *tdb; static enum agent_return do_operation(enum operation op, const char *name) { TDB_DATA k; enum agent_return ret; TDB_DATA data; if (op != OPEN && op != OPEN_WITH_CLEAR_IF_FIRST && !tdb) { diag("external: No tdb open!"); return OTHER_FAILURE; } k.dptr = discard_const_p(uint8_t, name); k.dsize = strlen(name); locking_would_block = 0; switch (op) { case OPEN: if (tdb) { diag("Already have tdb %s open", tdb_name(tdb)); return OTHER_FAILURE; } tdb = tdb_open_ex(name, 0, TDB_DEFAULT, O_RDWR, 0, &taplogctx, NULL); if (!tdb) { if (!locking_would_block) diag("Opening tdb gave %s", strerror(errno)); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case OPEN_WITH_CLEAR_IF_FIRST: if (tdb) return OTHER_FAILURE; tdb = tdb_open_ex(name, 0, TDB_CLEAR_IF_FIRST, O_RDWR, 0, &taplogctx, NULL); ret = tdb ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_START: ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE; break; case FETCH: data = tdb_fetch(tdb, k); if (data.dptr == NULL) { if (tdb_error(tdb) == TDB_ERR_NOEXIST) ret = FAILED; else ret = OTHER_FAILURE; } else if (data.dsize != k.dsize || memcmp(data.dptr, k.dptr, k.dsize) != 0) { ret = OTHER_FAILURE; } else { ret = SUCCESS; } free(data.dptr); break; case STORE: ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_COMMIT: ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE; break; case CHECK: ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE; break; case NEEDS_RECOVERY: ret = tdb_needs_recovery(tdb) ? SUCCESS : FAILED; break; case CLOSE: ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE; tdb = NULL; break; case PING: ret = SUCCESS; break; case UNMAP: ret = tdb_munmap(tdb) == 0 ? SUCCESS : OTHER_FAILURE; if (ret == SUCCESS) { tdb->flags |= TDB_NOMMAP; } break; default: ret = OTHER_FAILURE; } if (locking_would_block) ret = WOULD_HAVE_BLOCKED; return ret; } struct agent { int cmdfd, responsefd; pid_t pid; }; /* Do this before doing any tdb stuff. Return handle, or NULL. */ struct agent *prepare_external_agent(void) { int ret; int command[2], response[2]; char name[1+PATH_MAX]; struct agent *agent = malloc(sizeof(*agent)); if (pipe(command) != 0 || pipe(response) != 0) { fprintf(stderr, "pipe failed: %s\n", strerror(errno)); exit(1); } agent->pid = fork(); if (agent->pid < 0) { fprintf(stderr, "fork failed: %s\n", strerror(errno)); exit(1); } if (agent->pid != 0) { close(command[0]); close(response[1]); agent->cmdfd = command[1]; agent->responsefd = response[0]; return agent; } close(command[1]); close(response[0]); /* We want to fail, not block. */ nonblocking_locks = true; log_prefix = "external: "; while ((ret = read(command[0], name, sizeof(name))) > 0) { enum agent_return result; result = do_operation(name[0], name+1); if (write(response[1], &result, sizeof(result)) != sizeof(result)) abort(); } exit(0); } void shutdown_agent(struct agent *agent) { pid_t p; close(agent->cmdfd); close(agent->responsefd); p = waitpid(agent->pid, NULL, WNOHANG); if (p == 0) { kill(agent->pid, SIGKILL); } waitpid(agent->pid, NULL, 0); free(agent); } /* Ask the external agent to try to do an operation. */ enum agent_return external_agent_operation(struct agent *agent, enum operation op, const char *name) { enum agent_return res; unsigned int len; char *string; if (!name) name = ""; len = 1 + strlen(name) + 1; string = malloc(len); string[0] = op; strncpy(string+1, name, len - 1); string[len-1] = '\0'; if (write(agent->cmdfd, string, len) != len || read(agent->responsefd, &res, sizeof(res)) != sizeof(res)) res = AGENT_DIED; free(string); return res; } const char *agent_return_name(enum agent_return ret) { return ret == SUCCESS ? "SUCCESS" : ret == WOULD_HAVE_BLOCKED ? "WOULD_HAVE_BLOCKED" : ret == AGENT_DIED ? "AGENT_DIED" : ret == FAILED ? "FAILED" : ret == OTHER_FAILURE ? "OTHER_FAILURE" : "**INVALID**"; } const char *operation_name(enum operation op) { switch (op) { case OPEN: return "OPEN"; case OPEN_WITH_CLEAR_IF_FIRST: return "OPEN_WITH_CLEAR_IF_FIRST"; case TRANSACTION_START: return "TRANSACTION_START"; case FETCH: return "FETCH"; case STORE: return "STORE"; case TRANSACTION_COMMIT: return "TRANSACTION_COMMIT"; case CHECK: return "CHECK"; case NEEDS_RECOVERY: return "NEEDS_RECOVERY"; case CLOSE: return "CLOSE"; case PING: return "PING"; case UNMAP: return "UNMAP"; } return "**INVALID**"; } ldb-2.0.8/lib/tdb/test/external-agent.h0000660000000000000000000000204712406075657017622 0ustar rootroot00000000000000#ifndef TDB_TEST_EXTERNAL_AGENT_H #define TDB_TEST_EXTERNAL_AGENT_H /* For locking tests, we need a different process to try things at * various times. */ enum operation { OPEN, OPEN_WITH_CLEAR_IF_FIRST, TRANSACTION_START, FETCH, STORE, TRANSACTION_COMMIT, CHECK, NEEDS_RECOVERY, CLOSE, PING, UNMAP, }; /* Do this before doing any tdb stuff. Return handle, or -1. */ struct agent *prepare_external_agent(void); void shutdown_agent(struct agent *agent); enum agent_return { SUCCESS, WOULD_HAVE_BLOCKED, AGENT_DIED, FAILED, /* For fetch, or NEEDS_RECOVERY */ OTHER_FAILURE, }; /* Ask the external agent to try to do an operation. * name == tdb name for OPEN/OPEN_WITH_CLEAR_IF_FIRST, * record name for FETCH/STORE (store stores name as data too) */ enum agent_return external_agent_operation(struct agent *handle, enum operation op, const char *name); /* Mapping enum -> string. */ const char *agent_return_name(enum agent_return ret); const char *operation_name(enum operation op); #endif /* TDB_TEST_EXTERNAL_AGENT_H */ ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb0000660000000000000000000000127012406075657020171 0ustar rootroot00000000000000TDB file &mƒ×¶”å<ƒldb-2.0.8/lib/tdb/test/jenkins-le-hash.tdb0000660000000000000000000000127012406075657020203 0ustar rootroot00000000000000TDB file m&ƒå”¶×D¹vldb-2.0.8/lib/tdb/test/lock-tracking.c0000660000000000000000000000666712406075657017443 0ustar rootroot00000000000000/* We save the locks so we can reaquire them. */ #include "../common/tdb_private.h" #include #include #include #include #include "tap-interface.h" #include "lock-tracking.h" struct testlock { struct testlock *next; unsigned int off; unsigned int len; int type; }; static struct testlock *testlocks; int locking_errors = 0; bool suppress_lockcheck = false; bool nonblocking_locks; int locking_would_block = 0; void (*unlock_callback)(int fd); int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ) { va_list ap; int ret, arg3; struct flock *fl; bool may_block = false; if (cmd != F_SETLK && cmd != F_SETLKW) { /* This may be totally bogus, but we don't know in general. */ va_start(ap, cmd); arg3 = va_arg(ap, int); va_end(ap); return fcntl(fd, cmd, arg3); } va_start(ap, cmd); fl = va_arg(ap, struct flock *); va_end(ap); if (cmd == F_SETLKW && nonblocking_locks) { cmd = F_SETLK; may_block = true; } ret = fcntl(fd, cmd, fl); /* Detect when we failed, but might have been OK if we waited. */ if (may_block && ret == -1 && (errno == EAGAIN || errno == EACCES)) { locking_would_block++; } if (fl->l_type == F_UNLCK) { struct testlock **l; struct testlock *old = NULL; for (l = &testlocks; *l; l = &(*l)->next) { if ((*l)->off == fl->l_start && (*l)->len == fl->l_len) { if (ret == 0) { old = *l; *l = (*l)->next; free(old); } break; } if (((*l)->off == fl->l_start) && ((*l)->len == 0) && (ret == 0)) { /* * Remove a piece from the start of the * allrecord_lock */ old = *l; (*l)->off += fl->l_len; break; } } if (!old && !suppress_lockcheck) { diag("Unknown unlock %u@%u - %i", (int)fl->l_len, (int)fl->l_start, ret); locking_errors++; } } else { struct testlock *new, *i; unsigned int fl_end = fl->l_start + fl->l_len; if (fl->l_len == 0) fl_end = (unsigned int)-1; /* Check for overlaps: we shouldn't do this. */ for (i = testlocks; i; i = i->next) { unsigned int i_end = i->off + i->len; if (i->len == 0) i_end = (unsigned int)-1; if (fl->l_start >= i->off && fl->l_start < i_end) break; if (fl_end >= i->off && fl_end < i_end) break; /* tdb_allrecord_lock does this, handle adjacent: */ if (fl->l_start == i_end && fl->l_type == i->type) { if (ret == 0) { i->len = fl->l_len ? i->len + fl->l_len : 0; } goto done; } } if (i) { /* Special case: upgrade of allrecord lock. */ if (i->type == F_RDLCK && fl->l_type == F_WRLCK && i->off == FREELIST_TOP && fl->l_start == FREELIST_TOP && i->len == 0 && fl->l_len == 0) { if (ret == 0) i->type = F_WRLCK; goto done; } if (!suppress_lockcheck) { diag("%s testlock %u@%u overlaps %u@%u", fl->l_type == F_WRLCK ? "write" : "read", (int)fl->l_len, (int)fl->l_start, i->len, (int)i->off); locking_errors++; } } if (ret == 0) { new = malloc(sizeof *new); new->off = fl->l_start; new->len = fl->l_len; new->type = fl->l_type; new->next = testlocks; testlocks = new; } } done: if (ret == 0 && fl->l_type == F_UNLCK && unlock_callback) unlock_callback(fd); return ret; } unsigned int forget_locking(void) { unsigned int num = 0; while (testlocks) { struct testlock *next = testlocks->next; free(testlocks); testlocks = next; num++; } return num; } ldb-2.0.8/lib/tdb/test/lock-tracking.h0000660000000000000000000000125112406075657017430 0ustar rootroot00000000000000#ifndef LOCK_TRACKING_H #define LOCK_TRACKING_H #include /* Set this if you want a callback after fnctl unlock. */ extern void (*unlock_callback)(int fd); /* Replacement fcntl. */ int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ); /* Discard locking info: returns number of locks outstanding. */ unsigned int forget_locking(void); /* Number of errors in locking. */ extern int locking_errors; /* Suppress lock checking. */ extern bool suppress_lockcheck; /* Make all locks non-blocking. */ extern bool nonblocking_locks; /* Number of times we failed a lock because we made it non-blocking. */ extern int locking_would_block; #endif /* LOCK_TRACKING_H */ ldb-2.0.8/lib/tdb/test/logging.c0000660000000000000000000000131412406075657016321 0ustar rootroot00000000000000#include "logging.h" #include "tap-interface.h" #include #include #include #include bool suppress_logging = false; const char *log_prefix = ""; /* Turn log messages into tap diag messages. */ static void taplog(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; char line[200]; if (suppress_logging) return; va_start(ap, fmt); vsprintf(line, fmt, ap); va_end(ap); /* Strip trailing \n: diag adds it. */ if (line[0] && line[strlen(line)-1] == '\n') diag("%s%.*s", log_prefix, (unsigned)strlen(line)-1, line); else diag("%s%s", log_prefix, line); } struct tdb_logging_context taplogctx = { taplog, NULL }; ldb-2.0.8/lib/tdb/test/logging.h0000660000000000000000000000041012406075657016322 0ustar rootroot00000000000000#ifndef TDB_TEST_LOGGING_H #define TDB_TEST_LOGGING_H #include "replace.h" #include "../include/tdb.h" #include extern bool suppress_logging; extern const char *log_prefix; extern struct tdb_logging_context taplogctx; #endif /* TDB_TEST_LOGGING_H */ ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb0000660000000000000000000000127012406075657017643 0ustar rootroot00000000000000TDB file &mƒldb-2.0.8/lib/tdb/test/old-nohash-le.tdb0000660000000000000000000000127012406075657017655 0ustar rootroot00000000000000TDB file m&ƒldb-2.0.8/lib/tdb/test/run-3G-file.c0000660000000000000000000000740413573675413016673 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static int tdb_expand_file_sparse(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; return -1; } if (tdb_ftruncate(tdb, size+addition) == -1) { char b = 0; ssize_t written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); if (written == 0) { /* try once more, potentially revealing errno */ written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); } if (written == 0) { /* again - give up, guessing errno */ errno = ENOSPC; } if (written != 1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", size+addition, strerror(errno))); return -1; } } return 0; } static const struct tdb_methods large_io_methods = { tdb_read, tdb_write, tdb_next_hash_chain, tdb_notrans_oob, tdb_expand_file_sparse }; static int test_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *_data) { TDB_DATA *expect = _data; ok1(key.dsize == strlen("hi")); ok1(memcmp(key.dptr, "hi", strlen("hi")) == 0); ok1(data.dsize == expect->dsize); ok1(memcmp(data.dptr, expect->dptr, data.dsize) == 0); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, orig_data, data; uint32_t hashval; tdb_off_t rec_ptr; struct tdb_record rec; int ret; plan_tests(24); tdb = tdb_open_ex("run-36-file.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); tdb->methods = &large_io_methods; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); orig_data.dsize = strlen("world"); orig_data.dptr = discard_const_p(uint8_t, "world"); /* Enlarge the file (internally multiplies by 2). */ ret = tdb_expand(tdb, 1500000000); #ifdef HAVE_INCOHERENT_MMAP /* This can fail due to mmap failure on 32 bit systems. */ if (ret == -1) { /* These should now fail. */ ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == -1); data = tdb_fetch(tdb, key); ok1(data.dptr == NULL); ok1(tdb_traverse(tdb, test_traverse, &orig_data) == -1); ok1(tdb_delete(tdb, key) == -1); ok1(tdb_traverse(tdb, test_traverse, NULL) == -1); /* Skip the rest... */ for (ret = 0; ret < 24 - 6; ret++) ok1(1); tdb_close(tdb); return exit_status(); } #endif ok1(ret == 0); /* Put an entry in, and check it. */ ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); /* That currently fills at the end, make sure that's true. */ hashval = tdb->hash_fn(&key); rec_ptr = tdb_find_lock_hash(tdb, key, hashval, F_RDLCK, &rec); ok1(rec_ptr); ok1(rec_ptr > 2U*1024*1024*1024); tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); /* Traverse must work. */ ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); /* Delete should work. */ ok1(tdb_delete(tdb, key) == 0); ok1(tdb_traverse(tdb, test_traverse, NULL) == 0); /* Transactions should work. */ ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); ok1(tdb_transaction_commit(tdb) == 0); ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c0000660000000000000000000001220512553526140023031 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "logging.h" static void do_allrecord_lock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_lockall(tdb); ok(ret == 0, "tdb_lockall should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); ret = tdb_traverse(tdb, NULL, NULL); ok(ret == -1, "do_allrecord_lock: traverse should fail"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); exit(0); } static void do_traverse(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_traverse(tdb, NULL, NULL); ok(ret == 1, "do_traverse: tdb_traverse should return 1 record"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); exit(0); } /* * Process 1: get the allrecord_lock on a tdb. * Process 2: start a traverse, this will stall waiting for the * first chainlock: That is taken by the allrecord_lock * Process 1: start a traverse: This will get EDEADLK in trying to * get the TRANSACTION_LOCK. It will deadlock for mutexes, * which don't have built-in deadlock detection. */ static int do_tests(const char *name, int tdb_flags) { struct tdb_context *tdb; int ret; pid_t traverse_child, allrecord_child; int traverse_down[2]; int traverse_up[2]; int allrecord_down[2]; int allrecord_up[2]; char c; ssize_t nread, nwritten; TDB_DATA key, data; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store should succeed"); ret = pipe(traverse_down); ok(ret == 0, "pipe should succeed"); ret = pipe(traverse_up); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_down); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_up); ok(ret == 0, "pipe should succeed"); allrecord_child = fork(); ok(allrecord_child != -1, "fork should succeed"); if (allrecord_child == 0) { tdb_close(tdb); close(traverse_up[0]); close(traverse_up[1]); close(traverse_down[0]); close(traverse_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); do_allrecord_lock(name, tdb_flags, allrecord_up[1], allrecord_down[0]); exit(0); } close(allrecord_up[1]); close(allrecord_down[0]); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); traverse_child = fork(); ok(traverse_child != -1, "fork should succeed"); if (traverse_child == 0) { tdb_close(tdb); close(traverse_up[0]); close(traverse_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); do_traverse(name, tdb_flags, traverse_up[1], traverse_down[0]); exit(0); } close(traverse_up[1]); close(traverse_down[0]); poll(NULL, 0, 1000); nwritten = write(allrecord_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(traverse_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); nwritten = write(traverse_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "ret should succeed"); close(traverse_up[0]); close(traverse_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); diag("%s tests done", name); return exit_status(); } int main(int argc, char *argv[]) { int ret; bool mutex_support; mutex_support = tdb_runtime_check_for_robust_mutexes(); ret = do_tests("marklock-deadlock-fcntl.tdb", TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); if (!mutex_support) { skip(1, "No robust mutex support, " "skipping marklock-deadlock-mutex.tdb tests"); return exit_status(); } ret = do_tests("marklock-deadlock-mutex.tdb", TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c0000660000000000000000000000310412406075657020217 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; struct tdb_header hdr; int fd; plan_tests(11); /* Can open fine if complete crap, as long as O_CREAT. */ fd = open("run-bad-tdb-header.tdb", O_RDWR|O_CREAT|O_TRUNC, 0600); ok1(fd >= 0); ok1(write(fd, "hello world", 11) == 11); close(fd); tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(!tdb); tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); tdb_close(tdb); /* Now, with wrong version it should *not* overwrite. */ fd = open("run-bad-tdb-header.tdb", O_RDWR); ok1(fd >= 0); ok1(read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); ok1(hdr.version == TDB_VERSION); hdr.version++; lseek(fd, 0, SEEK_SET); ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); close(fd); tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT, 0600, &taplogctx, NULL); ok1(errno == EIO); ok1(!tdb); /* With truncate, will be fine. */ tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT|O_TRUNC, 0600, &taplogctx, NULL); ok1(tdb); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-check.c0000660000000000000000000000321012406075657016547 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(13); tdb = tdb_open_ex("run-check.tdb", 1, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("run-check.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == -1); ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); tdb_close(tdb); /* Big and little endian should work! */ tdb = tdb_open_ex("test/old-nohash-le.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-be.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-circular-chain.c0000660000000000000000000000150013573675413020360 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key; plan_tests(3); tdb = tdb_open_ex( "test/circular_chain.tdb", 0, TDB_DEFAULT, O_RDONLY, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("x"); key.dptr = discard_const_p(uint8_t, "x"); ok1(tdb_exists(tdb, key) == 0); ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-circular-freelist.c0000660000000000000000000000207713573675413021125 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(3); tdb = tdb_open_ex( "test/circular_freelist.tdb", 0, TDB_DEFAULT, O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); /* * All freelist records are just 1 byte key and value. Insert * something that will walk the whole freelist and hit the * circle. */ key.dsize = strlen("x"); key.dptr = discard_const_p(uint8_t, "x"); data.dsize = strlen("too long"); data.dptr = discard_const_p(uint8_t, "too long"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == -1); ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-corrupt.c0000660000000000000000000000660712406075657017205 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static int check(TDB_DATA key, TDB_DATA data, void *private) { unsigned int *sizes = private; if (key.dsize > strlen("hello")) return -1; if (memcmp(key.dptr, "hello", key.dsize) != 0) return -1; if (data.dsize != strlen("world")) return -1; if (memcmp(data.dptr, "world", data.dsize) != 0) return -1; sizes[0] += key.dsize; sizes[1] += data.dsize; return 0; } static void tdb_flip_bit(struct tdb_context *tdb, unsigned int bit) { unsigned int off = bit / CHAR_BIT; unsigned char mask = (1 << (bit % CHAR_BIT)); if (tdb->map_ptr) ((unsigned char *)tdb->map_ptr)[off] ^= mask; else { unsigned char c; if (pread(tdb->fd, &c, 1, off) != 1) { fprintf(stderr, "pread: %s\n", strerror(errno)); exit(1); } c ^= mask; if (pwrite(tdb->fd, &c, 1, off) != 1) { fprintf(stderr, "pwrite: %s\n", strerror(errno)); exit(1); } } } static void check_test(struct tdb_context *tdb) { TDB_DATA key, data; unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize; ok1(tdb_check(tdb, NULL, NULL) == 0); key.dptr = discard_const_p(uint8_t, "hello"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); /* Key and data size respectively. */ dsize = ksize = 0; /* 5 keys in hash size 2 means we'll have multichains. */ for (key.dsize = 1; key.dsize <= 5; key.dsize++) { ksize += key.dsize; dsize += data.dsize; if (tdb_store(tdb, key, data, TDB_INSERT) != 0) abort(); } /* This is how many bytes we expect to be verifiable. */ /* From the file header. */ verifiable = strlen(TDB_MAGIC_FOOD) + 1 + 2 * sizeof(uint32_t) + 2 * sizeof(tdb_off_t) + 2 * sizeof(uint32_t); /* From the free list chain and hash chains. */ verifiable += 3 * sizeof(tdb_off_t); /* From the record headers & tailer */ verifiable += 5 * (sizeof(struct tdb_record) + sizeof(uint32_t)); /* The free block: we ignore datalen, keylen, full_hash. */ verifiable += sizeof(struct tdb_record) - 3*sizeof(uint32_t) + sizeof(uint32_t); /* Our check function verifies the key and data. */ verifiable += ksize + dsize; /* Flip one bit at a time, make sure it detects verifiable bytes. */ for (i = 0, corrupt = 0; i < tdb->map_size * CHAR_BIT; i++) { tdb_flip_bit(tdb, i); memset(sizes, 0, sizeof(sizes)); if (tdb_check(tdb, check, sizes) != 0) corrupt++; else if (sizes[0] != ksize || sizes[1] != dsize) corrupt++; tdb_flip_bit(tdb, i); } ok(corrupt == verifiable * CHAR_BIT, "corrupt %u should be %u", corrupt, verifiable * CHAR_BIT); } int main(int argc, char *argv[]) { struct tdb_context *tdb; plan_tests(4); /* This should use mmap. */ tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (!tdb) abort(); check_test(tdb); tdb_close(tdb); /* This should not. */ tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST|TDB_NOMMAP, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (!tdb) abort(); check_test(tdb); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c0000660000000000000000000001203112406075657022045 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); static ssize_t write_check(int fd, const void *buf, size_t count); static int ftruncate_check(int fd, off_t length); #define pwrite pwrite_check #define write write_check #define fcntl fcntl_with_lockcheck #define ftruncate ftruncate_check #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "external-agent.h" #include "logging.h" #undef write #undef pwrite #undef fcntl #undef ftruncate static bool in_transaction; static int target, current; static jmp_buf jmpbuf; #define TEST_DBNAME "run-die-during-transaction.tdb" #define KEY_STRING "helloworld" static void maybe_die(int fd) { if (in_transaction && current++ == target) { longjmp(jmpbuf, 1); } } static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset) { ssize_t ret; maybe_die(fd); ret = pwrite(fd, buf, count, offset); if (ret != count) return ret; maybe_die(fd); return ret; } static ssize_t write_check(int fd, const void *buf, size_t count) { ssize_t ret; maybe_die(fd); ret = write(fd, buf, count); if (ret != count) return ret; maybe_die(fd); return ret; } static int ftruncate_check(int fd, off_t length) { int ret; maybe_die(fd); ret = ftruncate(fd, length); maybe_die(fd); return ret; } static bool test_death(enum operation op, struct agent *agent) { struct tdb_context *tdb = NULL; TDB_DATA key; enum agent_return ret; int needed_recovery = 0; current = target = 0; reset: unlink(TEST_DBNAME); tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (setjmp(jmpbuf) != 0) { /* We're partway through. Simulate our death. */ close(tdb->fd); forget_locking(); in_transaction = false; ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); if (ret == SUCCESS) needed_recovery++; else if (ret != FAILED) { diag("Step %u agent NEEDS_RECOVERY = %s", current, agent_return_name(ret)); return false; } ret = external_agent_operation(agent, op, KEY_STRING); if (ret != SUCCESS) { diag("Step %u op %s failed = %s", current, operation_name(op), agent_return_name(ret)); return false; } ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); if (ret != FAILED) { diag("Still needs recovery after step %u = %s", current, agent_return_name(ret)); return false; } ret = external_agent_operation(agent, CHECK, ""); if (ret != SUCCESS) { diag("Step %u check failed = %s", current, agent_return_name(ret)); return false; } ret = external_agent_operation(agent, CLOSE, ""); if (ret != SUCCESS) { diag("Step %u close failed = %s", current, agent_return_name(ret)); return false; } /* Suppress logging as this tries to use closed fd. */ suppress_logging = true; suppress_lockcheck = true; tdb_close(tdb); suppress_logging = false; suppress_lockcheck = false; target++; current = 0; goto reset; } /* Put key for agent to fetch. */ key.dsize = strlen(KEY_STRING); key.dptr = discard_const_p(uint8_t, KEY_STRING); if (tdb_store(tdb, key, key, TDB_INSERT) != 0) return false; /* This is the key we insert in transaction. */ key.dsize--; ret = external_agent_operation(agent, OPEN, TEST_DBNAME); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to open: %s\n", agent_return_name(ret)); exit(1); } ret = external_agent_operation(agent, FETCH, KEY_STRING); if (ret != SUCCESS) { fprintf(stderr, "Agent failed find key: %s\n", agent_return_name(ret)); exit(1); } in_transaction = true; if (tdb_transaction_start(tdb) != 0) return false; if (tdb_store(tdb, key, key, TDB_INSERT) != 0) return false; if (tdb_transaction_commit(tdb) != 0) return false; in_transaction = false; /* We made it! */ diag("Completed %u runs", current); tdb_close(tdb); ret = external_agent_operation(agent, CLOSE, ""); if (ret != SUCCESS) { diag("Step %u close failed = %s", current, agent_return_name(ret)); return false; } #ifdef HAVE_INCOHERENT_MMAP /* This means we always mmap, which makes this test a noop. */ ok1(1); #else ok1(needed_recovery); #endif ok1(locking_errors == 0); ok1(forget_locking() == 0); locking_errors = 0; return true; } int main(int argc, char *argv[]) { enum operation ops[] = { FETCH, STORE, TRANSACTION_START }; struct agent *agent; int i; plan_tests(12); unlock_callback = maybe_die; agent = prepare_external_agent(); for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { diag("Testing %s after death", operation_name(ops[i])); ok1(test_death(ops[i], agent)); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-endian.c0000660000000000000000000000325412406075657016740 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(13); tdb = tdb_open_ex("run-endian.tdb", 1024, TDB_CLEAR_IF_FIRST|TDB_CONVERT, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); ok1(tdb_error(tdb) == TDB_ERR_EXISTS); ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); key.dsize++; data = tdb_fetch(tdb, key); ok1(data.dptr == NULL); tdb_close(tdb); /* Reopen: should read it */ tdb = tdb_open_ex("run-endian.tdb", 1024, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c0000660000000000000000000001174213120574744020350 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "replace.h" #include "system/filesys.h" #include "system/time.h" #include #include "tap-interface.h" /* * This tests the low level locking requirement * for the allrecord lock/prepare_commit and traverse_read interaction. * * The pattern with the traverse_read and prepare_commit interaction is * the following: * * 1. transaction_start got the allrecord lock with F_RDLCK. * * 2. the traverse_read code walks the database in a sequence like this * (per chain): * 2.1 chainlock(chainX, F_RDLCK) * 2.2 recordlock(chainX.record1, F_RDLCK) * 2.3 chainunlock(chainX, F_RDLCK) * 2.4 callback(chainX.record1) * 2.5 chainlock(chainX, F_RDLCK) * 2.6 recordunlock(chainX.record1, F_RDLCK) * 2.7 recordlock(chainX.record2, F_RDLCK) * 2.8 chainunlock(chainX, F_RDLCK) * 2.9 callback(chainX.record2) * 2.10 chainlock(chainX, F_RDLCK) * 2.11 recordunlock(chainX.record2, F_RDLCK) * 2.12 chainunlock(chainX, F_RDLCK) * 2.13 goto next chain * * So it has always one record locked in F_RDLCK mode and tries to * get the 2nd one before it releases the first one. * * 3. prepare_commit tries to upgrade the allrecord lock to F_RWLCK * If that happens at the time of 2.4, the operation of * 2.5 may deadlock with the allrecord lock upgrade. * On Linux step 2.5 works in order to make some progress with the * locking, but on solaris it might fail because the kernel * wants to satisfy the 1st lock requester before the 2nd one. * * I think the first step is a standalone test that does this: * * process1: F_RDLCK for ofs=0 len=2 * process2: F_RDLCK for ofs=0 len=1 * process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) * process2: F_RDLCK for ofs=1 len=1 * process2: unlock ofs=0 len=2 * process1: should continue at that point * * Such a test follows here... */ static int raw_fcntl_lock(int fd, int rw, off_t off, off_t len, bool waitflag) { struct flock fl; int cmd; fl.l_type = rw; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; cmd = waitflag ? F_SETLKW : F_SETLK; return fcntl(fd, cmd, &fl); } static int raw_fcntl_unlock(int fd, off_t off, off_t len) { struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = off; fl.l_len = len; fl.l_pid = 0; return fcntl(fd, F_SETLKW, &fl); } int pipe_r; int pipe_w; char buf[2]; static void expect_char(char c) { read(pipe_r, buf, 1); if (*buf != c) { fail("We were expecting %c, but got %c", c, buf[0]); } } static void send_char(char c) { write(pipe_w, &c, 1); } int main(int argc, char *argv[]) { int process; int fd; const char *filename = "run-fcntl-deadlock.lck"; int pid; int pipes_1_2[2]; int pipes_2_1[2]; int ret; pipe(pipes_1_2); pipe(pipes_2_1); fd = open(filename, O_RDWR | O_CREAT, 0755); pid = fork(); if (pid == 0) { pipe_r = pipes_1_2[0]; pipe_w = pipes_2_1[1]; process = 2; alarm(15); } else { pipe_r = pipes_2_1[0]; pipe_w = pipes_1_2[1]; process = 1; alarm(15); } /* a: process1: F_RDLCK for ofs=0 len=2 */ if (process == 1) { ret = raw_fcntl_lock(fd, F_RDLCK, 0, 2, true); ok(ret == 0, "process 1 lock ofs=0 len=2: %d - %s", ret, strerror(errno)); diag("process 1 took read lock on range 0,2"); send_char('a'); } /* process2: F_RDLCK for ofs=0 len=1 */ if (process == 2) { expect_char('a'); ret = raw_fcntl_lock(fd, F_RDLCK, 0, 1, true); ok(ret == 0, "process 2 lock ofs=0 len=1: %d - %s", ret, strerror(errno));; diag("process 2 took read lock on range 0,1"); send_char('b'); } /* process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) */ if (process == 1) { expect_char('b'); send_char('c'); diag("process 1 starts upgrade on range 0,2"); ret = raw_fcntl_lock(fd, F_WRLCK, 0, 2, true); ok(ret == 0, "process 1 RW lock ofs=0 len=2: %d - %s", ret, strerror(errno)); diag("process 1 got read upgrade done"); /* at this point process 1 is blocked on 2 releasing the read lock */ } /* * process2: F_RDLCK for ofs=1 len=1 * process2: unlock ofs=0 len=2 */ if (process == 2) { expect_char('c'); /* we know process 1 is *about* to lock */ sleep(1); ret = raw_fcntl_lock(fd, F_RDLCK, 1, 1, true); ok(ret == 0, "process 2 lock ofs=1 len=1: %d - %s", ret, strerror(errno)); diag("process 2 got read lock on 1,1\n"); ret = raw_fcntl_unlock(fd, 0, 2); ok(ret == 0, "process 2 unlock ofs=0 len=2: %d - %s", ret, strerror(errno)); diag("process 2 released read lock on 0,2\n"); sleep(1); send_char('d'); } if (process == 1) { expect_char('d'); } diag("process %d has got to the end\n", process); return 0; } ldb-2.0.8/lib/tdb/test/run-incompatible.c0000660000000000000000000001131012520121120020106 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include static unsigned int tdb_dumb_hash(TDB_DATA *key) { return key->dsize; } static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); if (strstr(fmt, "hash")) (*count)++; } static unsigned int hdr_rwlocks(const char *fname) { struct tdb_header hdr; ssize_t nread; int fd = open(fname, O_RDONLY); if (fd == -1) return -1; nread = read(fd, &hdr, sizeof(hdr)); close(fd); if (nread != sizeof(hdr)) { return -1; } return hdr.rwlocks; } int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count, flags; TDB_DATA d, r; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(38 * 2); for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) { unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC; if (flags & TDB_CONVERT) tdb_convert(&rwmagic, sizeof(rwmagic)); /* Create an old-style hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, flags, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Should not have marked rwlocks field. */ ok1(hdr_rwlocks("run-incompatible.tdb") == 0); /* We can still open any old-style with incompat flag. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, TDB_INCOMPATIBLE_HASH, O_RDWR, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* OK, now create with incompatible flag, default hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, flags|TDB_INCOMPATIBLE_HASH, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Should have marked rwlocks field. */ ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); /* Cannot open with old hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0600, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); /* Can open with jenkins hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0600, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* Can open by letting it figure it out itself. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* We can also use incompatible hash with other hashes. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, flags|TDB_INCOMPATIBLE_HASH, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, tdb_dumb_hash); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Should have marked rwlocks field. */ ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); /* It should not open if we don't specify. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(!tdb); ok1(log_count == 1); /* Should reopen with correct hash. */ log_count = 0; tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_dumb_hash); ok1(tdb); ok1(log_count == 0); r = tdb_fetch(tdb, d); ok1(r.dsize == 5); free(r.dptr); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c0000660000000000000000000001634313573675413021056 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "logging.h" static TDB_DATA key, data; static void do_chainlock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); exit(0); } static void do_allrecord_lock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); exit(0); } /* The code should barf on TDBs created with rwlocks. */ static int do_tests(const char *name, int tdb_flags) { struct tdb_context *tdb; int ret; pid_t chainlock_child, allrecord_child; int chainlock_down[2]; int chainlock_up[2]; int allrecord_down[2]; int allrecord_up[2]; char c; ssize_t nread, nwritten; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ret = pipe(chainlock_down); ok(ret == 0, "pipe should succeed"); ret = pipe(chainlock_up); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_down); ok(ret == 0, "pipe should succeed"); ret = pipe(allrecord_up); ok(ret == 0, "pipe should succeed"); chainlock_child = fork(); ok(chainlock_child != -1, "fork should succeed"); if (chainlock_child == 0) { close(chainlock_up[0]); close(chainlock_down[1]); close(allrecord_up[0]); close(allrecord_up[1]); close(allrecord_down[0]); close(allrecord_down[1]); do_chainlock(name, tdb_flags, chainlock_up[1], chainlock_down[0]); exit(0); } close(chainlock_up[1]); close(chainlock_down[0]); nread = read(chainlock_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); /* * Now we have a process holding a chainlock. Start another process * trying the allrecord lock. This will block. */ allrecord_child = fork(); ok(allrecord_child != -1, "fork should succeed"); if (allrecord_child == 0) { close(chainlock_up[0]); close(chainlock_up[1]); close(chainlock_down[0]); close(chainlock_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); do_allrecord_lock(name, tdb_flags, allrecord_up[1], allrecord_down[0]); exit(0); } close(allrecord_up[1]); close(allrecord_down[0]); poll(NULL, 0, 500); tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); /* * Someone already holds a chainlock, but we're able to get the * freelist lock. * * The freelist lock/mutex is independent from the allrecord lock/mutex. */ ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); /* * We have someone else having done the lock for us. Just mark it. */ ret = tdb_chainlock_mark(tdb, key); ok(ret == 0, "tdb_chainlock_mark should succeed"); /* * The tdb_store below will block the freelist. In one version of the * mutex patches, the freelist was already blocked here by the * allrecord child, which was waiting for the chainlock child to give * up its chainlock. Make sure that we don't run into this * deadlock. To exercise the deadlock, just comment out the "ok" * line. * * The freelist lock/mutex is independent from the allrecord lock/mutex. */ ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store should succeed"); ret = tdb_chainlock_unmark(tdb, key); ok(ret == 0, "tdb_chainlock_unmark should succeed"); nwritten = write(chainlock_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(chainlock_up[0], &c, sizeof(c)); ok(nread == 0, "read should succeed"); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); /* * Someone already holds the allrecord lock, but we're able to get the * freelist lock. * * The freelist lock/mutex is independent from the allrecord lock/mutex. */ ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); ret = tdb_lockall_nonblock(tdb); ok(ret == -1, "tdb_lockall_nonblock should not succeed"); ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); /* * We have someone else having done the lock for us. Just mark it. */ ret = tdb_lockall_mark(tdb); ok(ret == 0, "tdb_lockall_mark should succeed"); ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_lock_nonblock should succeed"); ret = tdb_unlock(tdb, -1, F_WRLCK); ok(ret == 0, "tdb_unlock should succeed"); ret = tdb_store(tdb, key, data, TDB_REPLACE); ok(ret == 0, "tdb_store should succeed"); ret = tdb_lockall_unmark(tdb); ok(ret == 0, "tdb_lockall_unmark should succeed"); nwritten = write(allrecord_down[1], &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(allrecord_up[0], &c, sizeof(c)); ok(nread == 0, "read should succeed"); close(chainlock_up[0]); close(chainlock_down[1]); close(allrecord_up[0]); close(allrecord_down[1]); diag("%s tests done", name); return exit_status(); } int main(int argc, char *argv[]) { int ret; bool mutex_support; mutex_support = tdb_runtime_check_for_robust_mutexes(); ret = do_tests("marklock-deadlock-fcntl.tdb", TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); if (!mutex_support) { skip(1, "No robust mutex support, " "skipping marklock-deadlock-mutex.tdb tests"); return exit_status(); } ret = do_tests("marklock-deadlock-mutex.tdb", TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c0000660000000000000000000000400612406075657021662 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2) { return (tv2->tv_sec - tv1->tv_sec) + (tv2->tv_usec - tv1->tv_usec)*1.0e-6; } static double timeval_elapsed(const struct timeval *tv) { struct timeval tv2; gettimeofday(&tv2, NULL); return timeval_elapsed2(tv, &tv2); } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; struct timeval start; double elapsed; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); tdb = tdb_open_ex("mutex-allrecord-bench.tdb", 1000000, TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); gettimeofday(&start, NULL); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); elapsed = timeval_elapsed(&start); ok(ret == 0, "tdb_allrecord_lock should succeed"); diag("allrecord_lock took %f seconds", elapsed); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c0000660000000000000000000000546112406075657021703 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-allrecord-block.tdb", 3, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); ok(ret == 0, "tdb_allrecord_unlock should succeed"); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-allrecord-block.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); write(tochild[1], &c, sizeof(c)); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should not succeed"); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c0000660000000000000000000000515412406075657022277 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 3, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); ok(ret == -1, "tdb_allrecord_lock (nowait) should not succeed"); write(tochild[1], &c, sizeof(c)); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-die.c0000660000000000000000000001160612406075657017403 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); static ssize_t write_check(int fd, const void *buf, size_t count); static int ftruncate_check(int fd, off_t length); #define pwrite pwrite_check #define write write_check #define fcntl fcntl_with_lockcheck #define ftruncate ftruncate_check #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include "external-agent.h" #include "logging.h" #undef write #undef pwrite #undef fcntl #undef ftruncate static int target, current; #define TEST_DBNAME "run-mutex-die.tdb" #define KEY_STRING "helloworld" static void maybe_die(int fd) { if (target == 0) { return; } current += 1; if (current == target) { _exit(1); } } static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset) { ssize_t ret; maybe_die(fd); ret = pwrite(fd, buf, count, offset); if (ret != count) return ret; maybe_die(fd); return ret; } static ssize_t write_check(int fd, const void *buf, size_t count) { ssize_t ret; maybe_die(fd); ret = write(fd, buf, count); if (ret != count) return ret; maybe_die(fd); return ret; } static int ftruncate_check(int fd, off_t length) { int ret; maybe_die(fd); ret = ftruncate(fd, length); maybe_die(fd); return ret; } static enum agent_return flakey_ops(struct agent *a) { enum agent_return ret; /* * Run in the external agent child */ ret = external_agent_operation(a, OPEN_WITH_CLEAR_IF_FIRST, TEST_DBNAME); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to open: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, UNMAP, ""); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to unmap: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, STORE, "xyz"); if (ret != SUCCESS) { fprintf(stderr, "Agent failed to store: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, STORE, KEY_STRING); if (ret != SUCCESS) { fprintf(stderr, "Agent failed store: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, FETCH, KEY_STRING); if (ret != SUCCESS) { fprintf(stderr, "Agent failed find key: %s\n", agent_return_name(ret)); return ret; } ret = external_agent_operation(a, PING, ""); if (ret != SUCCESS) { fprintf(stderr, "Agent failed ping: %s\n", agent_return_name(ret)); return ret; } return ret; } static bool prep_db(void) { struct tdb_context *tdb; TDB_DATA key; TDB_DATA data; key.dptr = discard_const_p(uint8_t, KEY_STRING); key.dsize = strlen((char *)key.dptr); data.dptr = discard_const_p(uint8_t, "foo"); data.dsize = strlen((char *)data.dptr); unlink(TEST_DBNAME); tdb = tdb_open_ex( TEST_DBNAME, 2, TDB_INCOMPATIBLE_HASH|TDB_MUTEX_LOCKING|TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); if (tdb == NULL) { return false; } if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { return false; } tdb_close(tdb); tdb = NULL; forget_locking(); return true; } static bool test_db(void) { struct tdb_context *tdb; int ret; tdb = tdb_open_ex( TEST_DBNAME, 1024, TDB_INCOMPATIBLE_HASH, O_RDWR, 0600, &taplogctx, NULL); if (tdb == NULL) { perror("tdb_open_ex failed"); return false; } ret = tdb_traverse(tdb, NULL, NULL); if (ret == -1) { perror("traverse failed"); goto fail; } tdb_close(tdb); forget_locking(); return true; fail: tdb_close(tdb); return false; } static bool test_one(void) { enum agent_return ret; ret = AGENT_DIED; target = 19; while (ret != SUCCESS) { struct agent *agent; { int child_target = target; bool pret; target = 0; pret = prep_db(); ok1(pret); target = child_target; } agent = prepare_external_agent(); ret = flakey_ops(agent); diag("Agent (target=%d) returns %s", target, agent_return_name(ret)); if (ret == SUCCESS) { ok((target > 19), "At least one AGENT_DIED expected"); } else { ok(ret == AGENT_DIED, "AGENT_DIED expected"); } shutdown_agent(agent); { int child_target = target; bool tret; target = 0; tret = test_db(); ok1(tret); target = child_target; } target += 1; } return true; } int main(int argc, char *argv[]) { bool ret; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } plan_tests(12); unlock_callback = maybe_die; ret = test_one(); ok1(ret); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c0000660000000000000000000000766413573675413020715 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include static TDB_DATA key, data; static void log_void(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { } static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int fd) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; struct tdb_logging_context nolog_ctx = { log_void, NULL }; char c; read(fd, &c, 1); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_DEFAULT without " "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_CLEAR_IF_FIRST without " "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_INTERNAL, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " "TDB_INTERNAL should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING | TDB_NOMMAP, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " "TDB_NOMMAP should fail with EINVAL - %d", errno); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING, O_RDONLY, 0755, &nolog_ctx, NULL); ok((tdb != NULL), "TDB_MUTEX_LOCKING with " "O_RDONLY should work - %d", errno); tdb_close(tdb); tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST | TDB_MUTEX_LOCKING, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok((tdb != NULL), "TDB_MUTEX_LOCKING with TDB_CLEAR_IF_FIRST" "TDB_NOMMAP should work - %d", errno); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; struct tdb_logging_context nolog_ctx = { log_void, NULL }; int ret, status; pid_t child, wait_ret; int pipefd[2]; char c = 0; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); ret = pipe(pipefd); ok1(ret == 0); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); if (!runtime_support) { tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST| TDB_MUTEX_LOCKING, O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); ok((tdb == NULL) && (errno == ENOSYS), "TDB_MUTEX_LOCKING without " "runtime support should fail with ENOSYS - %d", errno); skip(1, "No robust mutex support"); return exit_status(); } child = fork(); if (child == 0) { return do_child(pipefd[0]); } tdb = tdb_open_ex("mutex-openflags2.tdb", 0, TDB_CLEAR_IF_FIRST| TDB_MUTEX_LOCKING, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok((tdb != NULL), "tdb_open_ex with mutexes should succeed"); write(pipefd[1], &c, 1); wait_ret = wait(&status); ok((wait_ret == child) && (status == 0), "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c0000660000000000000000000001416512445751350021245 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-transaction1.tdb", 3, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_cancel(tdb); ok(ret == 0, "tdb_transaction_cancel should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); ret = tdb_store(tdb, key, data, TDB_INSERT); ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_commit(tdb); ok(ret == 0, "tdb_transaction_commit should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); ret = tdb_store(tdb, key, key, TDB_REPLACE); ok(ret == 0, "tdb_store(tdb, key, data, TDB_REPLACE) should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_transaction_commit(tdb); ok(ret == 0, "tdb_transaction_commit should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; TDB_DATA val; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-transaction1.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); /* * The child has the transaction running */ ret = tdb_transaction_start_nonblock(tdb); ok(ret == -1, "tdb_transaction_start_nonblock not succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); /* * We can still read */ ret = tdb_exists(tdb, key); ok(ret == 0, "tdb_exists(tdb, key) should return 0"); val = tdb_fetch(tdb, key); ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); write(tochild[1], &c, sizeof(c)); /* * When the child canceled we can start... */ ret = tdb_transaction_start(tdb); ok(ret == 0, "tdb_transaction_start should succeed"); read(fromchild[0], &c, sizeof(c)); write(tochild[1], &c, sizeof(c)); ret = tdb_transaction_cancel(tdb); ok(ret == 0, "tdb_transaction_cancel should succeed"); /* * When we canceled the child can start and store... */ read(fromchild[0], &c, sizeof(c)); /* * We still see the old values before the child commits... */ ret = tdb_exists(tdb, key); ok(ret == 0, "tdb_exists(tdb, key) should return 0"); val = tdb_fetch(tdb, key); ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); /* * We see the new values after the commit... */ ret = tdb_exists(tdb, key); ok(ret == 1, "tdb_exists(tdb, key) should return 1"); val = tdb_fetch(tdb, key); ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); /* * The child started a new transaction and replaces the value, * but we still see the old values before the child commits... */ ret = tdb_exists(tdb, key); ok(ret == 1, "tdb_exists(tdb, key) should return 1"); val = tdb_fetch(tdb, key); ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); /* * We see the new values after the commit... */ ret = tdb_exists(tdb, key); ok(ret == 1, "tdb_exists(tdb, key) should return 1"); val = tdb_fetch(tdb, key); ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); ok(val.dsize == key.dsize, "tdb_fetch(tdb, key) should return a value"); ok(memcmp(val.dptr, key.dptr, key.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); write(tochild[1], &c, sizeof(c)); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c0000660000000000000000000000546112406075657020333 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); write(to, &c, sizeof(c)); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == 0, "tdb_chainlock_nonblock should succeed"); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-mutex1.c0000660000000000000000000000642712406075657016732 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include static TDB_DATA key, data; static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } static int do_child(int tdb_flags, int to, int from) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret; char c = 0; tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock(tdb, key); ok(ret == 0, "tdb_chainlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_chainunlock(tdb, key); ok(ret == 0, "tdb_chainunlock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); write(to, &c, sizeof(c)); read(from, &c, sizeof(c)); ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); return 0; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; int ret, status; pid_t child, wait_ret; int fromchild[2]; int tochild[2]; char c; int tdb_flags; bool runtime_support; runtime_support = tdb_runtime_check_for_robust_mutexes(); if (!runtime_support) { skip(1, "No robust mutex support"); return exit_status(); } key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); pipe(fromchild); pipe(tochild); tdb_flags = TDB_INCOMPATIBLE_HASH| TDB_MUTEX_LOCKING| TDB_CLEAR_IF_FIRST; child = fork(); if (child == 0) { close(fromchild[0]); close(tochild[1]); return do_child(tdb_flags, fromchild[1], tochild[0]); } close(fromchild[1]); close(tochild[0]); read(fromchild[0], &c, sizeof(c)); tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, O_RDWR|O_CREAT, 0755, &log_ctx, NULL); ok(tdb, "tdb_open_ex should succeed"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); ok(ret == 0, "tdb_allrecord_lock should succeed"); ret = tdb_store(tdb, key, data, 0); ok(ret == 0, "tdb_store should succeed"); ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); ok(ret == 0, "tdb_allrecord_unlock should succeed"); write(tochild[1], &c, sizeof(c)); read(fromchild[0], &c, sizeof(c)); write(tochild[1], &c, sizeof(c)); ret = tdb_delete(tdb, key); ok(ret == 0, "tdb_delete should succeed"); wait_ret = wait(&status); ok(wait_ret == child, "child should have exited correctly"); diag("done"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-nested-transactions.c0000660000000000000000000000435712406075657021477 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(27); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); tdb = tdb_open_ex("run-nested-transactions.tdb", 1024, TDB_CLEAR_IF_FIRST|TDB_DISALLOW_NESTING, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); /* Nesting disallowed. */ ok1(tdb_transaction_start(tdb) == 0); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); ok1(tdb_transaction_start(tdb) != 0); ok1(tdb_error(tdb) == TDB_ERR_NESTING); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); ok1(tdb_transaction_commit(tdb) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); tdb_close(tdb); /* Nesting allowed by default */ tdb = tdb_open_ex("run-nested-transactions.tdb", 1024, TDB_DEFAULT, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_delete(tdb, key) == 0); ok1(tdb_transaction_commit(tdb) == 0); ok1(!tdb_exists(tdb, key)); ok1(tdb_transaction_cancel(tdb) == 0); /* Surprise! Kills inner "committed" transaction. */ ok1(tdb_exists(tdb, key)); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_delete(tdb, key) == 0); ok1(tdb_transaction_commit(tdb) == 0); ok1(!tdb_exists(tdb, key)); ok1(tdb_transaction_commit(tdb) == 0); ok1(!tdb_exists(tdb, key)); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-nested-traverse.c0000660000000000000000000000600613126252766020611 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" #define fcntl fcntl_with_lockcheck #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #undef fcntl #include #include #include "external-agent.h" #include "logging.h" static struct agent *agent; static bool correct_key(TDB_DATA key) { return key.dsize == strlen("hi") && memcmp(key.dptr, "hi", key.dsize) == 0; } static bool correct_data(TDB_DATA data) { return data.dsize == strlen("world") && memcmp(data.dptr, "world", data.dsize) == 0; } static int traverse2(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); return 0; } static int traverse1r(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse(tdb, traverse2, NULL); /* That should *not* release the all-records lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); return 0; } static int traverse1w(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse(tdb, traverse2, NULL); /* That should *not* release the all-records lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(17); agent = prepare_external_agent(); tdb = tdb_open_ex("run-nested-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) == SUCCESS); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); tdb_traverse(tdb, traverse1w, NULL); tdb_traverse_read(tdb, traverse1r, NULL); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c0000660000000000000000000000467112406075657022167 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" #define fcntl fcntl_with_lockcheck #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" #undef fcntl #define NUM_ENTRIES 10 static bool prepare_entries(struct tdb_context *tdb) { unsigned int i; TDB_DATA key, data; for (i = 0; i < NUM_ENTRIES; i++) { key.dsize = sizeof(i); key.dptr = (void *)&i; data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); if (tdb_store(tdb, key, data, 0) != 0) return false; } return true; } static void delete_entries(struct tdb_context *tdb) { unsigned int i; TDB_DATA key; for (i = 0; i < NUM_ENTRIES; i++) { key.dsize = sizeof(i); key.dptr = (void *)&i; ok1(tdb_delete(tdb, key) == 0); } } /* We don't know how many times this will run. */ static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { unsigned int i; memcpy(&i, key.dptr, 4); i = (i + 1) % NUM_ENTRIES; key.dptr = (void *)&i; if (tdb_delete(tdb, key) != 0) (*(int *)private_data)++; return 0; } static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { ok1(tdb_delete(tdb, key) == 0); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; int errors = 0; plan_tests(41); tdb = tdb_open_ex("run-no-lock-during-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); ok1(prepare_entries(tdb)); ok1(locking_errors == 0); ok1(tdb_lockall(tdb) == 0); ok1(locking_errors == 0); tdb_traverse(tdb, delete_other, &errors); ok1(errors == 0); ok1(locking_errors == 0); ok1(tdb_unlockall(tdb) == 0); ok1(prepare_entries(tdb)); ok1(locking_errors == 0); ok1(tdb_lockall(tdb) == 0); ok1(locking_errors == 0); tdb_traverse(tdb, delete_self, NULL); ok1(locking_errors == 0); ok1(tdb_unlockall(tdb) == 0); ok1(prepare_entries(tdb)); ok1(locking_errors == 0); ok1(tdb_lockall(tdb) == 0); ok1(locking_errors == 0); delete_entries(tdb); ok1(locking_errors == 0); ok1(tdb_unlockall(tdb) == 0); ok1(tdb_close(tdb) == 0); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-oldhash.c0000660000000000000000000000242512406075657017123 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; plan_tests(8); /* Old format (with zeroes in the hash magic fields) should * open with any hash (since we don't know what hash they used). */ tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, &taplogctx, tdb_jenkins_hash); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, &taplogctx, tdb_jenkins_hash); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c0000660000000000000000000001012412520121120022214 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "lock-tracking.h" static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); static ssize_t write_check(int fd, const void *buf, size_t count); static int ftruncate_check(int fd, off_t length); #define pwrite pwrite_check #define write write_check #define fcntl fcntl_with_lockcheck #define ftruncate ftruncate_check #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include "external-agent.h" #include "logging.h" static struct agent *agent; static bool opened; static int errors = 0; static bool clear_if_first; #define TEST_DBNAME "run-open-during-transaction.tdb" #undef write #undef pwrite #undef fcntl #undef ftruncate static bool is_same(const char *snapshot, const char *latest, off_t len) { unsigned i; for (i = 0; i < len; i++) { if (snapshot[i] != latest[i]) return false; } return true; } static bool compare_file(int fd, const char *snapshot, off_t snapshot_len) { char *contents; bool same; /* over-length read serves as length check. */ contents = malloc(snapshot_len+1); same = pread(fd, contents, snapshot_len+1, 0) == snapshot_len && is_same(snapshot, contents, snapshot_len); free(contents); return same; } static void check_file_intact(int fd) { enum agent_return ret; struct stat st; char *contents; fstat(fd, &st); contents = malloc(st.st_size); if (pread(fd, contents, st.st_size, 0) != st.st_size) { diag("Read fail"); errors++; free(contents); return; } /* Ask agent to open file. */ ret = external_agent_operation(agent, clear_if_first ? OPEN_WITH_CLEAR_IF_FIRST : OPEN, TEST_DBNAME); /* It's OK to open it, but it must not have changed! */ if (!compare_file(fd, contents, st.st_size)) { diag("Agent changed file after opening %s", agent_return_name(ret)); errors++; } if (ret == SUCCESS) { ret = external_agent_operation(agent, CLOSE, NULL); if (ret != SUCCESS) { diag("Agent failed to close tdb: %s", agent_return_name(ret)); errors++; } } else if (ret != WOULD_HAVE_BLOCKED) { diag("Agent opening file gave %s", agent_return_name(ret)); errors++; } free(contents); } static void after_unlock(int fd) { if (opened) check_file_intact(fd); } static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset) { if (opened) check_file_intact(fd); return pwrite(fd, buf, count, offset); } static ssize_t write_check(int fd, const void *buf, size_t count) { if (opened) check_file_intact(fd); return write(fd, buf, count); } static int ftruncate_check(int fd, off_t length) { if (opened) check_file_intact(fd); return ftruncate(fd, length); } int main(int argc, char *argv[]) { const int flags[] = { TDB_DEFAULT, TDB_CLEAR_IF_FIRST, TDB_NOMMAP, TDB_CLEAR_IF_FIRST | TDB_NOMMAP }; int i; struct tdb_context *tdb; TDB_DATA key, data; plan_tests(20); agent = prepare_external_agent(); unlock_callback = after_unlock; for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) { clear_if_first = (flags[i] & TDB_CLEAR_IF_FIRST); diag("Test with %s and %s", clear_if_first ? "CLEAR" : "DEFAULT", (flags[i] & TDB_NOMMAP) ? "no mmap" : "mmap"); unlink(TEST_DBNAME); tdb = tdb_open_ex(TEST_DBNAME, 1024, flags[i], O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); opened = true; ok1(tdb_transaction_start(tdb) == 0); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_transaction_commit(tdb) == 0); ok(!errors, "We had %u open errors", errors); opened = false; tdb_close(tdb); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c0000660000000000000000000000760413100601766020374 0ustar rootroot00000000000000#include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include #include #include #include "logging.h" static TDB_DATA key, data; static void do_chainlock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); ret = tdb_chainlock_read(tdb, key); ok(ret == 0, "tdb_chainlock_read should succeed"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == 0, "read should succeed"); exit(0); } static void do_trylock(const char *name, int tdb_flags, int up, int down) { struct tdb_context *tdb; int ret; ssize_t nread, nwritten; char c = 0; tdb = tdb_open_ex(name, 3, tdb_flags, O_RDWR|O_CREAT, 0755, &taplogctx, NULL); ok(tdb, "tdb_open_ex should succeed"); /* * tdb used to have a bug where with fcntl locks an upgrade * from a readlock to writelock did not check for the * underlying fcntl lock. Mutexes don't distinguish between * readlocks and writelocks, so that bug does not apply here. */ ret = tdb_chainlock_read(tdb, key); ok(ret == 0, "tdb_chainlock_read should succeed"); ret = tdb_chainlock_nonblock(tdb, key); ok(ret == -1, "tdb_chainlock_nonblock should fail"); nwritten = write(up, &c, sizeof(c)); ok(nwritten == sizeof(c), "write should succeed"); nread = read(down, &c, sizeof(c)); ok(nread == 0, "read should succeed"); exit(0); } static int do_tests(const char *name, int tdb_flags) { int ret; pid_t chainlock_child, store_child; int chainlock_down[2]; int chainlock_up[2]; int store_down[2]; int store_up[2]; char c; ssize_t nread; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ret = pipe(chainlock_down); ok(ret == 0, "pipe should succeed"); ret = pipe(chainlock_up); ok(ret == 0, "pipe should succeed"); ret = pipe(store_down); ok(ret == 0, "pipe should succeed"); ret = pipe(store_up); ok(ret == 0, "pipe should succeed"); chainlock_child = fork(); ok(chainlock_child != -1, "fork should succeed"); if (chainlock_child == 0) { close(chainlock_up[0]); close(chainlock_down[1]); close(store_up[0]); close(store_up[1]); close(store_down[0]); close(store_down[1]); do_chainlock(name, tdb_flags, chainlock_up[1], chainlock_down[0]); exit(0); } close(chainlock_up[1]); close(chainlock_down[0]); nread = read(chainlock_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); /* * Now we have a process holding a chain read lock. Start * another process trying to write lock. This should fail. */ store_child = fork(); ok(store_child != -1, "fork should succeed"); if (store_child == 0) { close(chainlock_up[0]); close(chainlock_down[1]); close(store_up[0]); close(store_down[1]); do_trylock(name, tdb_flags, store_up[1], store_down[0]); exit(0); } close(store_up[1]); close(store_down[0]); nread = read(store_up[0], &c, sizeof(c)); ok(nread == sizeof(c), "read should succeed"); close(chainlock_up[0]); close(chainlock_down[1]); close(store_up[0]); close(store_down[1]); diag("%s tests done", name); return exit_status(); } int main(int argc, char *argv[]) { int ret; ret = do_tests("rdlock-upgrade.tdb", TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH); ok(ret == 0, "rdlock-upgrade.tdb tests should succeed"); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-readonly-check.c0000660000000000000000000000275612406075657020400 0ustar rootroot00000000000000/* We should be able to tdb_check a O_RDONLY tdb, and we were previously allowed * to tdb_check() inside a transaction (though that's paranoia!). */ #include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(11); tdb = tdb_open_ex("run-readonly-check.tdb", 1024, TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); /* We are also allowed to do a check inside a transaction. */ ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_close(tdb) == 0); tdb = tdb_open_ex("run-readonly-check.tdb", 1024, TDB_DEFAULT, O_RDONLY, 0, &taplogctx, NULL); ok1(tdb); ok1(tdb_store(tdb, key, data, TDB_MODIFY) == -1); ok1(tdb_error(tdb) == TDB_ERR_RDONLY); ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_close(tdb) == 0); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c0000660000000000000000000000215012406075657021121 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/rescue.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" #define NUM 20 /* Binary searches are deceptively simple: easy to screw up! */ int main(int argc, char *argv[]) { unsigned int i, j, n; struct found f[NUM+1]; struct found_table table; /* Set up array for searching. */ for (i = 0; i < NUM+1; i++) { f[i].head = i * 3; } table.arr = f; for (i = 0; i < NUM; i++) { table.num = i; for (j = 0; j < (i + 2) * 3; j++) { n = find_entry(&table, j); ok1(n <= i); /* If we were searching for something too large... */ if (j > i*3) ok1(n == i); else { /* It must give us something after j */ ok1(f[n].head >= j); ok1(n == 0 || f[n-1].head < j); } } } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rescue.c0000660000000000000000000000566012406075657016773 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/rescue.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" struct walk_data { TDB_DATA key; TDB_DATA data; bool fail; unsigned count; }; static inline bool tdb_deq(TDB_DATA a, TDB_DATA b) { return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; } static inline TDB_DATA tdb_mkdata(const void *p, size_t len) { TDB_DATA d; d.dptr = discard_const_p(uint8_t, p); d.dsize = len; return d; } static void walk(TDB_DATA key, TDB_DATA data, void *_wd) { struct walk_data *wd = _wd; if (!tdb_deq(key, wd->key)) { wd->fail = true; } if (!tdb_deq(data, wd->data)) { wd->fail = true; } wd->count++; } static void count_records(TDB_DATA key, TDB_DATA data, void *_wd) { struct walk_data *wd = _wd; if (!tdb_deq(key, wd->key) || !tdb_deq(data, wd->data)) diag("%.*s::%.*s", (int)key.dsize, key.dptr, (int)data.dsize, data.dptr); wd->count++; } static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); (*count)++; } int main(int argc, char *argv[]) { struct tdb_context *tdb; struct walk_data wd; unsigned int i, size, log_count = 0; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(8); tdb = tdb_open_ex("run-rescue.tdb", 1, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &log_ctx, NULL); wd.key.dsize = strlen("hi"); wd.key.dptr = discard_const_p(uint8_t, "hi"); wd.data.dsize = strlen("world"); wd.data.dptr = discard_const_p(uint8_t, "world"); wd.count = 0; wd.fail = false; ok1(tdb_store(tdb, wd.key, wd.data, TDB_INSERT) == 0); ok1(tdb_rescue(tdb, walk, &wd) == 0); ok1(!wd.fail); ok1(wd.count == 1); /* Corrupt the database, walk should either get it or not. */ size = tdb->map_size; for (i = sizeof(struct tdb_header); i < size; i++) { char c; if (tdb->methods->tdb_read(tdb, i, &c, 1, false) != 0) fail("Reading offset %i", i); if (tdb->methods->tdb_write(tdb, i, "X", 1) != 0) fail("Writing X at offset %i", i); wd.count = 0; if (tdb_rescue(tdb, count_records, &wd) != 0) { wd.fail = true; break; } /* Could be 0 or 1. */ if (wd.count > 1) { wd.fail = true; break; } if (tdb->methods->tdb_write(tdb, i, &c, 1) != 0) fail("Restoring offset %i", i); } ok1(log_count == 0); ok1(!wd.fail); tdb_close(tdb); /* Now try our known-corrupt db. */ tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, &taplogctx, NULL); wd.count = 0; ok1(tdb_rescue(tdb, count_records, &wd) == 0); ok1(wd.count == 1627); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-rwlock-check.c0000660000000000000000000000223312406075657020052 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); if (strstr(fmt, "spinlocks")) (*count)++; } /* The code should barf on TDBs created with rwlocks. */ int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(4); /* We should fail to open rwlock-using tdbs of either endian. */ log_count = 0; tdb = tdb_open_ex("test/rwlock-le.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb_open_ex("test/rwlock-be.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(!tdb); ok1(log_count == 1); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-summary.c0000660000000000000000000000421612406075657017176 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/summary.c" #include "../common/mutex.c" #include "tap-interface.h" #include int main(int argc, char *argv[]) { unsigned int i, j; struct tdb_context *tdb; int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP, TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; TDB_DATA key = { (unsigned char *)&j, sizeof(j) }; TDB_DATA data = { (unsigned char *)&j, sizeof(j) }; char *summary; plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { tdb = tdb_open("run-summary.tdb", 131, flags[i], O_RDWR|O_CREAT|O_TRUNC, 0600); ok1(tdb); if (!tdb) continue; /* Put some stuff in there. */ for (j = 0; j < 500; j++) { /* Make sure padding varies to we get some graphs! */ data.dsize = j % (sizeof(j) + 1); if (tdb_store(tdb, key, data, TDB_REPLACE) != 0) fail("Storing in tdb"); } summary = tdb_summary(tdb); diag("%s", summary); ok1(strstr(summary, "Size of file/data: ")); ok1(strstr(summary, "Number of records: 500\n")); ok1(strstr(summary, "Smallest/average/largest keys: 4/4/4\n")); ok1(strstr(summary, "Smallest/average/largest data: 0/2/4\n")); ok1(strstr(summary, "Smallest/average/largest padding: ")); ok1(strstr(summary, "Number of dead records: 0\n")); ok1(strstr(summary, "Number of free records: 1\n")); ok1(strstr(summary, "Smallest/average/largest free records: ")); ok1(strstr(summary, "Number of hash chains: 131\n")); ok1(strstr(summary, "Smallest/average/largest hash chains: ")); ok1(strstr(summary, "Number of uncoalesced records: 0\n")); ok1(strstr(summary, "Smallest/average/largest uncoalesced runs: 0/0/0\n")); ok1(strstr(summary, "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: ")); free(summary); tdb_close(tdb); } return exit_status(); } ldb-2.0.8/lib/tdb/test/run-transaction-expand.c0000660000000000000000000000605112406075657021302 0ustar rootroot00000000000000#include "../common/tdb_private.h" /* Speed up the tests, but do the actual sync tests. */ static unsigned int sync_counts = 0; static inline int fake_fsync(int fd) { sync_counts++; return 0; } #define fsync fake_fsync #ifdef MS_SYNC static inline int fake_msync(void *addr, size_t length, int flags) { sync_counts++; return 0; } #define msync fake_msync #endif #ifdef HAVE_FDATASYNC static inline int fake_fdatasync(int fd) { sync_counts++; return 0; } #define fdatasync fake_fdatasync #endif #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static void write_record(struct tdb_context *tdb, size_t extra_len, TDB_DATA *data) { TDB_DATA key; key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data->dsize += extra_len; tdb_transaction_start(tdb); tdb_store(tdb, key, *data, TDB_REPLACE); tdb_transaction_commit(tdb); } int main(int argc, char *argv[]) { struct tdb_context *tdb; size_t i; TDB_DATA data; struct tdb_record rec; tdb_off_t off; /* Do *not* suppress sync for this test; we do it ourselves. */ unsetenv("TDB_NO_FSYNC"); plan_tests(5); tdb = tdb_open_ex("run-transaction-expand.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); data.dsize = 0; data.dptr = calloc(1000, getpagesize()); if (data.dptr == NULL) { diag("Unable to allocate memory for data.dptr"); tdb_close(tdb); exit(1); } /* Simulate a slowly growing record. */ for (i = 0; i < 1000; i++) write_record(tdb, getpagesize(), &data); tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); diag("TDB size = %zu, recovery = %llu-%llu", (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); /* We should only be about 5 times larger than largest record. */ ok1(tdb->map_size < 6 * i * getpagesize()); tdb_close(tdb); tdb = tdb_open_ex("run-transaction-expand.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); data.dsize = 0; /* Simulate a slowly growing record, repacking to keep * recovery area at end. */ for (i = 0; i < 1000; i++) { write_record(tdb, getpagesize(), &data); if (i % 10 == 0) tdb_repack(tdb); } tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); diag("TDB size = %zu, recovery = %llu-%llu", (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); /* We should only be about 4 times larger than largest record. */ ok1(tdb->map_size < 5 * i * getpagesize()); /* We should have synchronized multiple times. */ ok1(sync_counts); tdb_close(tdb); free(data.dptr); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-traverse-chain.c0000660000000000000000000000421313573675413020413 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" static char keystr0[] = "x"; static TDB_DATA key0 = { .dptr = (uint8_t *)keystr0, .dsize = sizeof(keystr0) }; static char valuestr0[] = "y"; static TDB_DATA value0 = { .dptr = (uint8_t *)valuestr0, .dsize = sizeof(valuestr0) }; static char keystr1[] = "aaa"; static TDB_DATA key1 = { .dptr = (uint8_t *)keystr1, .dsize = sizeof(keystr1) }; static char valuestr1[] = "bbbbb"; static TDB_DATA value1 = { .dptr = (uint8_t *)valuestr1, .dsize = sizeof(valuestr1) }; static TDB_DATA *keys[] = { &key0, &key1 }; static TDB_DATA *values[] = { &value0, &value1 }; static bool tdb_data_same(TDB_DATA d1, TDB_DATA d2) { if (d1.dsize != d2.dsize) { return false; } return (memcmp(d1.dptr, d2.dptr, d1.dsize) == 0); } struct traverse_chain_state { size_t idx; bool ok; }; static int traverse_chain_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) { struct traverse_chain_state *state = private_data; state->ok &= tdb_data_same(key, *keys[state->idx]); state->ok &= tdb_data_same(data, *values[state->idx]); state->idx += 1; return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; struct traverse_chain_state state = { .ok = true }; int ret; plan_tests(4); tdb = tdb_open_ex( "traverse_chain.tdb", 1, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600, &taplogctx, NULL); ok1(tdb); /* add in reverse order, tdb_store adds to the front of the list */ ret = tdb_store(tdb, key1, value1, TDB_INSERT); ok1(ret == 0); ret = tdb_store(tdb, key0, value0, TDB_INSERT); ok1(ret == 0); ret = tdb_traverse_key_chain(tdb, key0, traverse_chain_fn, &state); ok1(ret == 2); ok1(state.ok); unlink(tdb_name(tdb)); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c0000660000000000000000000000456213126252766022265 0ustar rootroot00000000000000#include "lock-tracking.h" #include "../common/tdb_private.h" #define fcntl fcntl_with_lockcheck #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #undef fcntl_with_lockcheck #include #include #include "external-agent.h" #include "logging.h" static struct agent *agent; static bool correct_key(TDB_DATA key) { return key.dsize == strlen("hi") && memcmp(key.dptr, "hi", key.dsize) == 0; } static bool correct_data(TDB_DATA data) { return data.dsize == strlen("world") && memcmp(data.dptr, "world", data.dsize) == 0; } static int traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) { ok1(correct_key(key)); ok1(correct_data(data)); return 0; } int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(13); agent = prepare_external_agent(); tdb = tdb_open_ex("run-traverse-in-transaction.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); ok1(tdb_transaction_active(tdb) == 0); ok1(tdb_transaction_start(tdb) == 0); ok1(tdb_transaction_active(tdb) == 1); ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse(tdb, traverse, NULL); /* That should *not* release the transaction lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); tdb_traverse_read(tdb, traverse, NULL); /* That should *not* release the transaction lock! */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == WOULD_HAVE_BLOCKED); ok1(tdb_transaction_commit(tdb) == 0); ok1(tdb_transaction_active(tdb) == 0); /* Now we should be fine. */ ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) == SUCCESS); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c0000660000000000000000000000577212406075657020422 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); if (strstr(fmt, "hash")) (*count)++; } int main(int argc, char *argv[]) { struct tdb_context *tdb; unsigned int log_count; TDB_DATA d; struct tdb_logging_context log_ctx = { log_fn, &log_count }; plan_tests(28); /* Create with default hash. */ log_count = 0; tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); d.dptr = discard_const_p(uint8_t, "Hello"); d.dsize = 5; ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); tdb_close(tdb); /* Fail to open with different hash. */ tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_jenkins_hash); ok1(!tdb); ok1(log_count == 1); /* Create with different hash. */ log_count = 0; tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); tdb_close(tdb); /* Endian should be no problem. */ log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; /* Fail to open with old default hash. */ tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, &log_ctx, tdb_old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); /* It should open with jenkins hash if we don't specify. */ log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); log_count = 0; tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDONLY, 0, &log_ctx, NULL); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/run-zero-append.c0000660000000000000000000000201612406075657017721 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(4); tdb = tdb_open_ex(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); /* Tickle bug on appending zero length buffer to zero length buffer. */ key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dptr = discard_const_p(uint8_t, "world"); data.dsize = 0; ok1(tdb_append(tdb, key, data) == 0); ok1(tdb_append(tdb, key, data) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == 0); tdb_close(tdb); free(data.dptr); return exit_status(); } ldb-2.0.8/lib/tdb/test/run.c0000660000000000000000000000246412406075657015506 0ustar rootroot00000000000000#include "../common/tdb_private.h" #include "../common/io.c" #include "../common/tdb.c" #include "../common/lock.c" #include "../common/freelist.c" #include "../common/traverse.c" #include "../common/transaction.c" #include "../common/error.c" #include "../common/open.c" #include "../common/check.c" #include "../common/hash.c" #include "../common/mutex.c" #include "tap-interface.h" #include #include "logging.h" int main(int argc, char *argv[]) { struct tdb_context *tdb; TDB_DATA key, data; plan_tests(10); tdb = tdb_open_ex("run.tdb", 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); ok1(tdb); key.dsize = strlen("hi"); key.dptr = discard_const_p(uint8_t, "hi"); data.dsize = strlen("world"); data.dptr = discard_const_p(uint8_t, "world"); ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); ok1(tdb_error(tdb) == TDB_ERR_EXISTS); ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); data = tdb_fetch(tdb, key); ok1(data.dsize == strlen("world")); ok1(memcmp(data.dptr, "world", strlen("world")) == 0); free(data.dptr); key.dsize++; data = tdb_fetch(tdb, key); ok1(data.dptr == NULL); tdb_close(tdb); return exit_status(); } ldb-2.0.8/lib/tdb/test/rwlock-be.tdb0000660000000000000000000000127012406075657017110 0ustar rootroot00000000000000TDB file m&ƒgÅ/ldb-2.0.8/lib/tdb/test/rwlock-le.tdb0000660000000000000000000000127012406075657017122 0ustar rootroot00000000000000TDB file m&ƒgÅ/ldb-2.0.8/lib/tdb/test/sample_tdb.tdb0000660000000000000000000002000013573675413017327 0ustar rootroot00000000000000TDB file m&ƒQ­ å”¶×D¹v¸ÀthfæþÙ|ì #nY„¨™&rpc_server972.2147483647/1085706313786795392972.100/1085706313786795392972.106/1085706313786795392972.95/1085706313786795392972.101/1085706313786795392972.113/1085706313786795392972.113/1085706313786795392€d #a¡]5fæþÙldap_server972.2147483650/1085706313786795392972.108/1085706313786795392|¨ ’nY„¨fæþÙrpc_server972.2147483647/1085706313786795392972.100/1085706313786795392972.106/1085706313786795392972.95/1085706313786795392972.101/1085706313786795392À4òoý™¬ify-daemon992/6389638235474936598L8ß%È™&winbind_server977/12826542715097898407P´à#h¬·cfæþÙdnssrv972.2147483658/1085706313786795392P< #{Ö­•™&dnsupdate972.2147483657/1085706313786795392¤8#E0]™&kccsrv972.2147483656/1085706313786795392ô< #ùcX™&dreplsrv972.2147483653/1085706313786795392H@ #Zž„8™&kdc_server972.2147483652/1085706313786795392 @ #>s™&cldap_server972.2147483651/1085706313786795392øh˜ #a¡]5fæþÙldap_server972.2147483650/1085706313786795392X@ #\yÀ™&wrepl_server972.2147483649/1085706313786795392°@ #^¬Â™&nbt_server972.2147483648/1085706313786795392X8@ #2óáÀfæþÙwins_server972.2147483648/1085706313786795392X¸€ #nY„¨fæþÙrpc_server972.2147483647/1085706313786795392X(B:0R™&samba0/1085706313786795392˜ldb-2.0.8/lib/tdb/test/tap-interface.h0000660000000000000000000000334612406075657017431 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Simplistic implementation of tap interface. Copyright (C) Rusty Russell 2012 ** NOTE! The following LGPL license applies to the talloc ** 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 . */ #include #ifndef __location__ #define __TAP_STRING_LINE1__(s) #s #define __TAP_STRING_LINE2__(s) __TAP_STRING_LINE1__(s) #define __TAP_STRING_LINE3__ __TAP_STRING_LINE2__(__LINE__) #define __location__ __FILE__ ":" __TAP_STRING_LINE3__ #endif #define plan_tests(num) #define fail(...) do { \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ fflush(stderr); \ exit(1); \ } while(0) #define diag(...) do { \ fprintf(stdout, __VA_ARGS__); \ fprintf(stdout, "\n"); \ fflush(stdout); \ } while(0) #define pass(...) do { \ fprintf(stdout, "."); \ fflush(stdout); \ } while(0) #define ok(e, ...) do { \ if (e) { \ pass(); \ } else { \ fail(__VA_ARGS__); \ } \ } while(0) #define ok1(e) ok((e), "%s:%s", __location__, #e) #define skip(n, ...) diag(__VA_ARGS__) #define exit_status() 0 ldb-2.0.8/lib/tdb/test/tap-to-subunit.h0000660000000000000000000001226612406075657017603 0ustar rootroot00000000000000#ifndef TAP_TO_SUBUNIT_H #define TAP_TO_SUBUNIT_H /* * tap-style wrapper for subunit. * * Copyright (c) 2011 Rusty Russell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "replace.h" /** * plan_tests - announce the number of tests you plan to run * @tests: the number of tests * * This should be the first call in your test program: it allows tracing * of failures which mean that not all tests are run. * * If you don't know how many tests will actually be run, assume all of them * and use skip() if you don't actually run some tests. * * Example: * plan_tests(13); */ void plan_tests(unsigned int tests); /** * ok1 - Simple conditional test * @e: the expression which we expect to be true. * * This is the simplest kind of test: if the expression is true, the * test passes. The name of the test which is printed will simply be * file name, line number, and the expression itself. * * Example: * ok1(somefunc() == 1); */ # define ok1(e) ((e) ? \ _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) /** * ok - Conditional test with a name * @e: the expression which we expect to be true. * @...: the printf-style name of the test. * * If the expression is true, the test passes. The name of the test will be * the filename, line number, and the printf-style string. This can be clearer * than simply the expression itself. * * Example: * ok1(somefunc() == 1); * ok(somefunc() == 0, "Second somefunc() should fail"); */ # define ok(e, ...) ((e) ? \ _gen_result(1, __func__, __FILE__, __LINE__, \ __VA_ARGS__) : \ _gen_result(0, __func__, __FILE__, __LINE__, \ __VA_ARGS__)) /** * pass - Note that a test passed * @...: the printf-style name of the test. * * For complicated code paths, it can be easiest to simply call pass() in one * branch and fail() in another. * * Example: * int x = somefunc(); * if (x > 0) * pass("somefunc() returned a valid value"); * else * fail("somefunc() returned an invalid value"); */ # define pass(...) ok(1, __VA_ARGS__) /** * fail - Note that a test failed * @...: the printf-style name of the test. * * For complicated code paths, it can be easiest to simply call pass() in one * branch and fail() in another. */ # define fail(...) ok(0, __VA_ARGS__) unsigned int _gen_result(int, const char *, const char *, unsigned int, const char *, ...) PRINTF_ATTRIBUTE(5, 6); /** * diag - print a diagnostic message (use instead of printf/fprintf) * @fmt: the format of the printf-style message * * diag ensures that the output will not be considered to be a test * result by the TAP test harness. It will append '\n' for you. * * Example: * diag("Now running complex tests"); */ void diag(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); /** * skip - print a diagnostic message (use instead of printf/fprintf) * @n: number of tests you're skipping. * @fmt: the format of the reason you're skipping the tests. * * Sometimes tests cannot be run because the test system lacks some feature: * you should explicitly document that you're skipping tests using skip(). * * From the Test::More documentation: * If it's something the user might not be able to do, use SKIP. This * includes optional modules that aren't installed, running under an OS that * doesn't have some feature (like fork() or symlinks), or maybe you need an * Internet connection and one isn't available. * * Example: * #ifdef HAVE_SOME_FEATURE * ok1(somefunc()); * #else * skip(1, "Don't have SOME_FEATURE"); * #endif */ void skip(unsigned int n, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); /** * exit_status - the value that main should return. * * For maximum compatibility your test program should return a particular exit * code (ie. 0 if all tests were run, and every test which was expected to * succeed succeeded). * * Example: * exit(exit_status()); */ int exit_status(void); #endif /* CCAN_TAP_H */ ldb-2.0.8/lib/tdb/test/tdb.corrupt0000660000000000000000000057000012406075657016723 0ustar rootroot00000000000000TDB file m&ƒ„~‚Xd¸ø`}pŽÄI Hàâp€°P†À ðÍt} ´`Ã0g˜w€Ð ¸ƒ Ð'€ƒ`8(…{Ðü/ˆ’„Æ€|`Øà¾@ŒÁ\IÈ ’Ðp8Ü Å¸‹H(•DÈÀˆ€ŠH›0‚TË (€)äÊx¾€®à€ Ax_¬Ì;za@~ЀïüJ`’«Ði £¨,PL¬<Ø‘°^`„øöü%@·°~€ÍPܰŒ ñ$ɬótK\-è.Ä|¼‘4L&°j\„`Ñð‘(XÆP /4 Úp‡0n,G¼‚ð|€‘`ΰ…ÀÎÀº(iÈD0-¸ °Ë‡T,L?à¤ÌÎðƒà¹fæþÙBBBBBBBBBBBBBBBB,X<JìÄ™&IDMAP/GID2SID/10000045 1251822591/S-1-5-21-1834383793-1770918451-929701000-63064Bp¨LX=fJw¯™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63064 1251822591/10000045BpX=tO8™&IDMAP/GID2SID/10000044 1251824032/S-1-5-21-1834383793-1770918451-929701000-143659pt X> „lá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143659 1251824032/10000044pX=ž²«™&IDMAP/GID2SID/10000043 1243613530/S-1-5-21-1834383793-1770918451-929701000-112509pX>ß>î±™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112509 1243613530/10000043pX;È™&IDMAP/GID2SID/10000042 1251822591/S-1-5-21-1834383793-1770918451-929701000-1390BBpˆºX<9Îá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-1390 1251822591/10000042BBp5X<òx’™&IDMAP/GID2SID/10000041 1251258541/S-1-5-21-1834383793-1770918451-929701000-42600Bp`®X=^j1™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42600 1251258541/10000041Bp°&X<Ü™&IDMAP/GID2SID/10000040 1251822591/S-1-5-21-1834383793-1770918451-929701000-68419BpðvX=Š5T¹™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68419 1251822591/10000040BpX;í»úÚ™&IDMAP/GID2SID/10000039 1251822591/S-1-5-21-1834383793-1770918451-929701000-1406BBp€ÉX<A(„À™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-1406 1251822591/10000039BBpX=íå]N™&IDMAP/GID2SID/10000038 1251824032/S-1-5-21-1834383793-1770918451-929701000-154049p€¼X>ƒôxï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-154049 1251824032/10000038pÜX=íÁÁ™&IDMAP/GID2SID/10000037 1250795400/S-1-5-21-1834383793-1770918451-929701000-119283p¨ X>Ûö™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119283 1250795400/10000037pX<í9$5™&IDMAP/GID2SID/10000036 1251246539/S-1-5-21-1834383793-1770918451-929701000-42610Bp|$X= ¤J™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42610 1251246539/10000036BpX<íc‡¨™&IDMAP/GID2SID/10000035 1251822591/S-1-5-21-1834383793-1770918451-929701000-22077Bp¨X=’ÄÍG™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-22077 1251822591/10000035Bp\ X<íê™&IDMAP/GID2SID/10000034 1251823756/S-1-5-21-1834383793-1770918451-929701000-25222Bp°“X=¶˜Œ:™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-25222 1251823756/10000034BpX<í·M™&IDMAP/GID2SID/10000033 1251822591/S-1-5-21-1834383793-1770918451-929701000-65941BpèX=Ž6Í™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-65941 1251822591/10000033BpX=íá°™&IDMAP/GID2SID/10000032 1250723401/S-1-5-21-1834383793-1770918451-929701000-107777pð»X>·ÈÚà™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107777 1250723401/10000032pX<í v™&IDMAP/GID2SID/10000031 1251824032/S-1-5-21-1834383793-1770918451-929701000-79185Bpô X=>K&w™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79185 1251824032/10000031BpX<í5wé™&IDMAP/GID2SID/10000030 1251331835/S-1-5-21-1834383793-1770918451-929701000-22078Bp ”X=úô*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-22078 1251331835/10000030BpÐMX:=Õ•¾™&IDMAP/GID2SID/10000029 1251246539/S-1-5-21-1834383793-1770918451-929701000-513BBBp(ÒX;ÔÑ·j™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-513 1251246539/10000029BBBpømX<ÍySX™&IDMAP/UID2SID/10000050 1251258541/S-1-5-21-1834383793-1770918451-929701000-36003Bp OX=FÚY™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-36003 1251258541/10000050Bpü"X<=S¿™&IDMAP/GID2SID/10000026 1251246553/S-1-5-21-1834383793-1770918451-929701000-89152Bp©X=ºUØê™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-89152 1251246553/10000026Bp4=}"Œ™&IDMAP/GID2SID/10000025 1251246539/S-1-5-11BBBL%4u¼±†™&IDMAP/SID2GID/S-1-5-11 1251246539/10000025BBBLX:=§…ÿ™&IDMAP/GID2SID/10000024 1251246553/S-1-5-21-1834383793-1770918451-929701000-515BBBpìX;ÔÑw™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-515 1251246553/10000024BBBpX=CÕ ™&IDMAP/UID2SID/10000048 1250712333/S-1-5-21-1834383793-1770918451-929701000-119484pì:X>›hŽÌ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119484 1250712333/10000048pX=m8™&IDMAP/UID2SID/10000047 1250643921/S-1-5-21-1834383793-1770918451-929701000-119489p(X>›ØÅ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119489 1250643921/10000047pX=Áþú™&IDMAP/UID2SID/10000045 1250618989/S-1-5-21-1834383793-1770918451-929701000-119367pàÔX>ïÓÚ-™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119367 1250618989/10000045pX=?(U™&IDMAP/UID2SID/10000042 1250643920/S-1-5-21-1834383793-1770918451-929701000-119322pøTX>H™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119322 1250643920/10000042pX=m†Ó÷™&IDMAP/UID2SID/10000037 1250618989/S-1-5-21-1834383793-1770918451-929701000-119366pà±X>ï#ôÈ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119366 1251224062/10000037pX=mýQ™&IDMAP/UID2SID/10000034 1251224061/S-1-5-21-1834383793-1770918451-929701000-119469pHôX>›mÁþ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119469 1251224061/10000034pX=m‚&¬™&IDMAP/UID2SID/10000031 1250618998/S-1-5-21-1834383793-1770918451-929701000-119472p0ºX>Ó™™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119472 1250618998/10000031pX=½u h™&IDMAP/UID2SID/10000028 1245435540/S-1-5-21-1834383793-1770918451-929701000-143691p¼?X>s5ª™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143691 1245435540/10000028pX=½ó4™&IDMAP/UID2SID/10000025 1250643920/S-1-5-21-1834383793-1770918451-929701000-119332pÜàX>oÃã‹™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119332 1250643920/10000025pX=½q^™&IDMAP/UID2SID/10000022 1250714212/S-1-5-21-1834383793-1770918451-929701000-119305p0ÈX>ï2"™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119305 1250714212/10000022pX= eCØ™&IDMAP/UID2SID/10000019 1250884333/S-1-5-21-1834383793-1770918451-929701000-119473p8ÀX>ƒ€„™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119473 1250884333/10000019pX= ãl2™&IDMAP/UID2SID/10000016 1250815021/S-1-5-21-1834383793-1770918451-929701000-119397p :X>otP×™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119397 1250815021/10000016pX= a–Œ™&IDMAP/UID2SID/10000013 1250726048/S-1-5-21-1834383793-1770918451-929701000-119404pÉX>›¼T³™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119404 1250726048/10000013pX= ß¿æ™&IDMAP/UID2SID/10000010 1250717566/S-1-5-21-1834383793-1770918451-929701000-119329pŒ6X>ï] k™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119329 1250717566/10000010pX=]¨A/™&IDMAP/UID2SID/10000008 1250705448/S-1-5-21-1834383793-1770918451-929701000-119310pX>oøÇû™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119310 1250705448/10000008pX=]PÎü™&IDMAP/UID2SID/10000004 1250714212/S-1-5-21-1834383793-1770918451-929701000-119334pà‰X>o#±U™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119334 1250714212/10000004pX=]¤”ã™&IDMAP/UID2SID/10000002 1250886708/S-1-5-21-1834383793-1770918451-929701000-119303pT X>ïÒTG™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119303 1250886708/10000002p8Ý[’l™&IDMAP/GID2SID/10000007 1251246513/S-1-5-32-545BBBP8ݯXS™&IDMAP/GID2SID/10000005 1251246513/S-1-5-32-544BBBP(Ä8¥õcy™&IDMAP/SID2GID/S-1-5-32-544 1251246513/10000005BBBP8êƒV™&IDMAP/GID2SID/10000013 1243558577/S-1-5-32-546BBBP@“8Ã-²™&IDMAP/SID2GID/S-1-5-32-545 1251246513/10000007BBBP0h­°™&IDMAP/GID2SID/10000010 1251246513/S-1-5-2HЧ0!ë›™&IDMAP/SID2GID/S-1-5-2 1251246513/10000010HÐb8 ïÿ’™&NBT/AD.VIACOM.COM#1C 1251229040/166.77.86.17:3891PPL+´jaµ™&NBT/BUBBLEBUDDY.PARAMOUNT.AD.VIACOM.COM#20 1251229216/166.77.172.94:0d0ÝÌ…™&IDMAP/GID2SID/10000009 1251246513/S-1-1-0HÈ0 Sq|™&IDMAP/SID2GID/S-1-1-0 1251246513/10000009H0Ý1/ù™&IDMAP/GID2SID/10000008 1251819747/S-1-0-0H4 0 SÅB™&IDMAP/SID2GID/S-1-0-0 1251819747/10000008HHæ$Z›;ö™&IDMAP/GID2SID/0 1251227602/-<¸}l>ïÞ[*™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119385 1250812305/10000029ch.ad.viacom.com-B„”$ÚN,™&IDMAP/UID2SID/0 1251228589/-B<¸ (™÷ ofæþÙSAF/DOMA$$—Lpã™&IDMAP/UID2SID/99 1251227602/-<Ê<(S¢f™&SAF/DOMAIN/IPT 1251229423/unitynyad02.ipt.viacom.comBT D"0(;™&NBT/UNITYNYAD02.IPT.VIACOM.COM#20 1251229040/172.21.200.28:0B\@"‘i_A™&AD_SITENAME/DOMAIN/IPT.VIACOM.COM 4294967295/IPT-US-NYCBBXH!#"ï¤ï™&AD_SITENAME/DOMAIN/AD.VIACOM.COM 4294967295/US-California-Burbank`@#þr²™&AD_SITENAME/DOMAIN/AD 4294967295/US-California-BurbankBBBX@cXó™&AD_SITENAME/DOMAIN/IPT 4294967295/IPT-US-NYC6:389,166.77.XLÍ-xÄ¡fæþÙSAF/DOMAIN/MTVN 1208ˆX=ræL™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-66812 1251824050/100000837px.X=¦r' ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79085 1251148458/10000066p /<ÆHÕ1™&NBT/VAD01.TAGWORLD.LOCAL#20 1251234381/10.64.0.101:0BThD!¯¸Ù™&NBT/MUSSELBEACH.AD.VIACOM.COM#20 1251229040/166.77.86.17:0BBB\Є@ Þ¼R™&NBT/NETDEV.VIACOM.COM#1C 1251229222/166.77.173.156:389m.cX_T".±Àv`™&SAF/DOMAIN/MTVNASIA.AD.VIACOM.COM 1251229469/SQUILLIAM.mtvnasia.ad.viacom.comlP&#hK™&AD_SITENAME/DOMAIN/MTVN.AD.VIACOM.COM 4294967295/US-California-BurbankBBBh@#HZrj™&AD_SITENAME/DOMAIN/MTVN 4294967295/US-California-BurbankBXè.H#Wo™&NBT/BILLYBOB.MTVN.AD.VIACOM.COM#20 1251217243/172.23.128.101:0BBB`tD!½týŸ™&NBT/MRSTAR.MTVN.AD.VIACOM.COM#20 1251217243/166.77.86.16:0BBB\(ÙD!yOé™&NBT/ALPUSS.MTVN.AD.VIACOM.COM#20 1251217243/166.77.80.155:0BB\XôD ‘ePó™&NBT/HOSTING.AD.VIACOM.COM#1C 1251229244/166.77.173.152:3893.1\²X3RÖl™™&NBT/PLAYASUR.AD.VIACOM.COM#1C 1251229229/166.77.172.111:389,166.77.172.128:389BBp|X>Ã_g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119272 1243615575/10000056pX=]Î÷V™&IDMAP/UID2SID/10000001 1250618991/S-1-5-21-1834383793-1770918451-929701000-119378p¨êX>o¹èu™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119378 1250618991/10000001p¤ X=½Å$™&IDMAP/UID2SID/10000020 1250712333/S-1-5-21-1834383793-1770918451-929701000-119389pÈÆX>ïžö½™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119389 1250712333/10000020p\;X=m\p„™&IDMAP/UID2SID/10000038 1250705447/S-1-5-21-1834383793-1770918451-929701000-119479pÐÃX>£èá™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119479 1250705447/10000038pX=½›Á™&IDMAP/UID2SID/10000021 1250643921/S-1-5-21-1834383793-1770918451-929701000-119357p%X>ož³J™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119357 1250643921/10000021pX=m2 ™&IDMAP/UID2SID/10000039 1250891274/S-1-5-21-1834383793-1770918451-929701000-119324pÅX>ïí‰r™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119324 1250891274/10000039pàRX= 73™&IDMAP/UID2SID/10000014 1250886708/S-1-5-21-1834383793-1770918451-929701000-119313p@¡X>o|*™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119313 1250886708/10000014pX=r-™&IDMAP/UID2SID/10000049 1250643921/S-1-5-21-1834383793-1770918451-929701000-119381pØX>ïÁ–™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119381 1250643921/10000049päX=m¬‰™&IDMAP/UID2SID/10000030 1250717565/S-1-5-21-1834383793-1770918451-929701000-119327p¸HX>ïý=¡™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119327 1250717565/10000030pX=i‹È™&IDMAP/UID2SID/10000041 1250624364/S-1-5-21-1834383793-1770918451-929701000-119307p¨SX>ï’ïÚ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119307 1250624364/10000041p@WX=]~Þ»™&IDMAP/UID2SID/10000009 1250898946/S-1-5-21-1834383793-1770918451-929701000-119314pp¸X>o¸b™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119314 1250898946/10000009pX=m.`Å™&IDMAP/UID2SID/10000033 1250643921/S-1-5-21-1834383793-1770918451-929701000-119490pˆÝX>Þ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119490 1250643921/10000033pX=ëan™&IDMAP/UID2SID/10000044 1250705447/S-1-5-21-1834383793-1770918451-929701000-119319p|ñX>o(䇙&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119319 1250705447/10000044pX<]ã©™&IDMAP/GID2SID/10000084 1251822594/S-1-5-21-1834383793-1770918451-929701000-58035BpŒ=X=âzöÒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-58035 1251822594/10000084BpX=]9F™&IDMAP/GID2SID/10000083 1251823992/S-1-5-21-1834383793-1770918451-929701000-113650p,@X> Tj™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113650 1251823992/10000083pX=]c©™&IDMAP/GID2SID/10000082 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25493p ­X>b2?ã™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25493 1251822594/10000082pX=] ™&IDMAP/GID2SID/10000081 1251823992/S-1-5-21-2140803266-1626024873-1299147156-29643pø&X>:š-·™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-29643 1251823992/10000081p€\X=]·ow™&IDMAP/GID2SID/10000080 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25491p ¿X>bÒq™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25491 1251822594/10000080pX<­VŽL™&IDMAP/GID2SID/10000079 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1158BpŒDX=O­á<™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1158 1251822594/10000079BpX=­€ñ¿™&IDMAP/GID2SID/10000078 1251822594/S-1-5-21-2140803266-1626024873-1299147156-24252pÌX> 9)™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24252 1251822594/10000078pX=­ªT3™&IDMAP/GID2SID/10000077 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31647pè<X=Šœß1™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56613 1251332444/10000092pX=­Ô·¦™&IDMAP/GID2SID/10000076 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25443pˆ.X>:Z3.™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31647 1251822594/10000077pX=­þ™&IDMAP/GID2SID/10000075 1251822594/S-1-5-21-2140803266-1626024873-1299147156-24253pkX> é{™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24253 1251822594/10000075pX=­(~™&IDMAP/GID2SID/10000074 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31834p•X>ˆŠ*™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31834 1251822594/10000074pX=­Rá™&IDMAP/GID2SID/10000073 1251822594/S-1-5-21-2140803266-1626024873-1299147156-21662p˜X>:U•­™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-21662 1251822594/10000073pX<­|Dt™&IDMAP/GID2SID/10000072 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7612Bp˜~X=Ÿ…ó¦™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7612 1251822594/10000072BpüX=­¦§ç™&IDMAP/GID2SID/10000071 1251823992/S-1-5-21-2140803266-1626024873-1299147156-29588ph­X>ަ25™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-29588 1251823992/10000071p$X=­Ð [™&IDMAP/GID2SID/10000070 1251822593/S-1-5-21-2140803266-1626024873-1299147156-18854p$ÂX>ó¢ñ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-18854 1251822593/10000070p¼X=ýo)0™&IDMAP/GID2SID/10000069 1248309549/S-1-5-21-2140803266-1626024873-1299147156-33933pXÛX>¾}g™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-33933 1248309549/10000069pâP. -™&SAF/DOMAIN/HOSTING 1251229484/misstuftsy.hosting.ad.viacom.com.77.172.128h †T3áS«™&NBT/MTVNE.AD.VIACOM.COM#1C 1251229229/166.77.172.124:389,166.77.172.123:389BBlðUT-#°ømâ™&AD_SITENAME/DOMAIN/VIACOM_CORP.AD.VIACOM.COM 4294967295/US-California-Burbankl@PH#jËÂ&™&AD_SITENAME/DOMAIN/VIACOM_CORP 4294967295/US-California-BurbankBB`°W`1)¨™ ™&SAF/DOMAIN/PARAMOUNT 1251229469/bubblebuddy.paramount.ad.viacom.com.COM#20 1247397223/1x0‰T!.ÒrX?™&SAF/DOMAIN/HOSTING.AD.VIACOM.COM 1251229484/misstuftsy.hosting.ad.viacom.comBlHÃX<ý™Œ£™&IDMAP/GID2SID/10000068 1251822591/S-1-5-21-1834383793-1770918451-929701000-75573Bp0[X=’¦’¥™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-75573 1251822591/10000068BpX<ýÃï™&IDMAP/GID2SID/10000067 1251822591/S-1-5-21-1834383793-1770918451-929701000-85165BpX=æ/»a™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-85165 1251822591/10000067BpX=ýíRŠ™&IDMAP/GID2SID/10000066 1251246539/S-1-5-21-1834383793-1770918451-929701000-119942p0—X>+A6™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119942 1251246539/10000066p¼X=ý¶ý™&IDMAP/GID2SID/10000065 1251822591/S-1-5-21-1834383793-1770918451-929701000-100732p X>·‚¾™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-100732 1251822591/10000065pX<ýAq™&IDMAP/GID2SID/10000064 1251823775/S-1-5-21-1834383793-1770918451-929701000-43457BpØ|X=:m"™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43457 1251823775/10000064BpX<ýk|ä™&IDMAP/GID2SID/10000063 1251822591/S-1-5-21-1834383793-1770918451-929701000-64119Bp ÁX=Š5ˆ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64119 1251822591/10000063BpœX<ý•ßW™&IDMAP/GID2SID/10000062 1251822591/S-1-5-21-1834383793-1770918451-929701000-64117Bp(&X=ŠÊ9Q™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64117 1251822591/10000062BpX<ý¿BË™&IDMAP/GID2SID/10000061 1251822591/S-1-5-21-1834383793-1770918451-929701000-43582Bp_X=¾¢T•™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43582 1251822591/10000061BpX=ýé¥>™&IDMAP/GID2SID/10000060 1251823334/S-1-5-21-1834383793-1770918451-929701000-136294pè'X>[Ør™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136294 1251823334/10000060pX=M‰Ä™&IDMAP/GID2SID/10000059 1251822591/S-1-5-21-1834383793-1770918451-929701000-103603pè©X>‹X”Ú™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-103603 1251822591/10000059pX=M³'‡™&IDMAP/GID2SID/10000058 1251822591/S-1-5-21-1834383793-1770918451-929701000-133857ph×X>c—f×™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-133857 1251822591/10000058pœX=MÝŠú™&IDMAP/GID2SID/10000057 1243613530/S-1-5-21-1834383793-1770918451-929701000-112480pX>3ò7™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112480 1243613530/10000057pì*X=Mîm™&IDMAP/GID2SID/10000056 1251824032/S-1-5-21-1834383793-1770918451-929701000-141499p0MX>³æÅ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-141499 1251824032/10000056pX=M1Qá™&IDMAP/GID2SID/10000055 1251824032/S-1-5-21-1834383793-1770918451-929701000-140543p(^X>ßô£1™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140543 1251824032/10000055pß~S™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112505 1243613530/10000053pX=M¯z;™&IDMAP/GID2SID/10000052 1251822591/S-1-5-21-1834383793-1770918451-929701000-129742pXœX>7¸yv™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129742 1251822591/10000052pX<MÙÝ®™&IDMAP/GID2SID/10000051 1251822591/S-1-5-21-1834383793-1770918451-929701000-68189Bp·X=>Éä‚™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68189 1251822591/10000051BpX=MA"™&IDMAP/GID2SID/10000050 1251823334/S-1-5-21-1834383793-1770918451-929701000-136393p¬CX> ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136393 1251823334/10000050p\X<¢_÷™&IDMAP/GID2SID/10000049 1251822591/S-1-5-21-1834383793-1770918451-929701000-63066Bp£X=fµÅu™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63066 1251822591/10000049BpX<ÌÂj™&IDMAP/GID2SID/10000048 1251822591/S-1-5-21-1834383793-1770918451-929701000-63067Bp X=æêìX™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63067 1251822591/10000048BpX=ö%Þ™&IDMAP/GID2SID/10000047 1251824032/S-1-5-21-1834383793-1770918451-929701000-101189päÃX>/ø’™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-101189 1251824032/10000047pX= ‰Q™&IDMAP/GID2SID/10000046 1251823334/S-1-5-21-1834383793-1770918451-929701000-120736p8X>·Bî™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-120736 1251823334/10000046pÌ(fæþÙBBBBBBBBBBBBBBBBBBBB0ÄÄX=Ò1 ª™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-56596 1251823756/10000415BpX==O’™&IDMAP/GID2SID/10000120 1251822591/S-1-5-21-1834383793-1770918451-929701000-139639p´%X> óœ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-139639 1251822591/10000120p|X=î°×™&IDMAP/GID2SID/10000119 1251822591/S-1-5-21-1834383793-1770918451-929701000-126385p”X>‡·E­™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126385 1251822591/10000119pX=K™&IDMAP/GID2SID/10000118 1251822591/S-1-5-21-1834383793-1770918451-929701000-116156pÀ X>¯S ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116156 1251822591/10000118pp‰X=Bw¾™&IDMAP/GID2SID/10000117 1251822591/S-1-5-21-1834383793-1770918451-929701000-117588pÈYX>ß:!i™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-117588 1251822591/10000117p„X=lÚ1™&IDMAP/GID2SID/10000116 1251822591/S-1-5-21-1834383793-1770918451-929701000-126396pžX>Sõ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126396 1251822591/10000116pX=–=¥™&IDMAP/GID2SID/10000115 1251822591/S-1-5-21-1834383793-1770918451-929701000-159265p —X>Û?3™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-159265 1251822591/10000115pX<À ™&IDMAP/GID2SID/10000114 1251822591/S-1-5-21-1834383793-1770918451-929701000-90602BphšX=^ê:™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90602 1251822591/10000114BpX=ꌙ&IDMAP/GID2SID/10000113 1251822591/S-1-5-21-1834383793-1770918451-929701000-126429phgX>3põ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126429 1251822591/10000113pX=gÿ™&IDMAP/GID2SID/10000112 1251822591/S-1-5-21-1834383793-1770918451-929701000-122069pèÓX>ƒ_Æ/™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122069 1251822591/10000112pX=>Êr™&IDMAP/GID2SID/10000111 1251822591/S-1-5-21-1834383793-1770918451-929701000-122067px›X>ƒÿøe™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122067 1251822591/10000111pX<h-æ™&IDMAP/GID2SID/10000110 1251822591/S-1-5-21-1834383793-1770918451-929701000-43400Bp¨ÎX=^jÜÈ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43400 1251822591/10000110BpsX<ÝL»™&IDMAP/GID2SID/10000109 1251822591/S-1-5-21-1834383793-1770918451-929701000-64115Bp`ÊX=Š_늙&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64115 1251822591/10000109BpX=Ý1¯.™&IDMAP/GID2SID/10000108 1251822591/S-1-5-21-1834383793-1770918451-929701000-116427p˜ÒX>3ÖÜ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116427 1251822591/10000108pÜ0X<Ý[¢™&IDMAP/GID2SID/10000107 1251822591/S-1-5-21-1834383793-1770918451-929701000-64114BpÈX= *ħ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64114 1251822591/10000107BpX<Ý…u™&IDMAP/GID2SID/10000106 1251822591/S-1-5-21-1834383793-1770918451-929701000-93011Bp0X=Š‘Ýy™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-93011 1251822591/10000106BpX<ݯ؈™&IDMAP/GID2SID/10000105 1251822591/S-1-5-21-1834383793-1770918451-929701000-64116BppªX= •n™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64116 1251822591/10000105BpX=ÝÙ;ü™&IDMAP/GID2SID/10000104 1251822591/S-1-5-21-1834383793-1770918451-929701000-114928p ÈX>àzÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-114928 1251822591/10000104p”*X<ÝŸo™&IDMAP/GID2SID/10000103 1251822591/S-1-5-21-1834383793-1770918451-929701000-31602BpðÂX=^}¡Z™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-31602 1251822591/10000103BpX=Ý-ã™&IDMAP/GID2SID/10000102 1251822591/S-1-5-21-1834383793-1770918451-929701000-157066pˆ8X>ƒO3ï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-157066 1251822591/10000102pX<Í):½™&IDMAP/UID2SID/10000058 1251822591/S-1-5-21-1834383793-1770918451-929701000-48064Bph+X=ÎÁ6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-48064 1251822591/10000058Bp=X=m°6k™&IDMAP/UID2SID/10000036 1250712333/S-1-5-21-1834383793-1770918451-929701000-119393p,X>o´µC™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119393 1250712333/10000036pX=]z1p™&IDMAP/UID2SID/10000003 1250705447/S-1-5-21-1834383793-1770918451-929701000-119309p ÌX>ïò¼¤™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119309 1250705447/10000003pÜEX=½ÉÑN™&IDMAP/UID2SID/10000026 1250705448/S-1-5-21-1834383793-1770918451-929701000-119488pèýX>›()`™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119488 1250705448/10000026p4*X=—›‡™&IDMAP/UID2SID/10000046 1250878940/S-1-5-21-1834383793-1770918451-929701000-129585pø{X>GRù†™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129585 1250878940/10000046pX=ÝÈÉ™&IDMAP/GID2SID/10000100 1251822591/S-1-5-21-1834383793-1770918451-929701000-112481pTX>31Ùœ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112481 1251822591/10000100pRX= Ð¥™&IDMAP/UID2SID/10000015 1250712334/S-1-5-21-1834383793-1770918451-929701000-119386p@@X>ïŽB™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119386 1250712334/10000015p`OX= ¦K™&IDMAP/UID2SID/10000018 1250718766/S-1-5-21-1834383793-1770918451-929701000-119388pÐX>ïîY™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119388 1250718766/10000018p@^X=mXÃ8™&IDMAP/UID2SID/10000032 1245283320/S-1-5-21-1834383793-1770918451-929701000-119485p`iX>›u1™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119485 1245283320/10000032pÀSX=mÚ™Þ™&IDMAP/UID2SID/10000035 1250643921/S-1-5-21-1834383793-1770918451-929701000-119304pX>ï‚;¬™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119304 1250643921/10000035pÌBX<؂ϙ&NBT/TAGWORLD.LOCAL#1C 1251233900/10.64.99.4:389,10.64.0.101:389,10.64.0.102:389BBp<<8"¹],™&AD_SITENAME/DOMAIN/DMZ.VIACOM.COM 4294967295/DMZBP$,SWVÞ™&AD_SITENAME/DOMAIN/DMZ 4294967295/DMZD@à4£®™&TDOMCACHE/TIMESTAMP 1250653195/1250652595.netLÚX=¢Ÿ91™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95251 1250615979/10000348p€hH%åµT™&NBT/NETQAROOTDC1.NETQA.VIACOM.COM#20 1249211682/166.77.173.159:0B`@$´·†™&AD_SITENAME/DOMAIN/NETQA.VIACOM.COM 4294967295/NETQA-NYCBX4öþ™&AD_SITENAME/DOMAIN/NETQA 4294967295/NETQA-NYCL¤<'.*¯þ™&SAF/DOMAIN/AD 1251229419/musselbeach.ad.viacom.com89Tx–Dévu ™&NBT/BEAVIS.DMZ.VIACOM.COM#20 1245379451/166.77.8.196:0m.comB\ªL'Ī1Ê™&NBT/NETDEVROOTDC1.NETDEV.VIACOM.COM#20 1251229217/166.77.173.156:0BBBd°ŽD%áwœ3™&AD_SITENAME/DOMAIN/NETDEV.VIACOM.COM 4294967295/NETDEV-NYCBBB\Ð84g‚™&AD_SITENAME/DOMAIN/NETDEV 4294967295/NETDEV-NYCBBPP@ÆHÕ1fæþÙNBT/VAD01.TAGWORLD.LOCAL#20 1251228864/10.64.0.101:09BBBXð T)#‡ß‘™&AD_SITENAME/DOMAIN/HOSTING.AD.VIACOM.COM 4294967295/US-California-BurbankomBl,)L)f¬*™&NBT/MRSSTAR.VIACOM_CORP.AD.VIACOM.COM#20 1251229216/166.77.86.15:0dÀH.dO´Ž™&SAF/DOMAIN/MTVNASIA 1251229469/SQUILLIAM.mtvnasia.ad.viacom.comBB`›<ÆH@€™&NBT/VAD02.TAGWORLD.LOCAL#20 1250525385/10.64.0.102:0BTX#í¼K÷™&AD_SITENAME/DOMAIN/PLAYASUR 4294967295/US-California-Burbankmount.ad.viacom.comBpL‘L'hØb™&NBT/PERCHPERKINS.MTVN.AD.VIACOM.COM#20 1251234357/166.77.123.16:04:0dÌëL*ãH7y™&NBT/HASSELHOFF.PARAMOUNT.AD.VIACOM.COM#20 1249211622/166.77.172.108:0dDP#U³¦™&AD_SITENAME/DOMAIN/HOSTING 4294967295/US-California-Burbankd.viacom.comBhxjD,äï²#™&SAF/DOMAIN/PLAYASUR 1251229469/pancton.playasur.ad.viacom.com\ yH&û¯ÈÍ™&NBT/NEW-BRDC02.MTVNE.AD.VIACOM.COM#20 1244242447/166.77.172.124:0`±T&;Œ™&NBT/PANCTON.PLAYASUR.AD.VIACOM.COM#20 1251229216/166.77.172.128:0om.com.comlòH" —ÐÆ™&NBT/LOU.MTVNASIA.AD.VIACOM.COM#20 1249211618/166.77.172.115:0mBB` L(™÷ o™&SAF/DOMAIN/IPT.VIACOM.COM 1251229423/unitynyad02.ipt.viacom.com0:0BBdDX*#÷¿(™&AD_SITENAME/DOMAIN/PLAYASUR.AD.VIACOM.COM 4294967295/US-California-Burbankom.comp €L1åpT™&NBT/IPT.VIACOM.COM#1C 1251229043/172.21.200.28:389,172.21.200.27:389BdàBP,LÙÏØ™&NBT/KANGREBURGUER.PLAYASUR.AD.VIACOM.COM#20 1249211617/166.77.172.111:0BBhXr@‰à%Y™&NBT/BUTTHEAD.DMZ.VIACOM.COM#20 1251234328/166.77.8.197:0BXœJX= ¹ ¿™&IDMAP/UID2SID/10000017 1250712327/S-1-5-21-1834383793-1770918451-929701000-119365p X>ïs d™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119365 1250712327/10000017p¼8X=“î;™&IDMAP/UID2SID/10000040 1250878940/S-1-5-21-1834383793-1770918451-929701000-119391pð…X>oTèy™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119391 1250878940/10000040pœGX=½˜5™&IDMAP/UID2SID/10000024 1250705447/S-1-5-21-1834383793-1770918451-929701000-119377pˆùX>o ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119377 1250705447/10000024pX=]øZÊ™&IDMAP/UID2SID/10000000 1250714213/S-1-5-21-1834383793-1770918451-929701000-119487pðåX>›xBû™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119487 1250714213/10000000pX=½K¨ô™&IDMAP/UID2SID/10000029 1250812305/S-1-5-21-1834383793-1770918451-929701000-119385pX= µ\s™&IDMAP/UID2SID/10000011 1250643921/S-1-5-21-1834383793-1770918451-929701000-119308pÄX>ïBÖ?™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119308 1250643921/10000011pàYX=]ü™&IDMAP/UID2SID/10000006 1250712334/S-1-5-21-1834383793-1770918451-929701000-129609pè5X>óŸs™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129609 1250712334/10000006pÀLX=Åá™&IDMAP/UID2SID/10000043 1250809544/S-1-5-21-1834383793-1770918451-929701000-119470p0žX>sÌU™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119470 1250809544/10000043pÀZX=]&k‰™&IDMAP/UID2SID/10000005 1250900348/S-1-5-21-1834383793-1770918451-929701000-119371pH3X>o陳™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119371 1250900348/10000005pÄ X= ‹ùÿ™&IDMAP/UID2SID/10000012 1250715320/S-1-5-21-1834383793-1770918451-929701000-119480pmX>›¨ó8™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119480 1250715320/10000012pð(X=½Gû¨™&IDMAP/UID2SID/10000023 1250712327/S-1-5-21-1834383793-1770918451-929701000-119475pdX>ãMN™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119475 1250712327/10000023pYX=]Ò¤¢™&IDMAP/UID2SID/10000007 1250712327/S-1-5-21-1834383793-1770918451-929701000-119368p(X>ïƒÁ’™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119368 1250712327/10000007pX=Í}¤™&IDMAP/UID2SID/10000056 1243615575/S-1-5-21-1834383793-1770918451-929701000-119272pȸt",1auõ™&SAF/DOMAIN/PLAYASUR.AD.VIACOM.COM 1251229469/pancton.playasur.ad.viacom.com 1251222444/166.77.173.152:3892.1Œ\4P'#;6\A™&AD_SITENAME/DOMAIN/MTVNE.AD.VIACOM.COM 4294967295/US-California-Burbank89h˜œ@#mæPž™&AD_SITENAME/DOMAIN/MTVNE 4294967295/US-California-BurbankXÐ}X/ƒ€™&SAF/DOMAIN/VIACOM_CORP 1251229458/mrsstar.viacom_corp.ad.viacom.com123:3898989p\L/ãÐÏñ™&NBT/DMZ.VIACOM.COM#1C 1251234328/166.77.8.196:389,166.77.8.197:389hd‘P-›Ph ™&SAF/DOMAIN/NETDEV.VIACOM.COM 1251229765/NETDEVROOTDC1.netdev.viacom.commhHÐX-í2àŒ™&SAF/DOMAIN/MTVN.AD.VIACOM.COM 1251234708/perchperkins.mtvn.ad.viacom.com01:389BBpüX= öGÆ™&IDMAP/GID2SID/10000094 1251309681/S-1-5-21-1834383793-1770918451-929701000-128556pˆ™X>_:©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128556 1251309681/10000094pÀtX< J­™&IDMAP/GID2SID/10000092 1251332444/S-1-5-21-1834383793-1770918451-929701000-56613Bp¨0X>â&{s™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25443 1251822594/10000076pxX=ýA™¦™&IDMAP/GID2SID/10000164 1251824032/S-1-5-21-1834383793-1770918451-929701000-129541pðaX>ß”`™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129541 1251824032/10000164pàsX<ýkü™&IDMAP/GID2SID/10000163 1250878940/S-1-5-21-1834383793-1770918451-929701000-79173BpX=’¦¾©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79173 1250878940/10000163Bp|:X< žÔ“™&IDMAP/GID2SID/10000090 1250872206/S-1-5-21-1834383793-1770918451-929701000-48068Bp X=fpD_™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-48068 1250872206/10000090Bp¼FX<ý•_™&IDMAP/GID2SID/10000162 1250868523/S-1-5-21-1834383793-1770918451-929701000-52245BpàªX=Ž´Mž™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-52245 1250868523/10000162BpX=]=óh™&IDMAP/GID2SID/10000089 1251309681/S-1-5-21-1834383793-1770918451-929701000-107847p`MX>ãa~>™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107847 1251309681/10000089pX=]‘¹O™&IDMAP/GID2SID/10000087 1251309681/S-1-5-21-1834383793-1770918451-929701000-129709pHØX>7²+¬™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129709 1251309681/10000087pX=]»Ù&IDMAP/GID2SID/10000086 1251309681/S-1-5-21-1834383793-1770918451-929701000-119269p`X>ÛÒ-™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119269 1251309681/10000086p@‡X<ý¿Â™&IDMAP/GID2SID/10000161 1250878940/S-1-5-21-1834383793-1770918451-929701000-48092BpÈKX=jܤ!™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-48092 1250878940/10000161BpX<ÍÿÖI™&IDMAP/UID2SID/10000059 1250878940/S-1-5-21-1834383793-1770918451-929701000-95300BpHûX=ÆIô÷™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95300 1250878940/10000059BpX=ÍS0™&IDMAP/UID2SID/10000057 1250784019/S-1-5-21-1834383793-1770918451-929701000-148285p°X>C¥#A™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148285 1250784019/10000057pX=½ŸnÛ™&IDMAP/UID2SID/10000027 1250705448/S-1-5-21-1834383793-1770918451-929701000-119380pöX>ïnÚ1™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119380 1250705448/10000027pX<M‰DI™&IDMAP/GID2SID/10000159 1250616246/S-1-5-21-1834383793-1770918451-929701000-66299BpÀ'X=ꈺ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-66299 1250616246/10000159Bp0JT8M³§¼™&IDMAP/GID2SID/10000158 1250616246/S-1-5-21-59184239-814559844-636688714-6119BlhcT9'v³Î™&IDMAP/SID2GID/S-1-5-21-59184239-814559844-636688714-6119 1250616246/10000158Bl MX<MÝ 0™&IDMAP/GID2SID/10000157 1250616246/S-1-5-21-1834383793-1770918451-929701000-66402Bpø—X=^…Rß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-66402 1250616246/10000157Bp€NX=Mn£™&IDMAP/GID2SID/10000156 1251822594/S-1-5-21-1834383793-1770918451-929701000-113647pPmX>‹î6I™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113647 1251822594/10000156p`wX<M1Ñ™&IDMAP/GID2SID/10000155 1251822594/S-1-5-21-1834383793-1770918451-929701000-90580BpX=¾ïà™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90580 1251822594/10000155Bp€…X=M[4Š™&IDMAP/GID2SID/10000154 1251822594/S-1-5-21-2140803266-1626024873-1299147156-15724pvX>æôØ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-15724 1251822594/10000154pX=M…—ý™&IDMAP/GID2SID/10000153 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20642pð\X>:êæ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20642 1251822594/10000153p€vX=M¯úp™&IDMAP/GID2SID/10000152 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20643pÔ X>:šÍ~™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20643 1251822594/10000152p X<MÙ]ä™&IDMAP/GID2SID/10000151 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1212BpôX=Ÿ…ñš™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1212 1251822594/10000151Bp€aX<MÁW™&IDMAP/GID2SID/10000150 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1677Bpˆ#X='ëÌj™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1677 1251822594/10000150Bp TX=¢ß,™&IDMAP/GID2SID/10000149 1251822594/S-1-5-21-2140803266-1626024873-1299147156-23995pÌX>¾²Ê5™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-23995 1251822594/10000149p€UX=ÌB ™&IDMAP/GID2SID/10000148 1251822594/S-1-5-21-2140803266-1626024873-1299147156-25492p€ÂX>b‚X~™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25492 1251822594/10000148p`VX=ö¥™&IDMAP/GID2SID/10000147 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31602pÖX>:©™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31602 1251822594/10000147p`†X< ‡™&IDMAP/GID2SID/10000146 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7613BpX=»Š™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7613 1251822594/10000146BppYX=Jlú™&IDMAP/GID2SID/10000145 1251822594/S-1-5-21-2140803266-1626024873-1299147156-34646p¸’X>:ªl1™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34646 1251822594/10000145pØ}X<tÏm™&IDMAP/GID2SID/10000144 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1209Bp°X=sÂêÉ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1209 1251822594/10000144BpX=ž2á™&IDMAP/GID2SID/10000143 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31603p`¯X>:Äû ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31603 1251822594/10000143pŒX<È•T™&IDMAP/GID2SID/10000142 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7654Bph“X=Oצ‰™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7654 1251822594/10000142Bp"X<òøÇ™&IDMAP/GID2SID/10000141 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7615Bp@¾X=&iP™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7615 1251822594/10000141Bp@jX=\;™&IDMAP/GID2SID/10000140 1251822594/S-1-5-21-2140803266-1626024873-1299147156-23175p`*X>^z²6™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-23175 1251822594/10000140p`]X=í»z™&IDMAP/GID2SID/10000139 1251822594/S-1-5-21-2106152344-1726899929-2013803672-40569pÐX>ª›=¼™&IDMAP/SID2GID/S-1-5-21-2106152344-1726899929-2013803672-40569 1251822594/10000139p@xX<íå݃™&IDMAP/GID2SID/10000138 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7653BpìAX=Ï¡¦™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7653 1251822594/10000138Bp<X=íA÷™&IDMAP/GID2SID/10000137 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20644p X>:J´ã™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20644 1251822594/10000137pü6X=í9¤j™&IDMAP/GID2SID/10000136 1251822594/S-1-5-21-2140803266-1626024873-1299147156-31606pH]X>:Ô¯<™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31606 1251822594/10000136pX=ícÞ™&IDMAP/GID2SID/10000135 1251822594/S-1-5-21-2140803266-1626024873-1299147156-20641pˆ?X>::µ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20641 1251822594/10000135p¤X=íjQ™&IDMAP/GID2SID/10000134 1251822594/S-1-5-21-2106152344-1726899929-2013803672-12000p‚X>N 7i™&IDMAP/SID2GID/S-1-5-21-2106152344-1726899929-2013803672-12000 1251822594/10000134pÈ-X<í·ÍÄ™&IDMAP/GID2SID/10000133 1251822591/S-1-5-21-4186143834-2626045635-1021053583-1683Bp(X=ÓNIå™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1683 1251822591/10000133BpX=íá08™&IDMAP/GID2SID/10000132 1251822591/S-1-5-21-1834383793-1770918451-929701000-129472pðoX>³«£ ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129472 1251822591/10000132pX=í ”«™&IDMAP/GID2SID/10000131 1251822591/S-1-5-21-1834383793-1770918451-929701000-116153p`½X>¯CeÝ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116153 1251822591/10000131p@'X=í5÷™&IDMAP/GID2SID/10000130 1251822591/S-1-5-21-1834383793-1770918451-929701000-111062pJX>ƒ¬Q™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-111062 1251822591/10000130p4~X<=Õô™&IDMAP/GID2SID/10000129 1251822591/S-1-5-21-1834383793-1770918451-929701000-75607Bp X=ÞèÞÍ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-75607 1251822591/10000129Bpä X<=ÿxg™&IDMAP/GID2SID/10000128 1251822591/S-1-5-21-1834383793-1770918451-929701000-64118Bph¦X= a4™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64118 1251822591/10000128Bp|3X==)ÜÚ™&IDMAP/GID2SID/10000127 1251822591/S-1-5-21-1834383793-1770918451-929701000-122070pXX>eц™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122070 1251822591/10000127p¼1X==S?N™&IDMAP/GID2SID/10000126 1251822591/S-1-5-21-1834383793-1770918451-929701000-122076pplX>…9ä™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122076 1251822591/10000126pX==}¢Á™&IDMAP/GID2SID/10000125 1251822591/S-1-5-21-1834383793-1770918451-929701000-126386pð¦X>‡g,™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126386 1251822591/10000125pd X<=§5™&IDMAP/GID2SID/10000124 1251822591/S-1-5-21-1834383793-1770918451-929701000-63065BpP¤X=æž’™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-63065 1251822591/10000124BpX==Ñh¨™&IDMAP/GID2SID/10000123 1251822591/S-1-5-21-1834383793-1770918451-929701000-126395pqX>íl™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126395 1251822591/10000123pÀzX<=ûË™&IDMAP/GID2SID/10000122 1251822591/S-1-5-21-1834383793-1770918451-929701000-52079Bp¨EX=’7v¥™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-52079 1251822591/10000122BpX<=%/™&IDMAP/GID2SID/10000121 1251822591/S-1-5-21-1834383793-1770918451-929701000-36648Bp` fæþÙBBBBBBBBBBBBBBBBBBBBBBBBBBBB8Œ"X>Çqˆ9™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107559 1250873479/10000288ph|X=ÝÌð™&IDMAP/UID2SID/10000287 1250873530/S-1-5-21-1834383793-1770918451-929701000-107728pX>Ÿ”^9™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107728 1250873530/10000287pØúX ‰K™&NBT/NETQA.VIACOM.COM#1C 1249211677/166.77.173.159:3890.101:389,10.64.0.102:389BBpxXX=Ý[’×™&IDMAP/UID2SID/10000285 1250521814/S-1-5-21-1834383793-1770918451-929701000-148213p˜PX>ÃÎCA™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148213 1250521814/10000285pèÅX=Ý…õJ™&IDMAP/UID2SID/10000284 1250521814/S-1-5-21-1834383793-1770918451-929701000-148250pÈôX>Ô,Ÿ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148250 1250521814/10000284p¬úX<ÍÿÖ´™&IDMAP/UID2SID/10000259 1251218400/S-1-5-21-1834383793-1770918451-929701000-79240BpHX=v€¾™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79240 1251218400/10000259BpX= a–÷™&IDMAP/UID2SID/10000213 1250606578/S-1-5-21-1834383793-1770918451-929701000-129760p@+X>Ÿê[Ö™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129760 1250606578/10000213pˆbX<Ý¥™&IDMAP/UID2SID/10000281 1247866677/S-1-5-21-1834383793-1770918451-929701000-14857Bp¸X=¢ _r™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-14857 1247866677/10000281Bp X;Ý-‚™&IDMAP/UID2SID/10000280 1251824050/S-1-5-21-1834383793-1770918451-929701000-1442BBp°½X<ùh=™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1442 1251824050/10000280BBphƒX=-Í í™&IDMAP/UID2SID/10000279 1247866321/S-1-5-21-1834383793-1770918451-929701000-163142p(…X>—…¯™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-163142 1247866321/10000279pˆäX=-!gÔ™&IDMAP/UID2SID/10000277 1250193793/S-1-5-21-1834383793-1770918451-929701000-129310pð>X>oø2J™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129310 1250193793/10000277p¸X=i þ™&IDMAP/UID2SID/10000141 1251215817/S-1-5-21-1834383793-1770918451-929701000-148074pè·X>kLãê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148074 1251215817/10000141p˜;X=}de+™&IDMAP/UID2SID/10000266 1250703920/S-1-5-21-1834383793-1770918451-929701000-107875pðìX>Ëɇ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107875 1250703920/10000266p¸]X=-Ésl™&IDMAP/UID2SID/10000173 1250875191/S-1-5-21-1834383793-1770918451-929701000-143675p°îX>sVw™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143675 1250875191/10000173pøÖX=}6Ul™&IDMAP/UID2SID/10000261 1251131452/S-1-5-21-1834383793-1770918451-929701000-107925p˜ŒX>÷÷Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107925 1251131452/10000261pø³X=}`¸ß™&IDMAP/UID2SID/10000260 1251131452/S-1-5-21-1834383793-1770918451-929701000-148486p€LX>›È<´™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148486 1251131452/10000260pºX=-:S™&IDMAP/UID2SID/10000171 1251132005/S-1-5-21-1834383793-1770918451-929701000-143717pQX>¯|õ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143717 1251132005/10000171pØÞX=r˜™&IDMAP/UID2SID/10000249 1251150711/S-1-5-21-1834383793-1770918451-929701000-148466pˆ¥X>›]îí™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148466 1251150711/10000249plX=Ý[¢™&IDMAP/UID2SID/10000185 1251218700/S-1-5-21-1834383793-1770918451-929701000-119280pp±X>C5Á*™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119280 1251218700/10000185p8ÕX=CÕ ™&IDMAP/UID2SID/10000248 1250611448/S-1-5-21-1834383793-1770918451-929701000-119202pP{X>CéTÛ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119202 1250611448/10000248p8˜X=m8™&IDMAP/UID2SID/10000247 1250611448/S-1-5-21-1834383793-1770918451-929701000-143665p0 X>ó Z”™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143665 1250611448/10000247p XX=½›AÅ™&IDMAP/UID2SID/10000121 1251215911/S-1-5-21-1834383793-1770918451-929701000-143824p¨eX>K ±™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143824 1251215911/10000121pP–X=½qÞQ™&IDMAP/UID2SID/10000122 1251149659/S-1-5-21-1834383793-1770918451-929701000-141231p`íX>ÃÙ$ ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141231 1251149659/10000122pØ9X=­€q`™&IDMAP/GID2SID/10000378 1251132374/S-1-5-21-1834383793-1770918451-929701000-129606p,9X>‹h^v™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129606 1251132374/10000378pØ2X=-ºˆ™&IDMAP/UID2SID/10000271 1251132374/S-1-5-21-1834383793-1770918451-929701000-148082pÈ!X>ë!=™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148082 1251132374/10000271pX=-Gü™&IDMAP/UID2SID/10000270 1250180739/S-1-5-21-1834383793-1770918451-929701000-148493pÌòX>î¯h™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148493 1250180739/10000270pHX=}`8ª™&IDMAP/UID2SID/10000160 1251246539/S-1-5-21-1834383793-1770918451-929701000-141061pðX>kœh™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119073 1251826461/10000269px¢X=-GÆ™&IDMAP/UID2SID/10000170 1250871957/S-1-5-21-1834383793-1770918451-929701000-141230p` X>Ã)>;™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141230 1250871957/10000170ph$X=}ŽÈž™&IDMAP/UID2SID/10000265 1251153462/S-1-5-21-1834383793-1770918451-929701000-107874p@GX>Ë¡™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107874 1251153462/10000265p8sX<­(þ-™&IDMAP/GID2SID/10000374 1250872602/S-1-5-21-1834383793-1770918451-929701000-43583BppœX=>Ø{x™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43583 1250872602/10000374Bp˜½X=­Ra¡™&IDMAP/GID2SID/10000373 1250872602/S-1-5-21-1834383793-1770918451-929701000-148143pˆX>/?€™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148143 1250872602/10000373p¸æX=­|Ä™&IDMAP/GID2SID/10000372 1250872602/S-1-5-21-1834383793-1770918451-929701000-129731pHVX>·Òk.™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129731 1250872602/10000372pØóX=­¦'ˆ™&IDMAP/GID2SID/10000371 1250872602/S-1-5-21-1834383793-1770918451-929701000-129603p8X>‹XªG™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129603 1250872602/10000371p`ßX<}⎅™&IDMAP/UID2SID/10000263 1251824050/S-1-5-21-1834383793-1770918451-929701000-17010BpÐÊX=rÃ( ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-17010 1251824050/10000263Bp8²X=} òø™&IDMAP/UID2SID/10000262 1250617401/S-1-5-21-1834383793-1770918451-929701000-129555p-X>DZƒÝ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129555 1250617401/10000262pX=ÍS›™&IDMAP/UID2SID/10000257 1250110556/S-1-5-21-1834383793-1770918451-929701000-107873pœÛX>Ëiº·™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107873 1250110556/10000257p¬X=Í)ºò™&IDMAP/UID2SID/10000158 1250268910/S-1-5-21-1834383793-1770918451-929701000-143724p¿X>ŸÔï©™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143724 1250268910/10000158pøX=ÍOðO™&IDMAP/UID2SID/10000251 1250611094/S-1-5-21-1834383793-1770918451-929701000-107839pøùX>˳…ˆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107839 1250611094/10000251p˜IX=ÍySÙ&IDMAP/UID2SID/10000250 1251132373/S-1-5-21-1834383793-1770918451-929701000-143670pèQX>sæÿ~™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143670 1251132373/10000250pø1X=]PÎg™&IDMAP/UID2SID/10000204 1251313187/S-1-5-21-1834383793-1770918451-929701000-148158phX>ÛH¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148158 1251313187/10000204p0ÁX=½ó4-™&IDMAP/UID2SID/10000225 1251145639/S-1-5-21-1834383793-1770918451-929701000-148423pÈðX>›w2™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148423 1251145639/10000225pXKX=½˜ ™&IDMAP/UID2SID/10000224 1251152545/S-1-5-21-1834383793-1770918451-929701000-107735p¨>X>ºÑí™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107735 1251152545/10000224pXªX=ꌙ&IDMAP/UID2SID/10000191 1250010769/S-1-5-21-1834383793-1770918451-929701000-148314pèïX>o¸C­™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148314 1250010769/10000191pàeX=À ™&IDMAP/UID2SID/10000192 1248710990/S-1-5-21-1834383793-1770918451-929701000-148248p,X>Cß:ã™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148248 1248710990/10000192p(¡X=Á~0™&IDMAP/UID2SID/10000145 1251154820/S-1-5-21-1834383793-1770918451-929701000-119278pX>ÃÏn™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119278 1251154820/10000145p¸ôX=ëᣙ&IDMAP/UID2SID/10000144 1250188501/S-1-5-21-1834383793-1770918451-929701000-143890p@ÿX>ËÄ€S™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143890 1250188501/10000144p˜WX=½›Áú™&IDMAP/UID2SID/10000221 1247760644/S-1-5-21-1834383793-1770918451-929701000-148450px5X>_­™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148450 1247760644/10000221p QX=½Å$n™&IDMAP/UID2SID/10000220 1247760644/S-1-5-21-1834383793-1770918451-929701000-119105pxïX>—¿ï™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119105 1247760644/10000220pdX=]Ò¤ ™&IDMAP/UID2SID/10000207 1250699869/S-1-5-21-1834383793-1770918451-929701000-119263pLX>CÚ&“™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119263 1250699869/10000207pxQX=]¨Aš™&IDMAP/UID2SID/10000208 1250612201/S-1-5-21-1834383793-1770918451-929701000-119265pðýX>C:ô\™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119265 1250612201/10000208pœÔX=—›ò™&IDMAP/UID2SID/10000246 1250695746/S-1-5-21-1834383793-1770918451-929701000-129641pt+X>óõÚm™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129641 1250695746/10000246p˜BX=Áþe™&IDMAP/UID2SID/10000245 1250695770/S-1-5-21-1834383793-1770918451-929701000-129706p X>ŸÉØà™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129706 1250695770/10000245pX=“nq™&IDMAP/UID2SID/10000140 1250814800/S-1-5-21-1834383793-1770918451-929701000-148148pxX>—¥!Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148148 1250814800/10000140pH™X=ÍÿV™&IDMAP/UID2SID/10000159 1250797242/S-1-5-21-1834383793-1770918451-929701000-143699p °X>sjÑ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143699 1250797242/10000159pX£X=½Å¤8™&IDMAP/UID2SID/10000120 1251141205/S-1-5-21-1834383793-1770918451-929701000-119191p X>áµk™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119191 1251141205/10000120pxýX<ݯ؈™&IDMAP/UID2SID/10000183 1249573430/S-1-5-21-1834383793-1770918451-929701000-95346Bp¨ÇX=vqDg™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95346 1249573430/10000183BpÀãX=ëaÙ™&IDMAP/UID2SID/10000244 1251129712/S-1-5-21-1834383793-1770918451-929701000-143856pð×X>ËL$™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143856 1251129712/10000244pPCX=ÅL™&IDMAP/UID2SID/10000243 1250535879/S-1-5-21-1834383793-1770918451-929701000-143869pXâX>KT'6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143869 1250535879/10000243pìÕX= ¹ *™&IDMAP/UID2SID/10000217 1251143308/S-1-5-21-1834383793-1770918451-929701000-129309p¾X>ïò'ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129309 1251143308/10000217p¸hX= ãl™&IDMAP/UID2SID/10000216 1251143308/S-1-5-21-1834383793-1770918451-929701000-148406p`¼X>››™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148406 1251143308/10000216pØ\X=mý¼™&IDMAP/UID2SID/10000234 1251136486/S-1-5-21-1834383793-1770918451-929701000-119217pxCX>ÃŽý¶™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119217 1251136486/10000234pøbX=mÚ™I™&IDMAP/UID2SID/10000235 1251136486/S-1-5-21-1834383793-1770918451-929701000-119209pp£X>C¹£™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119209 1251136486/10000235p´ÁX=½K(*™&IDMAP/UID2SID/10000129 1250698952/S-1-5-21-1834383793-1770918451-929701000-148344p€EX>ïX¹V™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148344 1250698952/10000129pôÆX=} ò™&IDMAP/UID2SID/10000062 1249775312/S-1-5-21-1834383793-1770918451-929701000-129552pˆfX>ǡϮ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129552 1249775312/10000062p˜õX=?(À™&IDMAP/UID2SID/10000242 1250796340/S-1-5-21-1834383793-1770918451-929701000-143683pàKX>ó+Û™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143683 1250796340/10000242ppzX=i‹3™&IDMAP/UID2SID/10000241 1250796340/S-1-5-21-1834383793-1770918451-929701000-143684p°ËX>óÛÁõ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143684 1250796340/10000241pØX=“&IDMAP/UID2SID/10000240 1250632584/S-1-5-21-1834383793-1770918451-929701000-108010pÐØX>kK±Ê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-108010 1250632584/10000240pØX=m2 |™&IDMAP/UID2SID/10000239 1250810300/S-1-5-21-1834383793-1770918451-929701000-141234pеX>ÃéØÎ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141234 1250810300/10000239p¨–X=m\pï™&IDMAP/UID2SID/10000238 1250810300/S-1-5-21-1834383793-1770918451-929701000-143812p°‡X>Ëx™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143812 1250810300/10000238pX<B÷ˆ™&IDMAP/UID2SID/10000095 1250561251/S-1-5-21-1834383793-1770918451-929701000-64587Bpp¿X=¦…Ë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-64587 1250561251/10000095Bp¸®X<–½o™&IDMAP/UID2SID/10000093 1250727725/S-1-5-21-1834383793-1770918451-929701000-25489Bp0ÝX=¦W™™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-25489 1250727725/10000093BpÀmX=À ã™&IDMAP/UID2SID/10000092 1250606578/S-1-5-21-1834383793-1770918451-929701000-119082p€»X>ë!\æ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119082 1250606578/10000092pCX<êƒV™&IDMAP/UID2SID/10000091 1251822639/S-1-5-21-1834383793-1770918451-929701000-38137BpoX=J]e™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-38137 1251822639/10000091Bp@¨X=gÿ™&IDMAP/UID2SID/10000190 1250813974/S-1-5-21-1834383793-1770918451-929701000-141236p|ÕX>ÃI¦˜™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141236 1250813974/10000190p0­X=ݳ…Ô™&IDMAP/UID2SID/10000189 1250006981/S-1-5-21-1834383793-1770918451-929701000-143811phŠX>ËÈ-Ÿ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143811 1250006981/10000189pÈœX<MÝ ›™&IDMAP/GID2SID/10000357 1251140486/S-1-5-21-1834383793-1770918451-929701000-86083BpxX=>8ª*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-86083 1251140486/10000357BpØX<m.`0™&IDMAP/UID2SID/10000233 1251140486/S-1-5-21-1834383793-1770918451-929701000-26839Bp(¨X=JpÄù™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-26839 1251140486/10000233BpX X=mXã™&IDMAP/UID2SID/10000232 1250529960/S-1-5-21-1834383793-1770918451-929701000-129691pèöX>sŸÝ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129691 1250529960/10000232p€ÞX=m‚&™&IDMAP/UID2SID/10000231 1251822074/S-1-5-21-1834383793-1770918451-929701000-119352p(BX>o.2R™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119352 1251822074/10000231pTX=m¬‰Š™&IDMAP/UID2SID/10000230 1251822074/S-1-5-21-1834383793-1770918451-929701000-119383pˆòX>ï~Ž`™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119383 1251822074/10000230pÈrX=}âP™&IDMAP/UID2SID/10000163 1251148046/S-1-5-21-1834383793-1770918451-929701000-129581p X>G’^ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129581 1251148046/10000163px X=Bw¾™&IDMAP/UID2SID/10000195 1250805658/S-1-5-21-1834383793-1770918451-929701000-143716pÂX>ÿ•™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143716 1250805658/10000195p˜pX=½K¨_™&IDMAP/UID2SID/10000229 1251824350/S-1-5-21-1834383793-1770918451-929701000-141229p`?X>C$3ä™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141229 1251824350/10000229p¢X=½u Ó™&IDMAP/UID2SID/10000228 1250548473/S-1-5-21-1834383793-1770918451-929701000-107737pà4X>Ÿ·™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107737 1250548473/10000228phuX=í»z{™&IDMAP/GID2SID/10000339 1250813825/S-1-5-21-1834383793-1770918451-929701000-143889pP¹X>ã—™™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143889 1250813825/10000339pð"X=lZü™&IDMAP/UID2SID/10000094 1250889449/S-1-5-21-1834383793-1770918451-929701000-107553p X>ÇQ Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107553 1250889449/10000094pX`X=m2F™&IDMAP/UID2SID/10000139 1250813825/S-1-5-21-1834383793-1770918451-929701000-143893p¸vX>ËÔ4‚™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143893 1250813825/10000139p¸ûX=Ý1¯.™&IDMAP/UID2SID/10000186 1250614472/S-1-5-21-1834383793-1770918451-929701000-119277phX>ÃÏè ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119277 1250614472/10000186p”ÉX=íåÝî™&IDMAP/GID2SID/10000338 1250784823/S-1-5-21-1834383793-1770918451-929701000-143937pX>fœf™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143937 1250784823/10000338pX(X=½ŸnF™&IDMAP/UID2SID/10000227 1250525522/S-1-5-21-1834383793-1770918451-929701000-107554pÐßX>ÇA™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107554 1250525522/10000227p¸™X=½Éѹ™&IDMAP/UID2SID/10000226 1250805470/S-1-5-21-1834383793-1770918451-929701000-143668páX>ó0Ù&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143668 1250805470/10000226p ÌX=½u‹™&IDMAP/UID2SID/10000128 1250804339/S-1-5-21-1834383793-1770918451-929701000-141233pXkX>Ã9òi™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141233 1250804339/10000128p”ÂX=½Ÿî™&IDMAP/UID2SID/10000127 1250804339/S-1-5-21-1834383793-1770918451-929701000-143828ph\X>KΣD™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143828 1250804339/10000127p˜¨X=–=¥™&IDMAP/UID2SID/10000193 1251160436/S-1-5-21-1834383793-1770918451-929701000-148369phúX>ï3‰™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148369 1251160436/10000193pØuX=lÚ1™&IDMAP/UID2SID/10000194 1251132851/S-1-5-21-1834383793-1770918451-929701000-148249p¨sX>C!H™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148249 1251132851/10000194pð®X=ÝL»™&IDMAP/UID2SID/10000187 1250816421/S-1-5-21-1834383793-1770918451-929701000-148238p°¨X>é™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148238 1250816421/10000187p8LX=½Gû™&IDMAP/UID2SID/10000223 1251310037/S-1-5-21-1834383793-1770918451-929701000-129610pØŸX>s¥~_™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129610 1251310037/10000223pMX<½q^‡™&IDMAP/UID2SID/10000222 1248878179/S-1-5-21-1834383793-1770918451-929701000-67570Bp@X=zÕàÉ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-67570 1248878179/10000222Bp,ÔX= eCC™&IDMAP/UID2SID/10000219 1249921474/S-1-5-21-1834383793-1770918451-929701000-148161phåX>—@!à™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148161 1249921474/10000219p¨X= ¦¶™&IDMAP/UID2SID/10000218 1249942550/S-1-5-21-1834383793-1770918451-929701000-148212ppûX>Ã]Ü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148212 1249942550/10000218p³X=CUÖ™&IDMAP/UID2SID/10000148 1250871721/S-1-5-21-1834383793-1770918451-929701000-143685pÀCX>ó‹¨Z™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143685 1250871721/10000148ppsX=òb™&IDMAP/UID2SID/10000149 1250787383/S-1-5-21-1834383793-1770918451-929701000-119376pˆX>oY¬™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119376 1250787383/10000149p°àX= ‹ùj™&IDMAP/UID2SID/10000212 1250871163/S-1-5-21-1834383793-1770918451-929701000-143855p¨X>Ë^e¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143855 1250871163/10000212pÈ€X= µ\Þ™&IDMAP/UID2SID/10000211 1250871163/S-1-5-21-1834383793-1770918451-929701000-143863p°¡X>K4¿Ø™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143863 1250871163/10000211p€×X= ß¿Q™&IDMAP/UID2SID/10000210 1251131203/S-1-5-21-1834383793-1770918451-929701000-107752p(àX>l…™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107752 1251131203/10000210pˆmX=]~Þ&™&IDMAP/UID2SID/10000209 1250795680/S-1-5-21-1834383793-1770918451-929701000-148117pà¸X>UÅÍ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148117 1250795680/10000209pLX<ÍOp™&IDMAP/UID2SID/10000151 1250873129/S-1-5-21-1834383793-1770918451-929701000-95184Bpè–X=&íš"™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95184 1250873129/10000151Bpˆ‚X=ÄMd™&IDMAP/UID2SID/10000198 1250702675/S-1-5-21-1834383793-1770918451-929701000-143723pìêX>Ÿ$ E™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143723 1250702675/10000198pØ´X=—½™&IDMAP/UID2SID/10000146 1250810717/S-1-5-21-1834383793-1770918451-929701000-143721pP²X>ŸÄ;{™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143721 1250810717/10000146p ‹X=½ÉQ„™&IDMAP/UID2SID/10000126 1251147612/S-1-5-21-1834383793-1770918451-929701000-129575pX>ÇÒ£™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129575 1251147612/10000126p¬ìX=]z±¥™&IDMAP/UID2SID/10000103 1251143308/S-1-5-21-1834383793-1770918451-929701000-143710pœX>ß-3™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143710 1251143308/10000103p@cX=]¤™&IDMAP/UID2SID/10000102 1251150089/S-1-5-21-1834383793-1770918451-929701000-143781pH X>Ÿ'Ι&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143781 1251150089/10000102pxÌX=m¸I™&IDMAP/UID2SID/10000147 1250810717/S-1-5-21-1834383793-1770918451-929701000-141060pø‚X>ëVÖ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141060 1250810717/10000147p°·X=-!çž™&IDMAP/UID2SID/10000177 1250873609/S-1-5-21-1834383793-1770918451-929701000-143660pàÍX>ó°Ø›™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143660 1250873609/10000177pD/X<ýÕ%Å™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-9105 1251825058/100004191pð˜X>ëh;™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141061 1251246539/10000160pöX=]Ò$Ø™&IDMAP/UID2SID/10000107 1250729750/S-1-5-21-1834383793-1770918451-929701000-119177p˜¯X>–Ï™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119177 1250729750/10000107p*X=]ü‡K™&IDMAP/UID2SID/10000106 1250698977/S-1-5-21-1834383793-1770918451-929701000-148446pø*X>›òŸ'™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148446 1250698977/10000106pøFX=]ü™&IDMAP/UID2SID/10000206 1250180781/S-1-5-21-1834383793-1770918451-929701000-107869p(;X>KTû1™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107869 1250180781/10000206pbX=-÷ƒ+™&IDMAP/UID2SID/10000178 1250873574/S-1-5-21-1834383793-1770918451-929701000-129756p(WX>ÕœP™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129756 1250873574/10000178p†X=]&kô™&IDMAP/UID2SID/10000205 1251313168/S-1-5-21-1834383793-1770918451-929701000-148135pNX>`FÊ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148135 1251313168/10000205p|HX=m°¶ ™&IDMAP/UID2SID/10000136 1251141206/S-1-5-21-1834383793-1770918451-929701000-119190p@2X>1Ï™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119190 1251141206/10000136pؘX=mÚ™&IDMAP/UID2SID/10000135 1251147048/S-1-5-21-1834383793-1770918451-929701000-143897p°¯X>˔ϙ&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143897 1251147048/10000135pÈyX=šêð™&IDMAP/UID2SID/10000199 1251143920/S-1-5-21-1834383793-1770918451-929701000-143708p8X>Ÿ)e±$™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143751 1251142437/10000203pðLX=}¸«Ü™&IDMAP/UID2SID/10000164 1250831042/S-1-5-21-1834383793-1770918451-929701000-129576pøÏX>Ç̸™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129576 1250831042/10000164p@ÒX=Ý…u™&IDMAP/UID2SID/10000184 1250790279/S-1-5-21-1834383793-1770918451-929701000-107671pX!X>s–ºß™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107671 1250790279/10000184p¨øX=-Ÿù™&IDMAP/UID2SID/10000174 1250807756/S-1-5-21-1834383793-1770918451-929701000-143676pðÞX>shÜ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143676 1250807756/10000174ppÔX=-óÖß™&IDMAP/UID2SID/10000172 1251823492/S-1-5-21-1834383793-1770918451-929701000-141064pdX>ëj™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141064 1251823492/10000172p°ÄX=m¬ U™&IDMAP/UID2SID/10000130 1250726375/S-1-5-21-1834383793-1770918451-929701000-129567pPX>GGxŠ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129567 1250726375/10000130p(šX= 7³N™&IDMAP/UID2SID/10000114 1251138273/S-1-5-21-1834383793-1770918451-929701000-107670p¸„X>sæÓz™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107670 1251138273/10000114p0ÏX=K™&IDMAP/UID2SID/10000196 1251146640/S-1-5-21-1834383793-1770918451-929701000-141320pÀÇX>ï-0_™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141320 1251146640/10000196pÈ£X= a™&IDMAP/UID2SID/10000113 1251138927/S-1-5-21-1834383793-1770918451-929701000-148100p  X>—OO(™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148100 1251138927/10000113pè¢X=Ý-ã™&IDMAP/UID2SID/10000180 1250898780/S-1-5-21-1834383793-1770918451-929701000-129755px†X>%¶ë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129755 1250898780/10000180pÀX=ÝÝèG™&IDMAP/UID2SID/10000188 1251824050/S-1-5-21-1834383793-1770918451-929701000-107606p0KX>ó)¢™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107606 1251824050/10000188p0´X=]Î÷Á™&IDMAP/UID2SID/10000201 1250267973/S-1-5-21-1834383793-1770918451-929701000-143730ppÛX>J|ù™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143730 1250267973/10000201pø[X=]øZ5™&IDMAP/UID2SID/10000200 1250267973/S-1-5-21-1834383793-1770918451-929701000-143732p¸AX>ªIÙ&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143732 1250267973/10000200pÜçX=ÍSf™&IDMAP/UID2SID/10000157 1250630625/S-1-5-21-1834383793-1770918451-929701000-119178p¨ˆX>F¶g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119178 1250630625/10000157p8X=î°×™&IDMAP/UID2SID/10000197 1248394430/S-1-5-21-1834383793-1770918451-929701000-107832pP.X>Ëã6Æ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107832 1248394430/10000197p0¦X=]PN2™&IDMAP/UID2SID/10000104 1251149659/S-1-5-21-1834383793-1770918451-929701000-107712p@ÄX>?Ïø™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107712 1251149659/10000104p nX=ÝÙ;ü™&IDMAP/UID2SID/10000182 1250527870/S-1-5-21-1834383793-1770918451-929701000-143707p¸ X>ŸyU™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143707 1250527870/10000182p[X=ÝŸo™&IDMAP/UID2SID/10000181 1250527870/S-1-5-21-1834383793-1770918451-929701000-143712pXX>?ûü™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143712 1250527870/10000181p0ÖX=-KJ™&IDMAP/UID2SID/10000176 1250644308/S-1-5-21-1834383793-1770918451-929701000-107782pLïX>Ÿµá.™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107782 1250644308/10000176pØgX=-u­…™&IDMAP/UID2SID/10000175 1251158093/S-1-5-21-1834383793-1770918451-929701000-107828pˆ1X>KÎw@™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107828 1251158093/10000175pP<X=}™&IDMAP/UID2SID/10000168 1250816033/S-1-5-21-1834383793-1770918451-929701000-107751pØìX>e… ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107751 1250816033/10000168p8eX=}:‚‚™&IDMAP/UID2SID/10000167 1250700661/S-1-5-21-1834383793-1770918451-929701000-107750pŒæX>µž»™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107750 1250700661/10000167p06X<}dåõ™&IDMAP/UID2SID/10000166 1251146665/S-1-5-21-1834383793-1770918451-929701000-95305BphX=FU¸g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95305 1251146665/10000166BpèqX=}ŽHi™&IDMAP/UID2SID/10000165 1251147272/S-1-5-21-1834383793-1770918451-929701000-107702pàÆX>Ÿ ¨™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107702 1251147272/10000165pH X=} rÙ&IDMAP/UID2SID/10000162 1250698610/S-1-5-21-1834383793-1770918451-929701000-107771p KX>ÐÓæ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107771 1250698610/10000162pÔÀX=}6Õ6™&IDMAP/UID2SID/10000161 1250698668/S-1-5-21-1834383793-1770918451-929701000-107785p ÝX>ŸÅ•]™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107785 1250698668/10000161p¼ÚX<ͧãL™&IDMAP/UID2SID/10000155 1251149160/S-1-5-21-1834383793-1770918451-929701000-95370BpXyX=zݤ)™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95370 1251149160/10000155Bp™X=ÍÑFÀ™&IDMAP/UID2SID/10000154 1250796526/S-1-5-21-1834383793-1770918451-929701000-129547p,2X>GÜ)Ä™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129547 1250796526/10000154p¤ŸX=Íû©3™&IDMAP/UID2SID/10000153 1250715849/S-1-5-21-1834383793-1770918451-929701000-141242pÞX>C¿2è™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141242 1250715849/10000153p˜šX=Í% §™&IDMAP/UID2SID/10000152 1250787006/S-1-5-21-1834383793-1770918451-929701000-143835pèX>Ëóù™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143835 1250787006/10000152p¸VX=íAb™&IDMAP/GID2SID/10000337 1251157458/S-1-5-21-1834383793-1770918451-929701000-129692pÆX> Š$ß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129692 1251157458/10000337pLáX= ãìg™&IDMAP/UID2SID/10000116 1250270826/S-1-5-21-1834383793-1770918451-929701000-143752pÈ6X>˜‰™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143752 1250270826/10000116ph˜X= PÛ™&IDMAP/UID2SID/10000115 1250696220/S-1-5-21-1834383793-1770918451-929701000-143785phÂX>ŸÅÁa™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143785 1250696220/10000115pŽX=šj»™&IDMAP/UID2SID/10000099 1251824050/S-1-5-21-1834383793-1770918451-929701000-148092p !X>kWdç™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148092 1251824050/10000099ppéX=m\ð¹™&IDMAP/UID2SID/10000138 1250642977/S-1-5-21-1834383793-1770918451-929701000-143880pH„X>KYp™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143880 1250642977/10000138p¸¼X=m†S-™&IDMAP/UID2SID/10000137 1251143370/S-1-5-21-1834383793-1770918451-929701000-119216pXŽX>ÃÞR™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119216 1251143370/10000137p¨ñX=m}‡™&IDMAP/UID2SID/10000134 1250703805/S-1-5-21-1834383793-1770918451-929701000-119291pˆÈX>ÃÏr™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119291 1250703805/10000134p X=m.àú™&IDMAP/UID2SID/10000133 1250870800/S-1-5-21-1834383793-1770918451-929701000-119282p°ÙX>C•Žô™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119282 1250870800/10000133p(~X=mXCn™&IDMAP/UID2SID/10000132 1251133406/S-1-5-21-1834383793-1770918451-929701000-107781p€˜X>ŸûÉ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107781 1251133406/10000132pСX=m‚¦á™&IDMAP/UID2SID/10000131 1251133406/S-1-5-21-1834383793-1770918451-929701000-129711p€ŸX>~Ë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129711 1251133406/10000131p0uX<]&ë¾™&IDMAP/UID2SID/10000105 1250880279/S-1-5-21-1834383793-1770918451-929701000-95165Bp˜ÄX=N¯÷™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95165 1250880279/10000105Bp˜iX=½k™&IDMAP/UID2SID/10000124 1250698821/S-1-5-21-1834383793-1770918451-929701000-119208p˜X>C ½8™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119208 1250698821/10000124pèjX=½G{Þ™&IDMAP/UID2SID/10000123 1250698821/S-1-5-21-1834383793-1770918451-929701000-143882p.X>Kï&:™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143882 1250698821/10000123p¬ÞX< &™&IDMAP/UID2SID/10000118 1250790522/S-1-5-21-1834383793-1770918451-929701000-95343BpPtX=öÐν™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95343 1250790522/10000118BphnX= ¹‰ô™&IDMAP/UID2SID/10000117 1250874996/S-1-5-21-1834383793-1770918451-929701000-148463pæX>›M:¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148463 1250874996/10000117p¨X= ‹y5™&IDMAP/UID2SID/10000112 1250713299/S-1-5-21-1834383793-1770918451-929701000-143892p¨7X>Ë$N™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143892 1250713299/10000112pˆX= µÜ¨™&IDMAP/UID2SID/10000111 1248831893/S-1-5-21-1834383793-1770918451-929701000-107738p =X>Ê…™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107738 1248831893/10000111p˜•X<í9¤Õ™&IDMAP/GID2SID/10000336 1250868523/S-1-5-21-1834383793-1770918451-929701000-38184BpüÑX=¾µÆ{™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38184 1250868523/10000336Bp(ŒX<”™&IDMAP/UID2SID/10000096 1251825509/S-1-5-21-1834383793-1770918451-929701000-79416Bp€­X=rô™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79416 1251825509/10000096Bph‘X= ß?™&IDMAP/UID2SID/10000110 1250868523/S-1-5-21-1834383793-1770918451-929701000-129710pø‰X>ß—f™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129710 1250868523/10000110p(wX=]~^ñ™&IDMAP/UID2SID/10000109 1250785574/S-1-5-21-1834383793-1770918451-929701000-119192p(üX>‘œÐ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119192 1250785574/10000109pxX=]¨Ád™&IDMAP/UID2SID/10000108 1250785574/S-1-5-21-1834383793-1770918451-929701000-119198p`µX>±.™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119198 1250785574/10000108p¸§X=]ÎwŒ™&IDMAP/UID2SID/10000101 1251131675/S-1-5-21-1834383793-1770918451-929701000-141243pèÚX>CoM™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141243 1251131675/10000101pð¼X=]øÚÿ™&IDMAP/UID2SID/10000100 1251131674/S-1-5-21-1834383793-1770918451-929701000-143819pȪX>ËHcÆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143819 1251131674/10000100p [X=î0¢™&IDMAP/UID2SID/10000097 1250536200/S-1-5-21-1834383793-1770918451-929701000-148128pˆùX>—:Ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148128 1250536200/10000097p€oX=çÉ™&IDMAP/UID2SID/10000090 1249923102/S-1-5-21-1834383793-1770918451-929701000-119181p@îX>—«Žˆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119181 1249923102/10000090pH’X=ݳŸ™&IDMAP/UID2SID/10000089 1250611094/S-1-5-21-1834383793-1770918451-929701000-148421p1X>›Ðh™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148421 1250611094/10000089pô¿X=]·oâ™&IDMAP/GID2SID/10000280 1250538396/S-1-5-21-1834383793-1770918451-929701000-101680p°qX>lô–™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128970 1251822591/10000281pX=­VŽ·™&IDMAP/GID2SID/10000279 1250538396/S-1-5-21-1834383793-1770918451-929701000-101669pèX=] o™&IDMAP/GID2SID/10000281 1251822591/S-1-5-21-1834383793-1770918451-929701000-128970pè›X<­€ñ*™&IDMAP/GID2SID/10000278 1251246560/S-1-5-21-1834383793-1770918451-929701000-25224BpÈâX=¶Û™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-25224 1251246560/10000278Bp`X<ÝÝh™&IDMAP/UID2SID/10000088 1251824050/S-1-5-21-1834383793-1770918451-929701000-66635Bp@çX=Jú4œ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-66635 1251824050/10000088BpøºX<­Ô·™&IDMAP/GID2SID/10000276 1246951403/S-1-5-21-1834383793-1770918451-929701000-39695Bpˆ{X=ê$R·™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-39695 1246951403/10000276BpØ»X<­þ…™&IDMAP/GID2SID/10000275 1246951403/S-1-5-21-1834383793-1770918451-929701000-39694BptÃX=jï*Ô™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-39694 1246951403/10000275Bp”X<ÝÌ…™&IDMAP/UID2SID/10000087 1246951403/S-1-5-21-1834383793-1770918451-929701000-87059Bp8«X=¢ó™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87059 1246951403/10000087Bp˜¶X=Íû)þ™&IDMAP/UID2SID/10000053 1250286053/S-1-5-21-1834383793-1770918451-929701000-119356pxöX>oîÌå™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119356 1250286053/10000053pø¬(îò“º™&IDMAP/UID2SID/10000 1246297471/-B@X—(îò?ô™&IDMAP/UID2SID/10001 1246297471/-B@À¬X=-!gi™&IDMAP/UID2SID/10000077 1251824050/S-1-5-21-1834383793-1770918451-929701000-107858p(4X>Ëníé™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107858 1251824050/10000077p `X=-KÊÜ™&IDMAP/UID2SID/10000076 1251143169/S-1-5-21-1834383793-1770918451-929701000-129686pXþX>ó;ùò™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129686 1251143169/10000076pÐ]X<Ý1/ù™&IDMAP/UID2SID/10000086 1251824050/S-1-5-21-1834383793-1770918451-929701000-95888Bp˜&X=&Ã×L™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95888 1251824050/10000086BpÜ#X=Ý[’l™&IDMAP/UID2SID/10000085 1251310325/S-1-5-21-1834383793-1770918451-929701000-107683p»X>ó+¯Œ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107683 1251310325/10000085pÜ)X=Ý…õß™&IDMAP/UID2SID/10000084 1250642961/S-1-5-21-1834383793-1770918451-929701000-107767pàéX>Ÿºa™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107767 1250642961/10000084p§X=ý•ß™&IDMAP/GID2SID/10000262 1251824032/S-1-5-21-1834383793-1770918451-929701000-113648pà•X>‹ž®™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113648 1251824032/10000262p4ÅX=ý¿B6™&IDMAP/GID2SID/10000261 1250642960/S-1-5-21-1834383793-1770918451-929701000-148342p0=X>‡ÑŠ)™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148342 1250642960/10000261p˜“X<ݯXS™&IDMAP/UID2SID/10000083 1251824050/S-1-5-21-1834383793-1770918451-929701000-66812BpШX=ý饩™&IDMAP/GID2SID/10000260 1250802575/S-1-5-21-1834383793-1770918451-929701000-119218pЮX>[ƒ¸™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119218 1250802575/10000260pà&X<Ý-‚­™&IDMAP/UID2SID/10000080 1251824050/S-1-5-21-1834383793-1770918451-929701000-79421BpPX=žBs‹™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79421 1251824050/10000080Bpx©X=-Í ‚™&IDMAP/UID2SID/10000079 1250267446/S-1-5-21-1834383793-1770918451-929701000-119274pp&X>ÿ4Û™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119274 1250267446/10000079p¸”X=M1QL™&IDMAP/GID2SID/10000255 1250632584/S-1-5-21-1834383793-1770918451-929701000-129739pÐæX>·R¡U™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129739 1250632584/10000255pü=X=M[´¿™&IDMAP/GID2SID/10000254 1251822639/S-1-5-21-1834383793-1770918451-929701000-119284p@¶X>ÛÍúZ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119284 1251822639/10000254pëX<-Éó6™&IDMAP/UID2SID/10000073 1251130186/S-1-5-21-1834383793-1770918451-929701000-55147Bph´X=öFÞå™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-55147 1251130186/10000073Bp°¾X=-÷ö™&IDMAP/UID2SID/10000078 1250871873/S-1-5-21-1834383793-1770918451-929701000-143901pl7X>÷ÌÙ&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143901 1250871873/10000078p'X<-u-P™&IDMAP/UID2SID/10000075 1250893808/S-1-5-21-1834383793-1770918451-929701000-66597Bp0(X=R¿º¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-66597 1250893808/10000075BpØ­X=-ŸÃ™&IDMAP/UID2SID/10000074 1251310813/S-1-5-21-1834383793-1770918451-929701000-148455pH®X>xख़&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148455 1251310813/10000074p`€X=-óVª™&IDMAP/UID2SID/10000072 1247681305/S-1-5-21-1834383793-1770918451-929701000-148484pØX>›hoê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148484 1247681305/10000072pXðX=-º™&IDMAP/UID2SID/10000071 1250274070/S-1-5-21-1834383793-1770918451-929701000-148482p¨lX>›¢ ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148482 1250274070/10000071p@°X=-G‘™&IDMAP/UID2SID/10000070 1251822623/S-1-5-21-1834383793-1770918451-929701000-148479p8øX>£Éÿ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148479 1251822623/10000070p7m)Ú™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143728 1251132054/10000248pÜ~X=ö%I™&IDMAP/GID2SID/10000247 1250805470/S-1-5-21-1834383793-1770918451-929701000-136387pjX>‡~Å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136387 1250805470/10000247püDX= ‰¼™&IDMAP/GID2SID/10000246 1250805470/S-1-5-21-1834383793-1770918451-929701000-136388p˜¡X>‡Çd*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136388 1250805470/10000246p°¢X=Jì/™&IDMAP/GID2SID/10000245 1250793789/S-1-5-21-1834383793-1770918451-929701000-143907pHoX>Å&½™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143907 1250793789/10000245p£X=tO£™&IDMAP/GID2SID/10000244 1250971642/S-1-5-21-1834383793-1770918451-929701000-129618p`§X> þR#™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129618 1250971642/10000244pp¤X=ž²™&IDMAP/GID2SID/10000243 1250805470/S-1-5-21-1834383793-1770918451-929701000-129662p­X>‹é®5™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129662 1250805470/10000243pP¥X=ÈŠ™&IDMAP/GID2SID/10000242 1250805470/S-1-5-21-1834383793-1770918451-929701000-107844p´X>ãQÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107844 1250805470/10000242pÈŽX<òxý™&IDMAP/GID2SID/10000241 1250805470/S-1-5-21-1834383793-1770918451-929701000-42608BphX=^k.™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42608 1250805470/10000241Bpø¥X=Üp™&IDMAP/GID2SID/10000240 1251822639/S-1-5-21-1834383793-1770918451-929701000-107746pÈþX>7x~Ò™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107746 1251822639/10000240pð§X=í»úE™&IDMAP/GID2SID/10000239 1250805470/S-1-5-21-1834383793-1770918451-929701000-143774pàÛX>·¸R¶™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143774 1250805470/10000239pÜ7X=íå]¹™&IDMAP/GID2SID/10000238 1250805470/S-1-5-21-1834383793-1770918451-929701000-129747pØŠX>7(ûn™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129747 1250805470/10000238pdÀX=íÁ,™&IDMAP/GID2SID/10000237 1250906407/S-1-5-21-1834383793-1770918451-929701000-129198pÀÀX>¯‰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129198 1250906407/10000237pªX=í9$ ™&IDMAP/GID2SID/10000236 1250971642/S-1-5-21-1834383793-1770918451-929701000-143687ph9X>‹ÄÁ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143687 1250971642/10000236pp«X<íc‡™&IDMAP/GID2SID/10000235 1251135589/S-1-5-21-1834383793-1770918451-929701000-42572Bp@šX=iÐ?™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42572 1251135589/10000235BpP¬X=íꆙ&IDMAP/GID2SID/10000234 1251157458/S-1-5-21-1834383793-1770918451-929701000-148353pøX>·˜q™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148353 1251157458/10000234p<5X=í·Mú™&IDMAP/GID2SID/10000233 1250805470/S-1-5-21-1834383793-1770918451-929701000-129661p ÓX>‹9ÈЙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129661 1250805470/10000233p®X=íá°m™&IDMAP/GID2SID/10000232 1251822639/S-1-5-21-1834383793-1770918451-929701000-107691pH”X> Ú§B™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107691 1251822639/10000232p`bX=í á™&IDMAP/GID2SID/10000231 1250805470/S-1-5-21-1834383793-1770918451-929701000-107778pèX>·xÁE™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107778 1250805470/10000231p¤X=í5wT™&IDMAP/GID2SID/10000230 1250805470/S-1-5-21-1834383793-1770918451-929701000-108018pè X>¤…Ž™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-108018 1250805470/10000230p¤ÏX==Õ•)™&IDMAP/GID2SID/10000229 1250805470/S-1-5-21-1834383793-1770918451-929701000-129663p´X>‹™•š™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129663 1250805470/10000229p±X<=ÿøœ™&IDMAP/GID2SID/10000228 1251135589/S-1-5-21-1834383793-1770918451-929701000-42573BpˆX=’ž÷"™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42573 1251135589/10000228Bpp²X<=)\™&IDMAP/GID2SID/10000227 1250630963/S-1-5-21-1834383793-1770918451-929701000-42595BpH:X=ê|x÷™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42595 1250630963/10000227BpP³X==S¿ƒ™&IDMAP/GID2SID/10000226 1250805470/S-1-5-21-1834383793-1770918451-929701000-129721phX>7DK™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129721 1250805470/10000226pPŠX==}"÷™&IDMAP/GID2SID/10000225 1250805470/S-1-5-21-1834383793-1770918451-929701000-129664p×X>‹I|ÿ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129664 1250805470/10000225pµX==§…j™&IDMAP/GID2SID/10000224 1250805470/S-1-5-21-1834383793-1770918451-929701000-129660p¢X>‹‰ák™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129660 1250805470/10000224pHhX==ÑèÝ™&IDMAP/GID2SID/10000223 1251826514/S-1-5-21-1834383793-1770918451-929701000-148396pÀ³X>é,™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148396 1251826514/10000223pжX==ûKQ™&IDMAP/GID2SID/10000222 1250805470/S-1-5-21-1834383793-1770918451-929701000-107766ph@X>7ã̘™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107766 1250805470/10000222p kX<=%¯Ä™&IDMAP/GID2SID/10000221 1250805470/S-1-5-21-1834383793-1770918451-929701000-79444BpÀ„X=/ºß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79444 1250805470/10000221BpX<=O8™&IDMAP/GID2SID/10000220 1250805470/S-1-5-21-1834383793-1770918451-929701000-79394BpÌ X=jOØ5™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-79394 1250805470/10000220Bpp¹X<î0 ™&IDMAP/GID2SID/10000219 1250805470/S-1-5-21-1834383793-1770918451-929701000-95350Bp žX=ºB¸™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-95350 1250805470/10000219BpPºX=”€™&IDMAP/GID2SID/10000218 1251822639/S-1-5-21-1834383793-1770918451-929701000-141420p@½X>3@è™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-141420 1251822639/10000218pÄX<B÷ó™&IDMAP/GID2SID/10000217 1251132054/S-1-5-21-1834383793-1770918451-929701000-42589Bpˆ³X=>ü|™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42589 1251132054/10000217Bp¼X<lZg™&IDMAP/GID2SID/10000216 1251824032/S-1-5-21-1834383793-1770918451-929701000-42591Bp 3X=ê¦Ûj™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42591 1251824032/10000216Bp„X=–½Ú™&IDMAP/GID2SID/10000215 1250538396/S-1-5-21-1834383793-1770918451-929701000-148315pTX=¥R™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-36648 1251822591/10000121pнX=À N™&IDMAP/GID2SID/10000214 1251822639/S-1-5-21-1834383793-1770918451-929701000-113149pèáX>/.†ï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113149 1251822639/10000214pìƒX=êƒÁ™&IDMAP/GID2SID/10000213 1250805470/S-1-5-21-1834383793-1770918451-929701000-107779pÀ«X>·(¨ª™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107779 1250805470/10000213p¿X=ç4™&IDMAP/GID2SID/10000212 1251135589/S-1-5-21-1834383793-1770918451-929701000-129587ph»X>ߊeí™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129587 1251135589/10000212p ¬X<}¸+§™&IDMAP/UID2SID/10000064 1251824050/S-1-5-21-1834383793-1770918451-929701000-75911BpXX=òŽM™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-75911 1251824050/10000064Bp uX=}ŽÈ3™&IDMAP/UID2SID/10000065 1249586553/S-1-5-21-1834383793-1770918451-929701000-143853p`X>Ëþ—õ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143853 1249586553/10000065p€´X=M…3™&IDMAP/GID2SID/10000253 1250729595/S-1-5-21-1834383793-1770918451-929701000-148477p¼èX>³›Ò™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148477 1250729595/10000253p„ÌX<M¯z¦™&IDMAP/GID2SID/10000252 1246408046/S-1-5-21-1834383793-1770918451-929701000-36764Bp}X=fBþ ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-36764 1246408046/10000252Bpx|X=}ŸÙ™&IDMAP/UID2SID/10000068 1246408046/S-1-5-21-1834383793-1770918451-929701000-148476pXžX>“Ñ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148476 1246408046/10000068p¸X:MÙÝ™&IDMAP/GID2SID/10000251 1246407434/S-1-5-21-1834383793-1770918451-929701000-512BBBphŸX;ÔÑW™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-512 1246407434/10000251BBBpX= xl™&IDMAP/GID2SID/10000097 1251309681/S-1-5-21-1834383793-1770918451-929701000-126402p`X>35ql™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126402 1251309681/10000097p8¹X= ¢ß™&IDMAP/GID2SID/10000096 1251309681/S-1-5-21-1834383793-1770918451-929701000-126401p¨¹X>3…Š™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126401 1251309681/10000096pÜX= «9™&IDMAP/GID2SID/10000093 1251309681/S-1-5-21-1834383793-1770918451-929701000-126399pX‡X>­$™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126399 1251309681/10000093pX= tq ™&IDMAP/GID2SID/10000091 1251822074/S-1-5-21-1834383793-1770918451-929701000-119075pÔX>ՇΙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119075 1251822074/10000091pX=]gVÜ™&IDMAP/GID2SID/10000088 1250731374/S-1-5-21-1834383793-1770918451-929701000-107716pPÎX>·×)™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107716 1250731374/10000088pŒX=]å6™&IDMAP/GID2SID/10000085 1251309681/S-1-5-21-1834383793-1770918451-929701000-119293pIX>[S;Ù™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119293 1251309681/10000085p6X= ÌäR™&IDMAP/GID2SID/10000095 1251822639/S-1-5-21-1834383793-1770918451-929701000-143843pPfX>㡯™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143843 1251822639/10000095p¸µX=ÍÑÆŠ™&IDMAP/UID2SID/10000054 1250785101/S-1-5-21-1834383793-1770918451-929701000-148281pøžX>C刭™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148281 1250785101/10000054pX=ͧc™&IDMAP/UID2SID/10000055 1246406429/S-1-5-21-1834383793-1770918451-929701000-107798pôX> qo™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107798 1246406429/10000055p`pX=}:M™&IDMAP/UID2SID/10000067 1250012412/S-1-5-21-1834383793-1770918451-929701000-143891p ÜX>Ëtg¸™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143891 1250012412/10000067p _X<MA™&IDMAP/GID2SID/10000250 1251825058/S-1-5-21-1834383793-1770918451-929701000-46573BpˆtX=’ž£\™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-46573 1251825058/10000250Bp8ŸX<¢_b™&IDMAP/GID2SID/10000249 1251153193/S-1-5-21-1834383793-1770918451-929701000-38052Op¨)X=ºÌÒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38052 1251153193/100002496pX6X<}deÀ™&IDMAP/UID2SID/10000066 1251148458/S-1-5-21-1834383793-1770918451-929701000-79085BpðŒX=ÝÌð™&IDMAP/GID2SID/10000209 1250949070/S-1-5-21-1834383793-1770918451-929701000-137093p¸X>àÍ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-137093 1250949070/10000209pÀ<X=Ý1/d™&IDMAP/GID2SID/10000208 1250949070/S-1-5-21-1834383793-1770918451-929701000-127288pxX>Û@¢™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127288 1250949070/10000208p„ X=Ý[’×™&IDMAP/GID2SID/10000207 1250949070/S-1-5-21-1834383793-1770918451-929701000-137092pÜÙX>08h™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-137092 1250949070/10000207peX=Ý…õJ™&IDMAP/GID2SID/10000206 1250949070/S-1-5-21-1834383793-1770918451-929701000-127289pH¼X>Û='™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127289 1250949070/10000206p˜X<ݯX¾™&IDMAP/GID2SID/10000205 1250949070/S-1-5-21-1834383793-1770918451-929701000-91520BpЙX=¶•Ù™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-91520 1250949070/10000205BpÀfX<ÝÙ»1™&IDMAP/GID2SID/10000204 1250949070/S-1-5-21-1834383793-1770918451-929701000-88064BpHµX=fútœ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-88064 1250949070/10000204Bp gX<Ý¥™&IDMAP/GID2SID/10000203 1250949070/S-1-5-21-1834383793-1770918451-929701000-70905BpÈ X=Þ}™ç™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-70905 1250949070/10000203BpÀ{X=Ý-‚™&IDMAP/GID2SID/10000202 1250949070/S-1-5-21-2140803266-1626024873-1299147156-24034p( X>²ºu ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24034 1250949070/10000202p°xX=ÝWå‹™&IDMAP/GID2SID/10000201 1250949070/S-1-5-21-2106152344-1726899929-2013803672-44720pø#X> 7ç™&IDMAP/SID2GID/S-1-5-21-2106152344-1726899929-2013803672-44720 1250949070/10000201pX=ÝHÿ™&IDMAP/GID2SID/10000200 1250949070/S-1-5-21-2140803266-1626024873-1299147156-34812p0!X>½Ž™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34812 1250949070/10000200pàlX= $غ™&IDMAP/GID2SID/10000199 1250949070/S-1-5-21-2140803266-1626024873-1299147156-25445p ¢X>â†H=™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25445 1250949070/10000199pX= N;.™&IDMAP/GID2SID/10000198 1250949070/S-1-5-21-1834383793-1770918451-929701000-153031p`™X>?¼™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-153031 1250949070/10000198pÌ$X= xž¡™&IDMAP/GID2SID/10000197 1250949070/S-1-5-21-2140803266-1626024873-1299147156-37994pð´X>¾ÏT™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-37994 1250949070/10000197pðÌX= ¢™&IDMAP/GID2SID/10000196 1250949070/S-1-5-21-2140803266-1626024873-1299147156-34810p¨"X>]Á8™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34810 1250949070/10000196p@qX= Ìdˆ™&IDMAP/GID2SID/10000195 1250949070/S-1-5-21-1834383793-1770918451-929701000-127557pøMX>_ê/©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127557 1250949070/10000195pl%X= öÇû™&IDMAP/GID2SID/10000194 1250949070/S-1-5-21-2140803266-1626024873-1299147156-21488p¸,X>âlÙ&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-21488 1250949070/10000194pX< +o™&IDMAP/GID2SID/10000193 1250949070/S-1-5-21-1834383793-1770918451-929701000-68182BpðŸX=¾RÒL™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68182 1250949070/10000193BpŒX< JŽâ™&IDMAP/GID2SID/10000192 1250949070/S-1-5-21-1834383793-1770918451-929701000-70902BpÀŠX=^Ý#>™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-70902 1250949070/10000192BpX= tñU™&IDMAP/GID2SID/10000191 1250949070/S-1-5-21-1834383793-1770918451-929701000-123200pÅX>ÛaQ,™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-123200 1250949070/10000191p|AX< žTÉ™&IDMAP/GID2SID/10000190 1250949070/S-1-5-21-1834383793-1770918451-929701000-45011BpßX=ŠÙr™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-45011 1250949070/10000190Bp,$X<]=sž™&IDMAP/GID2SID/10000189 1250949070/S-1-5-21-1834383793-1770918451-929701000-90536BpÀX=bs™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90536 1250949070/10000189Bpð7X=]gÖ™&IDMAP/GID2SID/10000188 1250949070/S-1-5-21-1834383793-1770918451-929701000-122058p8õX>z¸ç™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122058 1250949070/10000188pX=]‘9…™&IDMAP/GID2SID/10000187 1250949070/S-1-5-21-2140803266-1626024873-1299147156-23996pÈÛX>¾b±š™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-23996 1250949070/10000187pX;]»œø™&IDMAP/GID2SID/10000186 1250949070/S-1-5-21-4186143834-2626045635-1021053583-519BBpx”X<ÚS8Å™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-519 1250949070/10000186BBpø’X<]åÿk™&IDMAP/GID2SID/10000185 1250949070/S-1-5-21-4186143834-2626045635-1021053583-1651Bp€¦X=Ï6¯ ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1651 1250949070/10000185Bp8ÏX<]cß™&IDMAP/GID2SID/10000184 1250949070/S-1-5-21-4186143834-2626045635-1021053583-7620BplÙX=KT¾ç™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7620 1250949070/10000184BpØ“X;]9ÆR™&IDMAP/GID2SID/10000183 1250949070/S-1-5-21-4186143834-2626045635-1021053583-513BBpІX<Òù š™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-513 1250949070/10000183BBpÆX<}⎙&IDMAP/UID2SID/10000063 1250949070/S-1-5-21-4186143834-2626045635-1021053583-1183BpDÁX=;vÊE™&IDMAP/SID2UID/S-1-5-21-4186143834-2626045635-1021053583-1183 1250949070/10000063BppRP,¾}8•™&SAF/DOMAIN/MTVNE.AD.VIACOM.COM 1251229469/NEW-BRDC01.mtvne.ad.viacom.comh@…D,Ugaô™&SAF/DOMAIN/MTVNE 1251229469/NEW-BRDC01.mtvne.ad.viacom.com:0\¨²D'}Rª™&SAF/DOMAIN/AD.VIACOM.COM 1251229419/musselbeach.ad.viacom.com\|ãD"0({x™&NBT/UNITYNYAD01.IPT.VIACOM.COM#20 1250705340/172.21.200.27:0B\ÔÇX=}6U™&IDMAP/UID2SID/10000061 1245280903/S-1-5-21-1834383793-1770918451-929701000-148440p°©X>›Ò7Ê™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148440 1245280903/10000061p0.X=­Ô7Ü™&IDMAP/GID2SID/10000176 1250795400/S-1-5-21-1834383793-1770918451-929701000-148426pì3X>3`ðý™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148426 1250795400/10000176pœ2X=­þšO™&IDMAP/GID2SID/10000175 1251822591/S-1-5-21-1834383793-1770918451-929701000-148427phóX>3×b™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148427 1251822591/10000175p rX=­Ra6™&IDMAP/GID2SID/10000173 1251823334/S-1-5-21-1834383793-1770918451-929701000-107054p@¢X>º'º™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107054 1251823334/10000173p\‚X=­|Ä©™&IDMAP/GID2SID/10000172 1251823334/S-1-5-21-2140803266-1626024873-1299147156-20439pdÇX>bÜê™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20439 1251823334/10000172pÜ>X<­¦'™&IDMAP/GID2SID/10000171 1251822594/S-1-5-21-4186143834-2626045635-1021053583-7668Bp¸X=ûæ\™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7668 1251822594/10000171Bpœ9X<­ÐŠ™&IDMAP/GID2SID/10000170 1251823334/S-1-5-21-4186143834-2626045635-1021053583-7638BpàX=÷9™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7638 1251823334/10000170Bpœ@X=ýo©e™&IDMAP/GID2SID/10000169 1251823334/S-1-5-21-1834383793-1770918451-929701000-117589plEX>ßêΙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-117589 1251823334/10000169p |X<ý™ Ù™&IDMAP/GID2SID/10000168 1251823334/S-1-5-21-1834383793-1770918451-929701000-90130BpˆMX=bχ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90130 1251823334/10000168Bp\BX=ýÃoL™&IDMAP/GID2SID/10000167 1251823334/S-1-5-21-1834383793-1770918451-929701000-102786pUX>7N;\™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-102786 1251823334/10000167ptÊX=ýíÒ¿™&IDMAP/GID2SID/10000166 1251823334/S-1-5-21-1834383793-1770918451-929701000-117590p´X>_ð%™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-117590 1251823334/10000166pDX<ý63™&IDMAP/GID2SID/10000165 1251823334/S-1-5-21-1834383793-1770918451-929701000-23125BpX€X=69Ìy™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-23125 1251823334/10000165Bp‰X<}`¸t™&IDMAP/UID2SID/10000060 1251823334/S-1-5-21-1834383793-1770918451-929701000-32616BpÀ¥X=r´# ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-32616 1251823334/10000060pˆƒD-úÊVd™&SAF/DOMAIN/NETDEV 1251229765/NETDEVROOTDC1.netdev.viacom.como\€X2U®ì™&NBT/PARAMOUNT.AD.VIACOM.COM#1C 1251229229/166.77.172.94:389,166.77.172.108:389-Bpl0L!ã§ ™&NBT/VIACOM_CORP.AD.VIACOM.COM#1C 1244247425/166.77.86.15:389com.comCdЯT+#fIÇ™&AD_SITENAME/DOMAIN/PARAMOUNT.AD.VIACOM.COM 4294967295/US-California-Burbank9:l¸›D#Ö«²5™&AD_SITENAME/DOMAIN/PARAMOUNT 4294967295/US-California-Burbank\À}áS«fæþÙNBT/MTVNE.AD.VIACOM.COM#4@©X32e½™&NBT/MTVNASIA.AD.VIACOM.COM#1C 1251229229/166.77.172.140:389,166.77.172.115:389ompÈkX#1ÿ2™¬™&SAF/DOMAIN/PARAMOUNT.AD.VIACOM.COM 1251229469/bubblebuddy.paramount.ad.viacom.compÍT(ïÓ ÷™&NBT/SQUILLIAM.MTVNASIA.AD.VIACOM.COM#20 1251229216/166.77.172.140:0acom.coml8¤T(‹£Ï×™&NBT/MISSTUFTSY.HOSTING.AD.VIACOM.COM#20 1251229217/166.77.173.152:0com.com1lT*#÷6½™&AD_SITENAME/DOMAIN/MTVNASIA.AD.VIACOM.COM 4294967295/US-California-Burbank9.2l°°D#í3à™&AD_SITENAME/DOMAIN/MTVNASIA 4294967295/US-California-Burbank\`¨0e÷ê™&IDMAP/SID2GID/S-1-5-32-546 1251227603/-1BHмL-xÄ¡™&SAF/DOMAIN/MTVN 1251234708/perchperkins.mtvn.ad.viacom.com.128:0mBBdXX=í·Íš™&IDMAP/GID2SID/10000533 1249523687/S-1-5-21-2140803266-1626024873-1299147156-34227pìñX>Š ³™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34227 1249523687/10000533phNX=íá0™&IDMAP/GID2SID/10000532 1249523687/S-1-5-21-2140803266-1626024873-1299147156-37778pP X>fäè™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-37778 1249523687/10000532ppX=í ”™&IDMAP/GID2SID/10000531 1249523687/S-1-5-21-2140803266-1626024873-1299147156-19855pÝX>£é#™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-19855 1249523687/10000531p¬×X=í5÷ô™&IDMAP/GID2SID/10000530 1249523687/S-1-5-21-2140803266-1626024873-1299147156-34231pìãX> _9™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34231 1249523687/10000530pøX==ÕÊ™&IDMAP/GID2SID/10000529 1249523687/S-1-5-21-2140803266-1626024873-1299147156-34228pýX>Џ†™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34228 1249523687/10000529p(X==ÿx=™&IDMAP/GID2SID/10000528 1249523686/S-1-5-21-2140803266-1626024873-1299147156-34229plîX>Šhm}™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34229 1249523686/10000528p°X==)ܰ™&IDMAP/GID2SID/10000527 1249523686/S-1-5-21-2140803266-1626024873-1299147156-34230pÈdX> nxÔ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34230 1249523686/10000527p<×X==S?$™&IDMAP/GID2SID/10000526 1249523685/S-1-5-21-1834383793-1770918451-929701000-136405pTÄX>3Eé™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136405 1249523685/10000526p,éX=B÷^™&IDMAP/GID2SID/10000417 1249523685/S-1-5-21-1834383793-1770918451-929701000-160163p ãX>/ycx™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-160163 1249523685/10000417p<åX==}¢—™&IDMAP/GID2SID/10000525 1249523685/S-1-5-21-1834383793-1770918451-929701000-136403pXÍX>3å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136403 1249523685/10000525pÀ5X==§ ™&IDMAP/GID2SID/10000524 1250949070/S-1-5-21-1834383793-1770918451-929701000-136402p,X>35ܺ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136402 1250949070/10000524pÜîX==Ñh~™&IDMAP/GID2SID/10000523 1249523685/S-1-5-21-1834383793-1770918451-929701000-136406pX>3õvN™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136406 1249523685/10000523p¸ÑX<=ûËñ™&IDMAP/GID2SID/10000522 1249523684/S-1-5-21-1834383793-1770918451-929701000-64158Bp¸íX=ºæÅP™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-64158 1249523684/10000522BpˆFX==%/e™&IDMAP/GID2SID/10000521 1249523684/S-1-5-21-1834383793-1770918451-929701000-136394püíX>=ñy™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136394 1249523684/10000521pˆ‰X==O’Ø™&IDMAP/GID2SID/10000520 1249523684/S-1-5-21-1834383793-1770918451-929701000-136295p\äX>[³¾×™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136295 1249523684/10000520päX=–½E™&IDMAP/GID2SID/10000415 1249523684/S-1-5-21-1834383793-1770918451-929701000-136410pìHX>³ 6Ô™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136410 1249523684/10000415ppX=î°­™&IDMAP/GID2SID/10000519 1249523684/S-1-5-21-1834383793-1770918451-929701000-136296ppX>[c¥<™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136296 1249523684/10000519p|êX=êƒ,™&IDMAP/GID2SID/10000413 1249523684/S-1-5-21-1834383793-1770918451-929701000-136409p°ÿX>3+}™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136409 1249523684/10000413pxqX<!™&IDMAP/GID2SID/10000518 1249523684/S-1-5-21-1834383793-1770918451-929701000-90338Bp°X=b{;™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-90338 1249523684/10000518BpÈ/X=Bw”™&IDMAP/GID2SID/10000517 1249523684/S-1-5-21-1834383793-1770918451-929701000-136404pAX>3•©„™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136404 1249523684/10000517p¼ïX=lÚ™&IDMAP/GID2SID/10000516 1249523683/S-1-5-21-1834383793-1770918451-929701000-143490p€ýX>³¶ºÓ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143490 1249523683/10000516pÐ*X=–={™&IDMAP/GID2SID/10000515 1250949070/S-1-5-21-1834383793-1770918451-929701000-136401p¬X>3…õU™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-136401 1250949070/10000515pxáX=À î™&IDMAP/GID2SID/10000514 1249523683/S-1-5-21-1834383793-1770918451-929701000-140136pÐþX>¯èË`™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140136 1249523683/10000514p8lX=êb™&IDMAP/GID2SID/10000513 1249523683/S-1-5-21-1834383793-1770918451-929701000-128030pØNX>tÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128030 1249523683/10000513p0X=gÕ™&IDMAP/GID2SID/10000512 1249523683/S-1-5-21-1834383793-1770918451-929701000-116610pÔûX> ~’E™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116610 1249523683/10000512pp-X=>ÊH™&IDMAP/GID2SID/10000511 1249523683/S-1-5-21-1834383793-1770918451-929701000-128031pð X>?[/™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-128031 1249523683/10000511pHX=h-¼™&IDMAP/GID2SID/10000510 1249523682/S-1-5-21-1834383793-1770918451-929701000-127548pH,X>ßdï*™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127548 1249523682/10000510pX=ÝL‘™&IDMAP/GID2SID/10000509 1249523682/S-1-5-21-1834383793-1770918451-929701000-140137ppIX>¯˜²Å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140137 1249523682/10000509pðX<Ý1¯™&IDMAP/GID2SID/10000508 1249523682/S-1-5-21-1834383793-1770918451-929701000-56310BpèxX= üI ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56310 1249523682/10000508BpÐX=Ý[x™&IDMAP/GID2SID/10000507 1249523682/S-1-5-21-1834383793-1770918451-929701000-127549p<óX>ßÖ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-127549 1249523682/10000507p¨zX=Ý…uë™&IDMAP/GID2SID/10000506 1249523682/S-1-5-21-1834383793-1770918451-929701000-119975p8ñX>Üj™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119975 1249523682/10000506pà X=ݯØ^™&IDMAP/GID2SID/10000505 1249523682/S-1-5-21-1834383793-1770918451-929701000-105139ph÷X>¯ø³X™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-105139 1249523682/10000505p¨ÀX<ÝÙ;Ò™&IDMAP/GID2SID/10000504 1249523681/S-1-5-21-1834383793-1770918451-929701000-57905Bp¸ßX=ÞÍŸ§™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-57905 1249523681/10000504BpئX=ÝŸE™&IDMAP/GID2SID/10000503 1249523681/S-1-5-21-1834383793-1770918451-929701000-116608pØ@X>‹È ‰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-116608 1249523681/10000503pœðX=Ý-¹™&IDMAP/GID2SID/10000502 1249523681/S-1-5-21-1834383793-1770918451-929701000-119974pè†X>,„©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-119974 1249523681/10000502pˆöX=ÝWe,™&IDMAP/GID2SID/10000501 1249523681/S-1-5-21-1834383793-1770918451-929701000-140124pð)X>/S׳™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-140124 1249523681/10000501p°X<Á~›™&IDMAP/UID2SID/10000345 1249523680/S-1-5-21-1834383793-1770918451-929701000-64298BpøÁX=Òôë™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-64298 1249523680/10000345BpáX=Ýٻƙ&IDMAP/UID2SID/10000082 1251221751/S-1-5-21-1834383793-1770918451-929701000-129642pPÇX>ó¥ÁÒ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129642 1251221751/10000082pX=]Ò$C™&IDMAP/UID2SID/10000307 1250630963/S-1-5-21-1834383793-1770918451-929701000-105272pFX>Ã_|™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-105272 1250630963/10000307pHíX=-÷a™&IDMAP/UID2SID/10000278 1249520768/S-1-5-21-1834383793-1770918451-929701000-129577p(ùX>Ç|Ÿm™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129577 1249520768/10000278pPZ$Ö]­™&IDMAP/GID2SID/99 1251227602/-<ØåX=M1Q·™&IDMAP/GID2SID/10000455 1251825059/S-1-5-21-2140803266-1626024873-1299147156-32221pPˆX>Šèw»™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-32221 1251825059/10000455pX<M[´*™&IDMAP/GID2SID/10000454 1250200846/S-1-5-21-1834383793-1770918451-929701000-61975Bp¨ÜX=’¹A5™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-61975 1250200846/10000454BpìùX=M…ž™&IDMAP/GID2SID/10000453 1250200846/S-1-5-21-1834383793-1770918451-929701000-126290p¸ÃX>[CÒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126290 1250200846/10000453pØÂX<h­†™&IDMAP/GID2SID/10000410 1251837380/S-1-5-21-1834383793-1770918451-929701000-80133BpˆÖX=â þ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-80133 1251837380/10000410BpPX<M¯z™&IDMAP/GID2SID/10000452 1250200846/S-1-5-21-1834383793-1770918451-929701000-31583BplçX=>€2©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-31583 1250200846/10000452BpÐX<MÙÝ„™&IDMAP/GID2SID/10000451 1251826461/S-1-5-21-1834383793-1770918451-929701000-95336Bpl>X=bÊü™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-95336 1251826461/10000451Bp(IH 6ù^ð™&TDOM/HOSTING 1250633849/S-1-5-21-656259101-2991933430-3416489241B`L74ðÙé™&TDOM/PARAMOUNT 1250633849/S-1-5-21-3692268541-1264201430-3503654325BBdÐ1H3³¡íÅ™&TDOM/HARMONIX 1250633849/S-1-5-21-73586283-776561741-725345543BBB`xÚH 7Ê•{á™&TDOM/MTVNE 1250633849/S-1-5-21-2106152344-1726899929-2013803672BB`L7}Þ]µ™&TDOM/MTVNASIA 1250633849/S-1-5-21-1736519922-1920428879-1691616715BBBdÐFH6ÿرG™&TDOM/PLAYASUR 1250633849/S-1-5-21-2129485696-1739684832-945835055` üL7ªÒ~™&TDOM/VIACOM_CORP 1250633849/S-1-5-21-2140803266-1626024873-1299147156d@ND7S[ý™&TDOM/AD 1250633849/S-1-5-21-4186143834-2626045635-1021053583B\P5X=>J¨™&IDMAP/GID2SID/10000211 1249517309/S-1-5-21-1834383793-1770918451-929701000-107951p˜4X>±VË™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107951 1249517309/10000211pX=m†S˜™&IDMAP/UID2SID/10000337 1249517309/S-1-5-21-1834383793-1770918451-929701000-119188p°$X>—{ÝJ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119188 1249517309/10000337pèJX=m\ð$™&IDMAP/UID2SID/10000338 1249517309/S-1-5-21-1834383793-1770918451-929701000-119107p4X>—½Ì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119107 1249517309/10000338p°9X=ëá™&IDMAP/UID2SID/10000344 1249435951/S-1-5-21-1834383793-1770918451-929701000-148518pØ×X>ÇëO™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148518 1249435951/10000344p"X=E‚™&IDMAP/UID2SID/10000343 1250273007/S-1-5-21-1834383793-1770918451-929701000-148361p¾X>ï³Sî™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148361 1250273007/10000343p ºX= Й&IDMAP/UID2SID/10000215 1250725628/S-1-5-21-1834383793-1770918451-929701000-141235pÐ?X>Ù¿3™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141235 1250725628/10000215pð(¦)µS™&IDMAP/UID2SID/25238 1248799054/-B@?X=Í}™&IDMAP/UID2SID/10000256 1250639960/S-1-5-21-1834383793-1770918451-929701000-107870pØÉX>ËY‰™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107870 1250639960/10000256pÐX<mÚ™&IDMAP/UID2SID/10000335 1250016356/S-1-5-21-1834383793-1770918451-929701000-95298BpPÕX=Òü°ƒ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95298 1250016356/10000335BpøX<]~^\™&IDMAP/UID2SID/10000309 1249319817/S-1-5-21-1834383793-1770918451-929701000-79512Bp˜üX=r>á4™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79512 1249319817/10000309Bp8ãX= PF™&IDMAP/UID2SID/10000315 1250546951/S-1-5-21-1834383793-1770918451-929701000-143917p,âX>w"¯™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143917 1250546951/10000315p©X< ¹‰_™&IDMAP/UID2SID/10000317 1251151498/S-1-5-21-1834383793-1770918451-929701000-95238BpðÐX=Ê¢Y™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95238 1251151498/10000317BpùX=m‚¦L™&IDMAP/UID2SID/10000331 1251331910/S-1-5-21-1834383793-1770918451-929701000-148513pÐ’X>Ç{V™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148513 1251331910/10000331pÀ–X=]PN™&IDMAP/UID2SID/10000304 1251824050/S-1-5-21-1834383793-1770918451-929701000-141063p>X>ëf5™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141063 1251824050/10000304pØ$X< ß?‡™&IDMAP/UID2SID/10000310 1250714401/S-1-5-21-1834383793-1770918451-929701000-50388Bp (X=&cø™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-50388 1250714401/10000310Bp¨aX=m¬ À™&IDMAP/UID2SID/10000330 1250878988/S-1-5-21-1834383793-1770918451-929701000-148506p %X>GV¢™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148506 1250878988/10000330p ïX=½›A0™&IDMAP/UID2SID/10000321 1251156944/S-1-5-21-1834383793-1770918451-929701000-143923pÈÍX>÷—;S™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143923 1251156944/10000321pÔX=½K(•™&IDMAP/UID2SID/10000329 1250273129/S-1-5-21-1834383793-1770918451-929701000-148435pOX> ’ß™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148435 1250273129/10000329p@X=M³']™&IDMAP/GID2SID/10000458 1251149354/S-1-5-21-1834383793-1770918451-929701000-129629pŸX>‹ã`k™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129629 1251149354/10000458pðÉX<½u‹™&IDMAP/UID2SID/10000328 1250810099/S-1-5-21-1834383793-1770918451-929701000-87280Bp0¥X=&¿ÀÍ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87280 1250810099/10000328Bpˆ¬X;½Ö™&IDMAP/UID2SID/10000324 1251146424/S-1-5-21-1834383793-1770918451-929701000-1480BBp`X<¡õMd™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1480 1251146424/10000324BBpøëX=]c)1™&IDMAP/GID2SID/10000382 1251157458/S-1-5-21-1834383793-1770918451-929701000-118513pÀ²X>_Tí™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-118513 1251157458/10000382p¨X=]Œ¤™&IDMAP/GID2SID/10000381 1248890662/S-1-5-21-1834383793-1770918451-929701000-129546p˜ËX>ßâû™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129546 1248890662/10000381p ˆX=-u-»™&IDMAP/UID2SID/10000275 1251157458/S-1-5-21-1834383793-1770918451-929701000-119215p(¯X>Ã.0í™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119215 1251157458/10000275p3X=ç4™&IDMAP/UID2SID/10000290 1251141635/S-1-5-21-1834383793-1770918451-929701000-129688pïX>󛯼™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129688 1251141635/10000290p8X=½qÞ¼™&IDMAP/UID2SID/10000322 1251158331/S-1-5-21-1834383793-1770918451-929701000-148511p€X>ÇÂŒ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148511 1251158331/10000322p)X=½Å¤£™&IDMAP/UID2SID/10000320 1248824845/S-1-5-21-1834383793-1770918451-929701000-148375pP X>o©e™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148375 1248824845/10000320pàX=]¤„™&IDMAP/UID2SID/10000302 1251826461/S-1-5-21-1834383793-1770918451-929701000-148494p(ËX>ž–Í™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148494 1251826461/10000302p·X<êƒÁ™&IDMAP/UID2SID/10000291 1250717354/S-1-5-21-1834383793-1770918451-929701000-87529Bp°+X=žFª™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87529 1250717354/10000291BpèX=ÜÛ™&IDMAP/GID2SID/10000440 1251224362/S-1-5-21-1834383793-1770918451-929701000-129604p(¶X>‹‘¬™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129604 1251224362/10000440påX= ãìÒ™&IDMAP/UID2SID/10000316 1250644308/S-1-5-21-1834383793-1770918451-929701000-107715pø™X>Oƒ'™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107715 1250644308/10000316pPãX= &ì™&IDMAP/UID2SID/10000318 1251141808/S-1-5-21-1834383793-1770918451-929701000-107850p€0X>Ëî·Â™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107850 1251141808/10000318p˜çX= ‹y ™&IDMAP/UID2SID/10000312 1248801216/S-1-5-21-1834383793-1770918451-929701000-148504px°X>GöNØ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148504 1248801216/10000312p`FX=òxh™&IDMAP/GID2SID/10000441 1250632968/S-1-5-21-1834383793-1770918451-929701000-143927pxX>0uƒ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-143927 1250632968/10000441pXRX==ûK¼™&IDMAP/GID2SID/10000422 1251822639/S-1-5-21-1834383793-1770918451-929701000-148502pŒX>ßn «™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148502 1251822639/10000422pÐ#X=B÷ó™&IDMAP/UID2SID/10000295 1250525522/S-1-5-21-1834383793-1770918451-929701000-148311pØ÷X>o¨~™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148311 1250525522/10000295pøòX=½ó´÷™&IDMAP/UID2SID/10000125 1251141450/S-1-5-21-1834383793-1770918451-929701000-129580pРX>GâwŽ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129580 1251141450/10000125pxèX= µÜ™&IDMAP/UID2SID/10000311 1249660297/S-1-5-21-1834383793-1770918451-929701000-148288pŒØX>Cµ×o™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148288 1249660297/10000311pHvX= 7³¹™&IDMAP/UID2SID/10000314 1250637001/S-1-5-21-1834383793-1770918451-929701000-148454p@ËX>Èù@™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148454 1250637001/10000314pÐ8X=ÍÑÆõ™&IDMAP/UID2SID/10000254 1250697509/S-1-5-21-1834383793-1770918451-929701000-107733p¨ZX>Z$™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107733 1250697509/10000254p 3X< a-™&IDMAP/UID2SID/10000313 1250708830/S-1-5-21-1834383793-1770918451-929701000-87285Bp°2X=¦Ê„=™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87285 1250708830/10000313BptX=ݯX¾™&IDMAP/UID2SID/10000283 1251152830/S-1-5-21-1834383793-1770918451-929701000-148134pH§X>°_e™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148134 1251152830/10000283p :X=ÝÙ»1™&IDMAP/UID2SID/10000282 1251152830/S-1-5-21-1834383793-1770918451-929701000-148232p¸oX>É«¢™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148232 1251152830/10000282pà¿X=Íû)i™&IDMAP/UID2SID/10000253 1250817897/S-1-5-21-1834383793-1770918451-929701000-148133pX>y™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148133 1250817897/10000253p˜ X=Í%Ü™&IDMAP/UID2SID/10000252 1250905890/S-1-5-21-1834383793-1770918451-929701000-148467p¸X>› ÕR™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148467 1250905890/10000252pÏX=-KÊG™&IDMAP/UID2SID/10000276 1250642444/S-1-5-21-1834383793-1770918451-929701000-148405p(çX>›l6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148405 1250642444/10000276p8SX=]¤”N™&IDMAP/UID2SID/10000202 1249922180/S-1-5-21-1834383793-1770918451-929701000-143764p°X>ŸªŒ6™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143764 1249922180/10000202p(pX=}æ»›™&IDMAP/UID2SID/10000169 1250872003/S-1-5-21-1834383793-1770918451-929701000-143826pPX>KnÖz™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143826 1250872003/10000169pèèX=-Ÿ.™&IDMAP/UID2SID/10000274 1250720448/S-1-5-21-1834383793-1770918451-929701000-143924pÈéX>÷G"¸™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143924 1250720448/10000274pÈ`X<=ÑèH™&IDMAP/GID2SID/10000423 1251824032/S-1-5-21-1834383793-1770918451-929701000-95355Bpˆ[X=:NÕ'™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-95355 1251824032/10000423Bp 6X==ÿø™&IDMAP/GID2SID/10000428 1250282972/S-1-5-21-2140803266-1626024873-1299147156-31601p áX>:d.D™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-31601 1250282972/10000428pxX<=)\{™&IDMAP/GID2SID/10000427 1250282972/S-1-5-21-1834383793-1770918451-929701000-42569Bp X=æ¥Én™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42569 1250282972/10000427Bp@9X<=S¿î™&IDMAP/GID2SID/10000426 1250282972/S-1-5-21-1834383793-1770918451-929701000-42575Bp0X=’ Fé™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-42575 1250282972/10000426Bpp4X==}"b™&IDMAP/GID2SID/10000425 1251156944/S-1-5-21-1834383793-1770918451-929701000-148356p ›X>ÇL ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148356 1251156944/10000425p°@X==§…Õ™&IDMAP/GID2SID/10000424 1250282972/S-1-5-21-1834383793-1770918451-929701000-129729püæX>7zr™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129729 1250282972/10000424p€7X<]ü‡¶™&IDMAP/UID2SID/10000306 1250282972/S-1-5-21-1834383793-1770918451-929701000-25076BpœâX=z¶H³™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-25076 1250282972/10000306Bp¸OX=]&ë)™&IDMAP/UID2SID/10000305 1250282972/S-1-5-21-1834383793-1770918451-929701000-143919p°X>w‚|Í™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143919 1250282972/10000305pØUX=lZg™&IDMAP/UID2SID/10000294 1250790522/S-1-5-21-1834383793-1770918451-929701000-143654ppâX>s;LL™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143654 1250790522/10000294pøtX=ÍyÓ™&IDMAP/UID2SID/10000150 1250873129/S-1-5-21-1834383793-1770918451-929701000-107732p(îX>ª¿™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107732 1250873129/10000150p¸ØX=m†Ób™&IDMAP/UID2SID/10000237 1250883037/S-1-5-21-1834383793-1770918451-929701000-143858p(œX>Ënî™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143858 1250883037/10000237p˜ÙX=m°6Ö™&IDMAP/UID2SID/10000236 1250883036/S-1-5-21-1834383793-1770918451-929701000-143884p ¾X>KOô™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143884 1250883036/10000236pˆX<?¨Š™&IDMAP/UID2SID/10000142 1250723949/S-1-5-21-1834383793-1770918451-929701000-79422Bp:X=xšn™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-79422 1250723949/10000142Bp¨¤X=E™&IDMAP/UID2SID/10000143 1251133100/S-1-5-21-1834383793-1770918451-929701000-129687p˜…X>óëßW™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129687 1251133100/10000143p¨X=]Îw÷™&IDMAP/UID2SID/10000301 1251824032/S-1-5-21-1834383793-1770918451-929701000-108847pàŽX>K‰?o™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-108847 1251824032/10000301p AX; ¢€™&IDMAP/GID2SID/10000396 1248213312/S-1-5-21-4186143834-2626045635-1021053583-515BBp˜àX<*mÓ¨™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-515 1248213312/10000396BBpØšX<šj&™&IDMAP/UID2SID/10000299 1248213312/S-1-5-21-4186143834-2626045635-1021053583-1251Bp7X=7^7™&IDMAP/SID2UID/S-1-5-21-4186143834-2626045635-1021053583-1251 1248213312/10000299BpøfX= Ìdó™&IDMAP/GID2SID/10000395 1248213312/S-1-5-21-2140803266-1626024873-1299147156-25446px'X>â6/¢™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25446 1248213312/10000395pøÝX= öÇf™&IDMAP/GID2SID/10000394 1248213312/S-1-5-21-1834383793-1770918451-929701000-122075p8EX>ÕR™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122075 1248213312/10000394px·X< +Ú™&IDMAP/GID2SID/10000393 1248213312/S-1-5-21-1834383793-1770918451-929701000-68183BpH}X=>ˆù/™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-68183 1248213312/10000393Bpà;X= JŽM™&IDMAP/GID2SID/10000392 1248213311/S-1-5-21-1834383793-1770918451-929701000-122068pøX>ƒ¯ßÊ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-122068 1248213311/10000392p˜^X< tñÀ™&IDMAP/GID2SID/10000391 1248213311/S-1-5-21-4186143834-2626045635-1021053583-1647BpXéX=#>U™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1647 1248213311/10000391Bpø?X< žT4™&IDMAP/GID2SID/10000390 1248213311/S-1-5-21-4186143834-2626045635-1021053583-1211Bpp;X=PÊ·™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1211 1248213311/10000390BpøäX<]=s ™&IDMAP/GID2SID/10000389 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1246BpðNX=£Ú<™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1246 1251822594/10000389BpäX<]gÖ|™&IDMAP/GID2SID/10000388 1248213311/S-1-5-21-4186143834-2626045635-1021053583-1245Bp›X=#Ó²Y™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1245 1248213311/10000388BpxÅX<]‘9ð™&IDMAP/GID2SID/10000387 1248213311/S-1-5-21-4186143834-2626045635-1021053583-7625BppBX=Ë_‚W™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7625 1248213311/10000387Bp8ÎX<]»œc™&IDMAP/GID2SID/10000386 1248213310/S-1-5-21-4186143834-2626045635-1021053583-1194Bp0»X=ÿ½©Ì™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1194 1248213310/10000386BpØcX<]åÿÖ™&IDMAP/GID2SID/10000385 1248213310/S-1-5-21-4186143834-2626045635-1021053583-1255BpXYX=Ï Ì`™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1255 1248213310/10000385BpPJX<]cJ™&IDMAP/GID2SID/10000384 1251822594/S-1-5-21-4186143834-2626045635-1021053583-1247BpðhX=#> ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1247 1251822594/10000384BpˆžX<]9ƽ™&IDMAP/GID2SID/10000383 1248213305/S-1-5-21-4186143834-2626045635-1021053583-7619Bp°NX=üÝ™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7619 1248213305/10000383Bp80X<ÄÍ™™&IDMAP/UID2SID/10000298 1248213305/S-1-5-21-4186143834-2626045635-1021053583-1662Bpè”X=cÍPW™&IDMAP/SID2UID/S-1-5-21-4186143834-2626045635-1021053583-1662 1248213305/10000298BpðµX=-Í ¸™&IDMAP/UID2SID/10000179 1250898780/S-1-5-21-1834383793-1770918451-929701000-143653pÈžX>s‹eç™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143653 1250898780/10000179p8X=Ý1/d™&IDMAP/UID2SID/10000286 1249607338/S-1-5-21-1834383793-1770918451-929701000-143682pÌÝX>ó{ô+™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143682 1249607338/10000286pXDX=]·ï™&IDMAP/GID2SID/10000380 1249576851/S-1-5-21-1834383793-1770918451-929701000-113649pÀêX>‹N™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113649 1249576851/10000380pEX=­Ví™&IDMAP/GID2SID/10000379 1249576851/S-1-5-21-1834383793-1770918451-929701000-126724p¼ÓX>7­Ø™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126724 1249576851/10000379pø8X<-Éó¡™&IDMAP/UID2SID/10000273 1249576851/S-1-5-21-1834383793-1770918451-929701000-87132BpœéX=Ê 1£™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87132 1249576851/10000273BpxÓX=-óV™&IDMAP/UID2SID/10000272 1249576851/S-1-5-21-1834383793-1770918451-929701000-143734pŒÑX> ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143734 1249576851/10000272pøÈX= eà ™&IDMAP/UID2SID/10000119 1251141204/S-1-5-21-1834383793-1770918451-929701000-148269pÈ—X>Cúo™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148269 1251141204/10000119p8"X<}ŸD™&IDMAP/UID2SID/10000268 1251332584/S-1-5-21-1834383793-1770918451-929701000-95887BpÀJX=¦°i™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-95887 1251332584/10000268BpèX<–½Ú™&IDMAP/UID2SID/10000293 1251218467/S-1-5-21-1834383793-1770918451-929701000-56083Bp¬5X=¦W±ö™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-56083 1251218467/10000293Bp(“X=À N™&IDMAP/UID2SID/10000292 1251218467/S-1-5-21-1834383793-1770918451-929701000-148487péX>›x#™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148487 1251218467/10000292pØÐX=Í}€Ù™&IDMAP/UID2SID/10000156 1251130673/S-1-5-21-1834383793-1770918451-929701000-119384pàœX>ï.uÅ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119384 1251130673/10000156pèX=}:¸™&IDMAP/UID2SID/10000267 1250527000/S-1-5-21-1834383793-1770918451-929701000-107719p°ÒX>»™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107719 1250527000/10000267p´ÈX=­ÐŠû™&IDMAP/GID2SID/10000370 1250637001/S-1-5-21-1834383793-1770918451-929701000-148229pLÚX>Ûüq™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148229 1250637001/10000370pX¸X=ͧc‚™&IDMAP/UID2SID/10000255 1251221622/S-1-5-21-1834383793-1770918451-929701000-118468pàX>›½zÌ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-118468 1251221622/10000255pøX=ݳ ™&IDMAP/UID2SID/10000289 1248110172/S-1-5-21-1834383793-1770918451-929701000-128816p¸ÊX>Ë8¹ý™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-128816 1248110172/10000289pX=X=Í):(™&IDMAP/UID2SID/10000258 1251218400/S-1-5-21-1834383793-1770918451-929701000-148496p{X>þc—™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148496 1251218400/10000258p87X=ÝÝh}™&IDMAP/UID2SID/10000288 1250873479/S-1-5-21-1834383793-1770918451-929701000-107559pD+ø+fæþÙBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,à‡X=î0N™&IDMAP/GID2SID/10000819 1251836362/S-1-5-21-1834383793-1770918451-929701000-141393p¸3X>•`™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-141393 1251836362/10000819p0`X=½›Áe™&IDMAP/UID2SID/10000421 1251836362/S-1-5-21-1834383793-1770918451-929701000-146636p ©X=}æ;Ñ™&IDMAP/UID2SID/10000269 1251826461/S-1-5-21-1834383793-1770918451-929701000-119073p€µX<½Å$Ù™&IDMAP/UID2SID/10000420 1251826461/S-1-5-21-1834383793-1770918451-929701000-45487Bp`‹X=¦Õï7™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-45487 1251826461/10000420Bp`¡X=ÝÌ1™&IDMAP/GID2SID/10000809 1251825059/S-1-5-21-2140803266-1626024873-1299147156-33834p X>ˆJÅ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-33834 1251825059/10000809p X=Ý1/¥™&IDMAP/GID2SID/10000808 1251825059/S-1-5-21-2140803266-1626024873-1299147156-37682pˆX>:ÀŽ’™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-37682 1251825059/10000808ppeX<Ý[’™&IDMAP/GID2SID/10000807 1251825059/S-1-5-21-1834383793-1770918451-929701000-56883BpÈÔX=>0Pþ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56883 1251825059/10000807BpЋX<Ý…õ‹™&IDMAP/GID2SID/10000806 1251825058/S-1-5-21-1834383793-1770918451-929701000-56882Bp ‰X=¾ú(™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56882 1251825058/10000806Bp ±X<ݯXÿ™&IDMAP/GID2SID/10000805 1251825058/S-1-5-21-1834383793-1770918451-929701000-56884BpÃX=¾ewá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-56884 1251825058/10000805Bp؃X<ÝÙ»r™&IDMAP/GID2SID/10000804 1251825058/S-1-5-21-1834383793-1770918451-929701000-88296Bp X=jÏ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-88296 1251825058/10000804BpÈ•X; eC®™&IDMAP/UID2SID/10000419 1251825058/S-1-5-21-1834383793-1770918451-929701000-9105BBp êX=Ý-‚Y™&IDMAP/GID2SID/10000802 1251824351/S-1-5-21-2140803266-1626024873-1299147156-13928pÈ(X>>Là™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-13928 1251824351/10000802p”X=ÝWåÌ™&IDMAP/GID2SID/10000801 1251824350/S-1-5-21-2140803266-1626024873-1299147156-24501pˆÏX>Ž*ÊV™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24501 1251824350/10000801pè X=ÝH@™&IDMAP/GID2SID/10000800 1251824350/S-1-5-21-2140803266-1626024873-1299147156-20408pàIX>âÀÜ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20408 1251824350/10000800pPSX= $Øû™&IDMAP/GID2SID/10000799 1251824350/S-1-5-21-2140803266-1626024873-1299147156-15905pØGX>>Ѿ…™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-15905 1251824350/10000799p¤ÅX; ¦!™&IDMAP/UID2SID/10000418 1251824350/S-1-5-21-1834383793-1770918451-929701000-1428BBpfX<Ã×Ì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1428 1251824350/10000418BBpðŠX==§ ™&IDMAP/GID2SID/10000324 1251823992/S-1-5-21-2140803266-1626024873-1299147156-19915p¨˜X>¾fž™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-19915 1251823992/10000324p˜¿X==%/ú™&IDMAP/GID2SID/10000321 1251823992/S-1-5-21-2140803266-1626024873-1299147156-22860p HX>’hZ¿™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-22860 1251823992/10000321p€X= xžâ™&IDMAP/GID2SID/10000797 1251823992/S-1-5-21-2140803266-1626024873-1299147156-25508p¨ãX>Žúxæ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-25508 1251823992/10000797pÀX<=ÿxÒ™&IDMAP/GID2SID/10000328 1251823992/S-1-5-21-4186143834-2626045635-1021053583-7657Bpˆ'X=Ïw3™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-7657 1251823992/10000328Bp ªX==)ÜE™&IDMAP/GID2SID/10000327 1251823992/S-1-5-21-1834383793-1770918451-929701000-105930p »X>–a™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-105930 1251823992/10000327p€§X< ¹ •™&IDMAP/UID2SID/10000417 1251823991/S-1-5-21-1834383793-1770918451-929701000-44651Bp¹X=¢ç ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-44651 1251823991/10000417Bp ¦X< ÌdÉ™&IDMAP/GID2SID/10000795 1251823775/S-1-5-21-1834383793-1770918451-929701000-43407Bp¥X=Þàîþ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43407 1251823775/10000795BpØnX< öÇ<™&IDMAP/GID2SID/10000794 1251823775/S-1-5-21-1834383793-1770918451-929701000-86979BpèX=’?Ü®™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-86979 1251823775/10000794Bp0TX= +°™&IDMAP/GID2SID/10000793 1251823775/S-1-5-21-1834383793-1770918451-929701000-156559pQX>_JÞ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-156559 1251823775/10000793pLFX< ãl™&IDMAP/UID2SID/10000416 1251823775/S-1-5-21-1834383793-1770918451-929701000-52123Bp ÏX=žýÍ_™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-52123 1251823775/10000416Bp;X< Ð{™&IDMAP/UID2SID/10000415 1251823756/S-1-5-21-1834383793-1770918451-929701000-56596BpˆTX=M…—>™&IDMAP/GID2SID/10000753 1251836362/S-1-5-21-1834383793-1770918451-929701000-161746p ‚X>7xÀØ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-161746 1251836362/10000753pp•X=¶™&IDMAP/UID2SID/10000396 1251227786/S-1-5-21-1834383793-1770918451-929701000-162831pÚX>Ë3ò4™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162831 1251227786/10000396p<¿X=]øZ ™&IDMAP/UID2SID/10000400 1251221604/S-1-5-21-1834383793-1770918451-929701000-162836pÀ.X>Ë£s-™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162836 1251221604/10000400pØ+X=—(™&IDMAP/UID2SID/10000346 1251217829/S-1-5-21-1834383793-1770918451-929701000-148520pȱX>G¡ ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148520 1251217829/10000346pBX=ÝÙ;=™&IDMAP/GID2SID/10000704 1251823334/S-1-5-21-1834383793-1770918451-929701000-164366pà²X>‡üÉê™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-164366 1251823334/10000704pèÌX<î°B™&IDMAP/UID2SID/10000397 1251148929/S-1-5-21-1834383793-1770918451-929701000-87035Bpˆ*X=JªF™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-87035 1251148929/10000397Bp@X= 73„™&IDMAP/UID2SID/10000214 1251132082/S-1-5-21-1834383793-1770918451-929701000-143829p–X>K~Š©™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143829 1251132082/10000214pÀÕX<Bw)™&IDMAP/UID2SID/10000395 1251131643/S-1-5-21-1834383793-1770918451-929701000-50238Bp@¯X=ÊB5™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-50238 1251131643/10000395Bp8zX=lÚœ™&IDMAP/UID2SID/10000394 1250901558/S-1-5-21-1834383793-1770918451-929701000-155079pxxX>k¼¯É™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-155079 1250901558/10000394p‰X=À ƒ™&IDMAP/UID2SID/10000392 1250892461/S-1-5-21-1834383793-1770918451-929701000-162830ppX>˃ Й&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162830 1250892461/10000392p¬!X=í9¤«™&IDMAP/GID2SID/10000736 1250868294/S-1-5-21-1834383793-1770918451-929701000-162201p8ÿX>Û„ý™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-162201 1250868294/10000736pà-X=íj’™&IDMAP/GID2SID/10000734 1250802845/S-1-5-21-1834383793-1770918451-929701000-126298pÐwX>[ø™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126298 1250802845/10000734pÈRX=í·Í™&IDMAP/GID2SID/10000733 1250802845/S-1-5-21-1834383793-1770918451-929701000-126309p ¥X>‡Ë¦'™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126309 1250802845/10000733pè_X=íá0y™&IDMAP/GID2SID/10000732 1250802845/S-1-5-21-1834383793-1770918451-929701000-125539p€ìX>_ßî™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-125539 1250802845/10000732pLX=í ”ì™&IDMAP/GID2SID/10000731 1250802845/S-1-5-21-1834383793-1770918451-929701000-126308pPÀX>‡À™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126308 1250802845/10000731p€åX=í5÷_™&IDMAP/GID2SID/10000730 1250802845/S-1-5-21-1834383793-1770918451-929701000-163450pÌäX>³àóã™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163450 1250802845/10000730pHÑX==Õ5™&IDMAP/GID2SID/10000729 1250802845/S-1-5-21-1834383793-1770918451-929701000-126310pL8X>ѱ~™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126310 1250802845/10000729p€)X==ÿx¨™&IDMAP/GID2SID/10000728 1250802845/S-1-5-21-1834383793-1770918451-929701000-126223pà£X>ÛÜs‰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126223 1250802845/10000728pHßX==)Ü™&IDMAP/GID2SID/10000727 1250802845/S-1-5-21-1834383793-1770918451-929701000-126305pP«X>‡ ”™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126305 1250802845/10000727pÌX==S?™&IDMAP/GID2SID/10000726 1250802845/S-1-5-21-1834383793-1770918451-929701000-126434ppÆX>³5´ß™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126434 1250802845/10000726pð0X==}¢™&IDMAP/GID2SID/10000725 1250802845/S-1-5-21-1834383793-1770918451-929701000-163462pÀ¤X>3vè™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163462 1250802845/10000725pÓX<=§v™&IDMAP/GID2SID/10000724 1250802845/S-1-5-21-1834383793-1770918451-929701000-32714Bp0³X= "ÔC™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-32714 1250802845/10000724BphGX<=Ñhé™&IDMAP/GID2SID/10000723 1250802845/S-1-5-21-1834383793-1770918451-929701000-40067Bp0¬X=æ:Å™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-40067 1250802845/10000723Bp@X<=ûË\™&IDMAP/GID2SID/10000722 1250802845/S-1-5-21-1834383793-1770918451-929701000-31839Bp°¶X=â ¿@™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-31839 1250802845/10000722Bpˆ—X==%/Й&IDMAP/GID2SID/10000721 1250802845/S-1-5-21-1834383793-1770918451-929701000-112531pX/X>__.4™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112531 1250802845/10000721p ·X<=O’C™&IDMAP/GID2SID/10000720 1250802845/S-1-5-21-1834383793-1770918451-929701000-25192Bp X=j,Ýž™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-25192 1250802845/10000720Bp ³X<î°™&IDMAP/GID2SID/10000719 1250802845/S-1-5-21-1834383793-1770918451-929701000-40068BphìX=fpìë™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-40068 1250802845/10000719BpÈ÷X<Œ™&IDMAP/GID2SID/10000718 1250802845/S-1-5-21-1834383793-1770918451-929701000-40069BplX=æ¥Ï™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-40069 1250802845/10000718BphÐX=ÝÝè²™&IDMAP/UID2SID/10000388 1250802845/S-1-5-21-1834383793-1770918451-929701000-117852pð­X>ËNðÚ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-117852 1250802845/10000388pHAX=ÝŸÚ™&IDMAP/UID2SID/10000381 1250789362/S-1-5-21-1834383793-1770918451-929701000-148066pHHX>ëv‰Ñ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148066 1250789362/10000381p0X=ÝŸ°™&IDMAP/GID2SID/10000703 1251823992/S-1-5-21-1834383793-1770918451-929701000-126387p°cX>‡w™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126387 1251823992/10000703pˆëX=Ý-$™&IDMAP/GID2SID/10000702 1251825058/S-1-5-21-1834383793-1770918451-929701000-126428pà«X>3À'™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126428 1251825058/10000702pyX=ÝWe—™&IDMAP/GID2SID/10000701 1250789304/S-1-5-21-1834383793-1770918451-929701000-126437pHOX>³Eh™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126437 1250789304/10000701pH‹X<ÝÈ ™&IDMAP/GID2SID/10000700 1250789304/S-1-5-21-1834383793-1770918451-929701000-36752Bp8–X=º–Ó™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-36752 1250789304/10000700BpÈ=X=Ý[ ™&IDMAP/UID2SID/10000385 1250789303/S-1-5-21-1834383793-1770918451-929701000-107912pH%X>w²™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107912 1250789303/10000385p˜X=MAø™&IDMAP/GID2SID/10000450 1251826461/S-1-5-21-1834383793-1770918451-929701000-113651p`¶X> öΙ&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113651 1251826461/10000450prX<¢_Í™&IDMAP/GID2SID/10000449 1250727725/S-1-5-21-1834383793-1770918451-929701000-72021BpX=6¥Í™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-72021 1250727725/10000449BpíX<ÌÂ@™&IDMAP/GID2SID/10000448 1250727725/S-1-5-21-1834383793-1770918451-929701000-38288Bp€ X=¾‹ÃÕ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38288 1250727725/10000448BpýX=ö%´™&IDMAP/GID2SID/10000447 1250727725/S-1-5-21-1834383793-1770918451-929701000-129730pèCX>·"…É™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129730 1250727725/10000447plX< ‰'™&IDMAP/GID2SID/10000446 1250727725/S-1-5-21-1834383793-1770918451-929701000-52150Bp\òX=ºâBh™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-52150 1250727725/10000446BpHÊX<Jìš™&IDMAP/GID2SID/10000445 1250727725/S-1-5-21-1834383793-1770918451-929701000-38267Bpp X=æâiä™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-38267 1250727725/10000445BpìX<tO™&IDMAP/GID2SID/10000444 1250727725/S-1-5-21-1834383793-1770918451-929701000-72022Bp&X=¶P̰™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-72022 1250727725/10000444Bp@ŽX=ݯØó™&IDMAP/UID2SID/10000383 1250727725/S-1-5-21-1834383793-1770918451-929701000-108002pÀX>ëuW±™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-108002 1250727725/10000383p X=ÝÙ;g™&IDMAP/UID2SID/10000382 1250715069/S-1-5-21-1834383793-1770918451-929701000-119502p¨ÕX>G– ð™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119502 1250715069/10000382p¸:X=Ý-N™&IDMAP/UID2SID/10000380 1250713298/S-1-5-21-1834383793-1770918451-929701000-162826pxJX>KnLJ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162826 1250713298/10000380pÀ¹X=-Í #™&IDMAP/UID2SID/10000379 1250708248/S-1-5-21-1834383793-1770918451-929701000-162825p4X>K¾eå™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162825 1250708248/10000379pÐX=-!ç ™&IDMAP/UID2SID/10000377 1250616247/S-1-5-21-1834383793-1770918451-929701000-148175p€ X>6ãV™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148175 1250616247/10000377p¨ÿX=-KJ}™&IDMAP/UID2SID/10000376 1250545067/S-1-5-21-1834383793-1770918451-929701000-119375pä+X>o©4G™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-119375 1250545067/10000376p€>X=-u­ð™&IDMAP/UID2SID/10000375 1251138855/S-1-5-21-1834383793-1770918451-929701000-162822p˜X>K®±¶™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162822 1251138855/10000375p ,X=-És×™&IDMAP/UID2SID/10000373 1251147240/S-1-5-21-1834383793-1770918451-929701000-107933p€"X>wÍ62™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107933 1251147240/10000373p ÖX=ͧ㷙&IDMAP/UID2SID/10000355 1250870551/S-1-5-21-1834383793-1770918451-929701000-162815p@ÙX>ˈ>™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162815 1250870551/10000355px<X=-óÖJ™&IDMAP/UID2SID/10000372 1250211480/S-1-5-21-1834383793-1770918451-929701000-162820pÐÑX>KNäì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162820 1250211480/10000372p—X=-G1™&IDMAP/UID2SID/10000370 1250200570/S-1-5-21-1834383793-1770918451-929701000-162819p\ÝX>ËHÙ•™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162819 1250200570/10000370p`1X=}ŽHÔ™&IDMAP/UID2SID/10000365 1250123071/S-1-5-21-1834383793-1770918451-929701000-107826ppÍX>Knªv™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107826 1250123071/10000365pÐíX==S¿Y™&IDMAP/GID2SID/10000626 1251141210/S-1-5-21-1834383793-1770918451-929701000-126435p€ŒX>³åšD™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126435 1251141210/10000626p<ìX==}"Í™&IDMAP/GID2SID/10000625 1251141210/S-1-5-21-1834383793-1770918451-929701000-126439pl#X>³¥5Ø™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126439 1251141210/10000625p¬ÐX<=§…@™&IDMAP/GID2SID/10000624 1251825059/S-1-5-21-1834383793-1770918451-929701000-46326Bp¨«X=¶ÛG™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-46326 1251825059/10000624Bp8X<=Ñè³™&IDMAP/GID2SID/10000623 1251141210/S-1-5-21-1834383793-1770918451-929701000-43571BpÛX=’3«™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-43571 1251141210/10000623BplÒX==ûK'™&IDMAP/GID2SID/10000622 1251141210/S-1-5-21-1834383793-1770918451-929701000-126436pèXX>³•©™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126436 1251141210/10000622p`æX==%¯š™&IDMAP/GID2SID/10000621 1251141210/S-1-5-21-1834383793-1770918451-929701000-126438p(õX>³õNs™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-126438 1251141210/10000621pX==O™&IDMAP/GID2SID/10000620 1251141210/S-1-5-21-1834383793-1770918451-929701000-113227pÀX>Ûœƒf™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-113227 1251141210/10000620pÀÜX<î0ã™&IDMAP/GID2SID/10000619 1251141210/S-1-5-21-1834383793-1770918451-929701000-35587Bp°šX=>V{o™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-35587 1251141210/10000619Bp(ƒX=”V™&IDMAP/GID2SID/10000618 1251141210/S-1-5-21-1834383793-1770918451-929701000-107859ph2X>c÷rë™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-107859 1251141210/10000618pÑX=B÷É™&IDMAP/GID2SID/10000617 1251141210/S-1-5-21-1834383793-1770918451-929701000-112793pX•X>·s_™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-112793 1251141210/10000617p0/X;ÍyÓø™&IDMAP/UID2SID/10000350 1251141210/S-1-5-21-1834383793-1770918451-929701000-1401BBpè°X<M/g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-1401 1251141210/10000350BBphÞX=}â»™&IDMAP/UID2SID/10000363 1250118308/S-1-5-21-1834383793-1770918451-929701000-162818pˆX>˘ò0™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162818 1250118308/10000363p`#X<Í}€D™&IDMAP/UID2SID/10000356 1250784084/S-1-5-21-1834383793-1770918451-929701000-64745BpÜÒX=ö3ØÓ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-64745 1250784084/10000356Bp<ÞX=½ó´b™&IDMAP/UID2SID/10000325 1250095624/S-1-5-21-1834383793-1770918451-929701000-148418p@$X>²÷G™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148418 1250095624/10000325px X=ÍÿVê™&IDMAP/UID2SID/10000359 1250809196/S-1-5-21-1834383793-1770918451-929701000-162817pÈX>Ëè Ì™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162817 1250809196/10000359p0ëX= N;™&IDMAP/GID2SID/10000598 1251837380/S-1-5-21-1834383793-1770918451-929701000-129656phUX> t"æ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-129656 1251837380/10000598pŒßX; xžw™&IDMAP/GID2SID/10000597 1251823756/S-1-5-21-1834383793-1770918451-929701000-9881BBp<X<åÇLÕ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-9881 1251823756/10000597BBpŒíX< ¢ë™&IDMAP/GID2SID/10000596 1251837380/S-1-5-21-1834383793-1770918451-929701000-34573BpŠX=’FZ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-34573 1251837380/10000596Bp äX< Ìd^™&IDMAP/GID2SID/10000595 1251837380/S-1-5-21-1834383793-1770918451-929701000-65873Bp|X=’N?Û™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-65873 1251837380/10000595Bp0äX=í9$v™&IDMAP/GID2SID/10000636 1250027977/S-1-5-21-1834383793-1770918451-929701000-148240pÓX>Û7¤X™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148240 1250027977/10000636p\ÖX;Í)º]™&IDMAP/UID2SID/10000358 1250027977/S-1-5-21-1834383793-1770918451-929701000-3687BBp èX<U9»—™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-3687 1250027977/10000358BBpàX=ÍSÑ™&IDMAP/UID2SID/10000357 1250017630/S-1-5-21-1834383793-1770918451-929701000-162816pˆÁX>Ë8%g™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-162816 1250017630/10000357pX±X=ÍÑF+™&IDMAP/UID2SID/10000354 1250010978/S-1-5-21-1834383793-1770918451-929701000-154305püßX>ï2îG™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-154305 1250010978/10000354p(-X=ÍOp…™&IDMAP/UID2SID/10000351 1250561251/S-1-5-21-1834383793-1770918451-929701000-148519p˜îX>Ç›÷³™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-148519 1250561251/10000351p0üX=òÍ™&IDMAP/UID2SID/10000349 1249930193/S-1-5-21-1834383793-1770918451-929701000-143850pX>ËîãÆ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143850 1249930193/10000349p8>X<CUA™&IDMAP/UID2SID/10000348 1250615979/S-1-5-21-1834383793-1770918451-929701000-95251BpìÜX=>J~™&IDMAP/GID2SID/10000611 1250805470/S-1-5-21-1834383793-1770918451-929701000-148264p(PX>Ûb²™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148264 1250805470/10000611pHX&û¯ò0™&NBT/NEW-BRDC01.MTVNE.AD.VIACOM.COM#20 1251229216/166.77.172.123:00.64.99.4:389BBp8êX=ÝÌÆ™&IDMAP/GID2SID/10000609 1250805470/S-1-5-21-1834383793-1770918451-929701000-148266p¦X>ÛÂZ|™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148266 1250805470/10000609p¸%X=Ý[’­™&IDMAP/GID2SID/10000607 1250805470/S-1-5-21-1834383793-1770918451-929701000-148262pHX>ÛÀè™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148262 1250805470/10000607p DX=ݯX”™&IDMAP/GID2SID/10000605 1250805470/S-1-5-21-1834383793-1770918451-929701000-148267pXX>ÛrAá™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148267 1250805470/10000605p¼áX=ÝHÕ™&IDMAP/GID2SID/10000600 1251130207/S-1-5-21-1834383793-1770918451-929701000-148521p (X>ß)ˆ ™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148521 1251130207/10000600pÌ4X=m°¶ ™&IDMAP/UID2SID/10000336 1250902730/S-1-5-21-1834383793-1770918451-929701000-141062p ëX>ë¶N ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-141062 1250902730/10000336pPêX=i i™&IDMAP/UID2SID/10000341 1249604757/S-1-5-21-1834383793-1770918451-929701000-156773p°GX>0Xk™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-156773 1249604757/10000341pìX=“nÜ™&IDMAP/UID2SID/10000340 1249604757/S-1-5-21-1834383793-1770918451-929701000-107684p°çX>óÛ•ñ™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-107684 1249604757/10000340p,ðX=Ý:™&IDMAP/UID2SID/10000081 1251228438/S-1-5-21-1834383793-1770918451-929701000-129672p X>sF7|™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-129672 1251228438/10000081pðEX=ýo)™&IDMAP/GID2SID/10000469 1251133100/S-1-5-21-1834383793-1770918451-929701000-148514pL1X>_X™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-148514 1251133100/10000469p,ÛX=]z±™&IDMAP/UID2SID/10000303 1250197567/S-1-5-21-1834383793-1770918451-929701000-143720p˜X>ŸU™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-143720 1250197567/10000303p|ÜX=­¦§½™&IDMAP/GID2SID/10000471 1251825059/S-1-5-21-1834383793-1770918451-929701000-164035pÐOX>ÿ!Ç™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-164035 1251825059/10000471pX÷X=­Ð 1™&IDMAP/GID2SID/10000470 1251825058/S-1-5-21-1834383793-1770918451-929701000-153022pÐVX>ƒ¹{™™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-153022 1251825058/10000470pèóX= ]™&IDMAP/GID2SID/10000546 1249523691/S-1-5-21-1834383793-1770918451-929701000-156570pX>_…Ë™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-156570 1249523691/10000546pLúX=JlЙ&IDMAP/GID2SID/10000545 1249523690/S-1-5-21-1834383793-1770918451-929701000-163262p dX>Û¶‚™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163262 1249523690/10000545p¨õX=tÏC™&IDMAP/GID2SID/10000544 1249523690/S-1-5-21-1834383793-1770918451-929701000-163260pÌÖX>ۢ踙&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-163260 1249523690/10000544pØX=ž2·™&IDMAP/GID2SID/10000543 1249523690/S-1-5-21-1834383793-1770918451-929701000-156572pLÓX>_åÝ”™&IDMAP/SID2GID/S-1-5-21-1834383793-1770918451-929701000-156572 1249523690/10000543pHøX=È•*™&IDMAP/GID2SID/10000542 1249523690/S-1-5-21-2140803266-1626024873-1299147156-24690p ÕX>º•]õ™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-24690 1249523690/10000542pP'X=òø™&IDMAP/GID2SID/10000541 1249523690/S-1-5-21-2140803266-1626024873-1299147156-34233p0DX> ~,™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34233 1249523690/10000541pLèX=\™&IDMAP/GID2SID/10000540 1249523689/S-1-5-21-2140803266-1626024873-1299147156-34232p\ëX> ÎEž™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34232 1249523689/10000540p8aX=í»zæ™&IDMAP/GID2SID/10000539 1249523689/S-1-5-21-2140803266-1626024873-1299147156-34226p8ZX>ŠX¹N™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34226 1249523689/10000539p`þX<íåÝY™&IDMAP/GID2SID/10000538 1249523689/S-1-5-21-4186143834-2626045635-1021053583-1210Bp¬åX=Ÿ£Ô™&IDMAP/SID2GID/S-1-5-21-4186143834-2626045635-1021053583-1210 1249523689/10000538Bp8ÇX==Ñh™&IDMAP/GID2SID/10000323 1249523689/S-1-5-21-2140803266-1626024873-1299147156-14614ppX>º©S!™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-14614 1249523689/10000323p8 X=íAÍ™&IDMAP/GID2SID/10000537 1249523689/S-1-5-21-2140803266-1626024873-1299147156-34225pXÔX>ЍÒé™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-34225 1249523689/10000537p8)X=í9¤@™&IDMAP/GID2SID/10000536 1249523689/S-1-5-21-2140803266-1626024873-1299147156-21811pûX> ç™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-21811 1249523689/10000536p0‹X=íc´™&IDMAP/GID2SID/10000535 1249523689/S-1-5-21-2140803266-1626024873-1299147156-20386püØX>6ÓÒ$™&IDMAP/SID2GID/S-1-5-21-2140803266-1626024873-1299147156-20386 1249523689/10000535p€X;íj'™&IDMAP/GID2SID/10000534 1249523688/S-1-5-21-2129485696-1739684832-945835055-1850BBplàX<ùˆöw™&IDMAP/SID2GID/S-1-5-21-2129485696-1739684832-945835055-1850 1249523688/10000534BBp#X>s0ë·™&IDMAP/SID2UID/S-1-5-21-1834383793-1770918451-929701000-146636 1251836362/10000421pldb-2.0.8/lib/tdb/test/test_tdbbackup.sh0000770000000000000000000000220313573675413020063 0ustar rootroot00000000000000#!/bin/sh # Blackbox test for tdbbackup of given ldb or tdb database # Copyright (C) 2018 Andrew Bartlett if [ $# -lt 1 ]; then echo "Usage: $0 LDBFILE" exit 1; fi LDBFILE=$1 timestamp() { date -u +'time: %Y-%m-%d %H:%M:%S.%6NZ' | sed 's/\..*NZ$/.000000Z/' } subunit_fail_test () { timestamp printf 'failure: %s [\n' "$1" cat - echo "]" } testit () { name="$1" shift cmdline="$@" timestamp printf 'test: %s\n' "$1" output=`$cmdline 2>&1` status=$? if [ x$status = x0 ]; then timestamp printf 'success: %s\n' "$name" else echo "$output" | subunit_fail_test "$name" fi return $status } $BINDIR/tdbdump $LDBFILE | sort > orig_dump testit "normal tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak $BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump testit "cmp between tdbdumps of original and backup" cmp orig_dump bak_dump rm $LDBFILE.bak rm bak_dump testit "readonly tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak -r $BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump testit "cmp between tdbdumps of original and back dbs" cmp orig_dump bak_dump rm $LDBFILE.bak rm bak_dump rm orig_dump ldb-2.0.8/lib/tdb/tools/tdbbackup.c0000660000000000000000000002021113573675413017012 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. low level tdb backup and restore utility Copyright (C) Andrew Tridgell 2002 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 . */ /* This program is meant for backup/restore of tdb databases. Typical usage would be: tdbbackup *.tdb when Samba shuts down cleanly, which will make a backup of all the local databases to *.bak files. Then on Samba startup you would use: tdbbackup -v *.tdb and this will check the databases for corruption and if corruption is detected then the backup will be restored. You may also like to do a backup on a regular basis while Samba is running, perhaps using cron. The reason this program is needed is to cope with power failures while Samba is running. A power failure could lead to database corruption and Samba will then not start correctly. Note that many of the databases in Samba are transient and thus don't need to be backed up, so you can optimise the above a little by only running the backup on the critical databases. */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" #ifdef HAVE_GETOPT_H #include #endif static int failed; static struct tdb_logging_context log_ctx; #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); fflush(stdout); } static char *add_suffix(const char *name, const char *suffix) { char *ret; int len = strlen(name) + strlen(suffix) + 1; ret = (char *)malloc(len); if (!ret) { fprintf(stderr,"Out of memory!\n"); exit(1); } snprintf(ret, len, "%s%s", name, suffix); return ret; } static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new)); failed = 1; return 1; } return 0; } static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { return 0; } /* carefully backup a tdb, validating the contents and only doing the backup if its OK this function is also used for restore */ static int backup_tdb(const char *old_name, const char *new_name, int hash_size, int nolock, bool readonly) { TDB_CONTEXT *tdb; TDB_CONTEXT *tdb_new; char *tmp_name; struct stat st; int count1, count2; tmp_name = add_suffix(new_name, ".tmp"); /* stat the old tdb to find its permissions */ if (stat(old_name, &st) != 0) { perror(old_name); free(tmp_name); return 1; } /* open the old tdb */ tdb = tdb_open_ex(old_name, 0, TDB_DEFAULT | (nolock ? TDB_NOLOCK : 0), O_RDWR, 0, &log_ctx, NULL); if (!tdb) { printf("Failed to open %s\n", old_name); free(tmp_name); return 1; } /* create the new tdb */ unlink(tmp_name); tdb_new = tdb_open_ex(tmp_name, hash_size ? hash_size : tdb_hash_size(tdb), TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, st.st_mode & 0777, &log_ctx, NULL); if (!tdb_new) { perror(tmp_name); free(tmp_name); return 1; } if (readonly) { if (tdb_lockall_read(tdb) != 0) { printf("Failed to obtain read only lock on old tdb\n"); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } } else if (tdb_transaction_start(tdb) != 0) { printf("Failed to start transaction on db\n"); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } /* lock the backup tdb so that nobody else can change it */ if (tdb_lockall(tdb_new) != 0) { printf("Failed to lock backup tdb\n"); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } failed = 0; /* traverse and copy */ if (readonly) { count1 = tdb_traverse_read(tdb, copy_fn, (void *)tdb_new); } else { count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); } if (count1 < 0 || failed) { fprintf(stderr,"failed to copy %s\n", old_name); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } /* close the old tdb */ tdb_close(tdb); /* copy done, unlock the backup tdb */ tdb_unlockall(tdb_new); #ifdef HAVE_FDATASYNC if (fdatasync(tdb_fd(tdb_new)) != 0) { #else if (fsync(tdb_fd(tdb_new)) != 0) { #endif /* not fatal */ fprintf(stderr, "failed to fsync backup file\n"); } /* close the new tdb and re-open read-only */ tdb_close(tdb_new); tdb_new = tdb_open_ex(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0, &log_ctx, NULL); if (!tdb_new) { fprintf(stderr,"failed to reopen %s\n", tmp_name); unlink(tmp_name); perror(tmp_name); free(tmp_name); return 1; } /* traverse the new tdb to confirm */ count2 = tdb_traverse(tdb_new, test_fn, NULL); if (count2 != count1) { fprintf(stderr,"failed to copy %s\n", old_name); tdb_close(tdb_new); unlink(tmp_name); free(tmp_name); return 1; } /* close the new tdb and rename it to .bak */ tdb_close(tdb_new); if (rename(tmp_name, new_name) != 0) { perror(new_name); free(tmp_name); return 1; } free(tmp_name); return 0; } /* verify a tdb and if it is corrupt then restore from *.bak */ static int verify_tdb(const char *fname, const char *bak_name) { TDB_CONTEXT *tdb; int count = -1; /* open the tdb */ tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &log_ctx, NULL); /* traverse the tdb, then close it */ if (tdb) { count = tdb_traverse(tdb, test_fn, NULL); tdb_close(tdb); } /* count is < 0 means an error */ if (count < 0) { printf("restoring %s\n", fname); return backup_tdb(bak_name, fname, 0, 0, 0); } printf("%s : %d records\n", fname, count); return 0; } /* see if one file is newer than another */ static int file_newer(const char *fname1, const char *fname2) { struct stat st1, st2; if (stat(fname1, &st1) != 0) { return 0; } if (stat(fname2, &st2) != 0) { return 1; } return (st1.st_mtime > st2.st_mtime); } static void usage(void) { printf("Usage: tdbbackup [options] \n\n"); printf(" -h this help message\n"); printf(" -s suffix set the backup suffix\n"); printf(" -v verify mode (restore if corrupt)\n"); printf(" -n hashsize set the new hash size for the backup\n"); printf(" -l open without locking to back up mutex dbs\n"); printf(" -r open with read only locking\n"); } int main(int argc, char *argv[]) { int i; int ret = 0; int c; int verify = 0; int hashsize = 0; int nolock = 0; bool readonly = false; const char *suffix = ".bak"; log_ctx.log_fn = tdb_log; while ((c = getopt(argc, argv, "vhs:n:lr")) != -1) { switch (c) { case 'h': usage(); exit(0); case 'v': verify = 1; break; case 's': suffix = optarg; break; case 'n': hashsize = atoi(optarg); break; case 'l': nolock = 1; break; case 'r': readonly = true; } } argc -= optind; argv += optind; if (argc < 1) { usage(); exit(1); } for (i=0; i. */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" static void print_data(TDB_DATA d) { unsigned char *p = (unsigned char *)d.dptr; int len = d.dsize; while (len--) { if (isprint(*p) && !strchr("\"\\", *p)) { fputc(*p, stdout); } else { printf("\\%02X", *p); } p++; } } static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { printf("{\n"); printf("key(%zu) = \"", key.dsize); print_data(key); printf("\"\n"); printf("data(%zu) = \"", dbuf.dsize); print_data(dbuf); printf("\"\n"); printf("}\n"); return 0; } static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { va_list ap; const char *name = tdb_name(tdb); const char *prefix = ""; if (!name) name = "unnamed"; switch (level) { case TDB_DEBUG_ERROR: prefix = "ERROR: "; break; case TDB_DEBUG_WARNING: prefix = "WARNING: "; break; case TDB_DEBUG_TRACE: return; default: case TDB_DEBUG_FATAL: prefix = "FATAL: "; break; } va_start(ap, fmt); fprintf(stderr, "tdb(%s): %s", name, prefix); vfprintf(stderr, fmt, ap); va_end(ap); } static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) { if (keyname) { if (key.dsize != strlen(keyname)) return; if (memcmp(key.dptr, keyname, key.dsize) != 0) return; } traverse_fn(NULL, key, dbuf, NULL); } static int dump_tdb(const char *fname, const char *keyname, bool emergency) { TDB_CONTEXT *tdb; TDB_DATA key, value; struct tdb_logging_context logfn = { .log_fn = log_stderr, }; int tdb_flags = TDB_DEFAULT; /* * Note: that O_RDONLY implies TDB_NOLOCK, but we want to make it * explicit as it's important when working on databases which were * created with mutex locking. */ tdb_flags |= TDB_NOLOCK; tdb = tdb_open_ex(fname, 0, tdb_flags, O_RDONLY, 0, &logfn, NULL); if (!tdb) { printf("Failed to open %s\n", fname); return 1; } if (emergency) { return tdb_rescue(tdb, emergency_walk, discard_const(keyname)) == 0; } if (!keyname) { return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0; } else { key.dptr = discard_const_p(uint8_t, keyname); key.dsize = strlen(keyname); value = tdb_fetch(tdb, key); if (!value.dptr) { return 1; } else { print_data(value); free(value.dptr); } } return 0; } static void usage( void) { printf( "Usage: tdbdump [options] \n\n"); printf( " -h this help message\n"); printf( " -k keyname dumps value of keyname\n"); printf( " -e emergency dump, for corrupt databases\n"); } int main(int argc, char *argv[]) { char *fname, *keyname=NULL; bool emergency = false; int c; if (argc < 2) { printf("Usage: tdbdump \n"); exit(1); } while ((c = getopt( argc, argv, "hk:e")) != -1) { switch (c) { case 'h': usage(); exit( 0); case 'k': keyname = optarg; break; case 'e': emergency = true; break; default: usage(); exit( 1); } } fname = argv[optind]; return dump_tdb(fname, keyname, emergency); } ldb-2.0.8/lib/tdb/tools/tdbrestore.c0000660000000000000000000001013012553526140017214 0ustar rootroot00000000000000/* tdbrestore -- construct a tdb from tdbdump output. Copyright (C) Volker Lendecke 2010 Copyright (C) Simon McVittie 2005 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 . */ #include "replace.h" #include #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" static int read_linehead(FILE *f) { int i, c; int num_bytes; char prefix[128]; while (1) { c = getc(f); if (c == EOF) { return -1; } if (c == '(') { break; } } for (i=0; idptr = (unsigned char *)malloc(size); if (d->dptr == NULL) { return -1; } d->dsize = size; for (i=0; idptr[i] = (low|high); } else { d->dptr[i] = c; } } return 0; } static int swallow(FILE *f, const char *s, int *eof) { char line[128]; if (fgets(line, sizeof(line), f) == NULL) { if (eof != NULL) { *eof = 1; } return -1; } if (strcmp(line, s) != 0) { return -1; } return 0; } static int read_rec(FILE *f, TDB_CONTEXT *tdb, int *eof) { int length; TDB_DATA key, data; int ret = -1; key.dptr = NULL; data.dptr = NULL; if (swallow(f, "{\n", eof) == -1) { goto fail; } length = read_linehead(f); if (length == -1) { goto fail; } if (read_data(f, &key, length) == -1) { goto fail; } if (swallow(f, "\"\n", NULL) == -1) { goto fail; } length = read_linehead(f); if (length == -1) { goto fail; } if (read_data(f, &data, length) == -1) { goto fail; } if ((swallow(f, "\"\n", NULL) == -1) || (swallow(f, "}\n", NULL) == -1)) { goto fail; } if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { fprintf(stderr, "TDB error: %s\n", tdb_errorstr(tdb)); goto fail; } ret = 0; fail: free(key.dptr); free(data.dptr); return ret; } static int restore_tdb(const char *fname) { TDB_CONTEXT *tdb; tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT|O_EXCL, 0666); if (!tdb) { perror("tdb_open"); fprintf(stderr, "Failed to open %s\n", fname); return 1; } while (1) { int eof = 0; if (read_rec(stdin, tdb, &eof) == -1) { if (eof) { break; } return 1; } } if (tdb_close(tdb)) { fprintf(stderr, "Error closing tdb\n"); return 1; } return 0; } int main(int argc, char *argv[]) { char *fname; if (argc < 2) { printf("Usage: %s dbname < tdbdump_output\n", argv[0]); exit(1); } fname = argv[1]; return restore_tdb(fname); } ldb-2.0.8/lib/tdb/tools/tdbtest.c0000660000000000000000000001223712406075657016533 0ustar rootroot00000000000000/* a test program for tdb - the trivial database */ #include "replace.h" #include "tdb.h" #include "system/filesys.h" #include "system/time.h" #include #define DELETE_PROB 7 #define STORE_PROB 5 static struct tdb_context *db; static GDBM_FILE gdbm; struct timeval tp1,tp2; static void _start_timer(void) { gettimeofday(&tp1,NULL); } static double _end_timer(void) { gettimeofday(&tp2,NULL); return((tp2.tv_sec - tp1.tv_sec) + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); } static void fatal(const char *why) { perror(why); exit(1); } #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); fflush(stdout); } static void compare_db(void) { TDB_DATA d, key, nextkey; datum gd, gkey, gnextkey; key = tdb_firstkey(db); while (key.dptr) { d = tdb_fetch(db, key); gkey.dptr = key.dptr; gkey.dsize = key.dsize; gd = gdbm_fetch(gdbm, gkey); if (!gd.dptr) fatal("key not in gdbm"); if (gd.dsize != d.dsize) fatal("data sizes differ"); if (memcmp(gd.dptr, d.dptr, d.dsize)) { fatal("data differs"); } nextkey = tdb_nextkey(db, key); free(key.dptr); free(d.dptr); free(gd.dptr); key = nextkey; } gkey = gdbm_firstkey(gdbm); while (gkey.dptr) { gd = gdbm_fetch(gdbm, gkey); key.dptr = gkey.dptr; key.dsize = gkey.dsize; d = tdb_fetch(db, key); if (!d.dptr) fatal("key not in db"); if (d.dsize != gd.dsize) fatal("data sizes differ"); if (memcmp(d.dptr, gd.dptr, gd.dsize)) { fatal("data differs"); } gnextkey = gdbm_nextkey(gdbm, gkey); free(gkey.dptr); free(gd.dptr); free(d.dptr); gkey = gnextkey; } } static char *randbuf(int len) { char *buf; int i; buf = (char *)malloc(len+1); for (i=0;i. */ #include "replace.h" #include "system/locale.h" #include "system/time.h" #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" static int do_command(void); const char *cmdname; char *arg1, *arg2; size_t arg1len, arg2len; int bIterate = 0; char *line; TDB_DATA iterate_kbuf; char cmdline[1024]; static int disable_mmap; static int _disable_lock; enum commands { CMD_CREATE_TDB, CMD_OPEN_TDB, CMD_TRANSACTION_START, CMD_TRANSACTION_COMMIT, CMD_TRANSACTION_CANCEL, CMD_ERASE, CMD_DUMP, CMD_INSERT, CMD_MOVE, CMD_STOREHEX, CMD_STORE, CMD_SHOW, CMD_KEYS, CMD_HEXKEYS, CMD_DELETE, CMD_LIST_HASH_FREE, CMD_LIST_FREE, CMD_FREELIST_SIZE, CMD_INFO, CMD_MMAP, CMD_SPEED, CMD_FIRST, CMD_NEXT, CMD_SYSTEM, CMD_CHECK, CMD_REPACK, CMD_QUIT, CMD_HELP }; typedef struct { const char *name; enum commands cmd; } COMMAND_TABLE; COMMAND_TABLE cmd_table[] = { {"create", CMD_CREATE_TDB}, {"open", CMD_OPEN_TDB}, {"transaction_start", CMD_TRANSACTION_START}, {"transaction_commit", CMD_TRANSACTION_COMMIT}, {"transaction_cancel", CMD_TRANSACTION_CANCEL}, {"erase", CMD_ERASE}, {"dump", CMD_DUMP}, {"insert", CMD_INSERT}, {"move", CMD_MOVE}, {"storehex", CMD_STOREHEX}, {"store", CMD_STORE}, {"show", CMD_SHOW}, {"keys", CMD_KEYS}, {"hexkeys", CMD_HEXKEYS}, {"delete", CMD_DELETE}, {"list", CMD_LIST_HASH_FREE}, {"free", CMD_LIST_FREE}, {"freelist_size", CMD_FREELIST_SIZE}, {"info", CMD_INFO}, {"speed", CMD_SPEED}, {"mmap", CMD_MMAP}, {"first", CMD_FIRST}, {"1", CMD_FIRST}, {"next", CMD_NEXT}, {"n", CMD_NEXT}, {"check", CMD_CHECK}, {"quit", CMD_QUIT}, {"q", CMD_QUIT}, {"!", CMD_SYSTEM}, {"repack", CMD_REPACK}, {NULL, CMD_HELP} }; struct timeval tp1,tp2; static void _start_timer(void) { gettimeofday(&tp1,NULL); } static double _end_timer(void) { gettimeofday(&tp2,NULL); return((tp2.tv_sec - tp1.tv_sec) + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); } #ifdef PRINTF_ATTRIBUTE static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { const char *mutex_msg = "Can use mutexes only with MUTEX_LOCKING or NOLOCK\n"; char *p; va_list ap; p = strstr(format, mutex_msg); if (p != NULL) { /* * Yes, this is a hack, but we don't want to see this * message on first open, but we want to see * everything else. */ return; } va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } /* a tdb tool for manipulating a tdb database */ static TDB_CONTEXT *tdb; static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); static void print_asc(const char *buf,int len) { int i; /* We're probably printing ASCII strings so don't try to display the trailing NULL character. */ if (buf[len - 1] == 0) len--; for (i=0;i8) printf(" "); while (n--) printf(" "); n = i%16; if (n > 8) n = 8; print_asc(&buf[i-(i%16)],n); printf(" "); n = (i%16) - n; if (n>0) print_asc(&buf[i-n],n); printf("\n"); } } static void help(void) { printf("\n" "tdbtool: \n" " create dbname : create a database\n" " open dbname : open an existing database\n" " transaction_start : start a transaction\n" " transaction_commit : commit a transaction\n" " transaction_cancel : cancel a transaction\n" " erase : erase the database\n" " dump : dump the database as strings\n" " keys : dump the database keys as strings\n" " hexkeys : dump the database keys as hex values\n" " info : print summary info about the database\n" " insert key data : insert a record\n" " move key file : move a record to a destination tdb\n" " storehex key data : store a record (replace), key/value in hex format\n" " store key data : store a record (replace)\n" " show key : show a record by key\n" " delete key : delete a record by key\n" " list : print the database hash table and freelist\n" " free : print the database freelist\n" " freelist_size : print the number of records in the freelist\n" " check : check the integrity of an opened database\n" " repack : repack the database\n" " speed : perform speed tests on the database\n" " ! command : execute system command\n" " 1 | first : print the first record\n" " n | next : print the next record\n" " q | quit : terminate\n" " \\n : repeat 'next' command\n" "\n"); } static void terror(const char *why) { printf("%s\n", why); } static void create_tdb(const char *tdbname) { struct tdb_logging_context log_ctx = { NULL, NULL}; log_ctx.log_fn = tdb_log; if (tdb) tdb_close(tdb); tdb = tdb_open_ex(tdbname, 0, TDB_CLEAR_IF_FIRST | (disable_mmap?TDB_NOMMAP:0) | (_disable_lock?TDB_NOLOCK:0), O_RDWR | O_CREAT | O_TRUNC, 0600, &log_ctx, NULL); if (!tdb) { printf("Could not create %s: %s\n", tdbname, strerror(errno)); } } static void open_tdb(const char *tdbname) { struct tdb_logging_context log_ctx = { NULL, NULL }; log_ctx.log_fn = tdb_log_open; if (tdb) tdb_close(tdb); tdb = tdb_open_ex(tdbname, 0, (disable_mmap?TDB_NOMMAP:0) | (_disable_lock?TDB_NOLOCK:0), O_RDWR, 0600, &log_ctx, NULL); log_ctx.log_fn = tdb_log; if (tdb != NULL) { tdb_set_logging_function(tdb, &log_ctx); } if ((tdb == NULL) && (errno == EINVAL)) { /* * Retry NOLOCK and readonly. There we want to see all * error messages. */ tdb = tdb_open_ex(tdbname, 0, (disable_mmap?TDB_NOMMAP:0) |TDB_NOLOCK, O_RDONLY, 0600, &log_ctx, NULL); } if (!tdb) { printf("Could not open %s: %s\n", tdbname, strerror(errno)); } } static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) { TDB_DATA key, dbuf; if ((keyname == NULL) || (keylen == 0)) { terror("need key"); return; } key.dptr = (unsigned char *)keyname; key.dsize = keylen; dbuf.dptr = (unsigned char *)data; dbuf.dsize = datalen; if (tdb_store(tdb, key, dbuf, TDB_INSERT) != 0) { terror("insert failed"); } } static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) { TDB_DATA key, dbuf; if ((keyname == NULL) || (keylen == 0)) { terror("need key"); return; } if ((data == NULL) || (datalen == 0)) { terror("need data"); return; } key.dptr = (unsigned char *)keyname; key.dsize = keylen; dbuf.dptr = (unsigned char *)data; dbuf.dsize = datalen; printf("Storing key:\n"); print_rec(tdb, key, dbuf, NULL); if (tdb_store(tdb, key, dbuf, TDB_REPLACE) != 0) { terror("store failed"); } } static bool hexchar(char c, uint8_t *v) { if ((c >= '0') && (c <= '9')) { *v = (c - '0'); return true; } if ((c >= 'A') && (c <= 'F')) { *v = (c - 'A' + 10); return true; } if ((c >= 'a') && (c <= 'f')) { *v = (c - 'a' + 10); return true; } return false; } static bool parse_hex(const char *src, size_t srclen, uint8_t *dst) { size_t i=0; if ((srclen % 2) != 0) { return false; } while (iname) { cmd_len = strlen(ctp->name); if (strncmp(ctp->name,cmdname,cmd_len) == 0) { mycmd = ctp->cmd; break; } ctp++; } } } switch (mycmd) { case CMD_CREATE_TDB: bIterate = 0; create_tdb(arg1); return 0; case CMD_OPEN_TDB: bIterate = 0; open_tdb(arg1); return 0; case CMD_SYSTEM: /* Shell command */ if (system(arg1) == -1) { terror("system() call failed\n"); } return 0; case CMD_QUIT: return 1; default: /* all the rest require a open database */ if (!tdb) { bIterate = 0; terror("database not open"); help(); return 0; } switch (mycmd) { case CMD_TRANSACTION_START: bIterate = 0; tdb_transaction_start(tdb); return 0; case CMD_TRANSACTION_COMMIT: bIterate = 0; tdb_transaction_commit(tdb); return 0; case CMD_REPACK: bIterate = 0; tdb_repack(tdb); return 0; case CMD_TRANSACTION_CANCEL: bIterate = 0; tdb_transaction_cancel(tdb); return 0; case CMD_ERASE: bIterate = 0; tdb_wipe_all(tdb); return 0; case CMD_DUMP: bIterate = 0; tdb_traverse(tdb, print_rec, NULL); return 0; case CMD_INSERT: bIterate = 0; insert_tdb(arg1, arg1len,arg2,arg2len); return 0; case CMD_MOVE: bIterate = 0; move_rec(arg1,arg1len,arg2); return 0; case CMD_STORE: bIterate = 0; store_tdb(arg1,arg1len,arg2,arg2len); return 0; case CMD_STOREHEX: bIterate = 0; store_hex_tdb(arg1,arg1len,arg2,arg2len); return 0; case CMD_SHOW: bIterate = 0; show_tdb(arg1, arg1len); return 0; case CMD_KEYS: tdb_traverse(tdb, print_key, NULL); return 0; case CMD_HEXKEYS: tdb_traverse(tdb, print_hexkey, NULL); return 0; case CMD_DELETE: bIterate = 0; delete_tdb(arg1,arg1len); return 0; case CMD_LIST_HASH_FREE: tdb_dump_all(tdb); return 0; case CMD_LIST_FREE: tdb_printfreelist(tdb); return 0; case CMD_FREELIST_SIZE: { int size; size = tdb_freelist_size(tdb); if (size < 0) { printf("Error getting freelist size.\n"); } else { printf("freelist size: %d\n", size); } return 0; } case CMD_INFO: info_tdb(); return 0; case CMD_SPEED: speed_tdb(arg1); return 0; case CMD_MMAP: toggle_mmap(); return 0; case CMD_FIRST: bIterate = 1; first_record(tdb, &iterate_kbuf); return 0; case CMD_NEXT: if (bIterate) next_record(tdb, &iterate_kbuf); return 0; case CMD_CHECK: check_db(tdb); return 0; case CMD_HELP: help(); return 0; case CMD_CREATE_TDB: case CMD_OPEN_TDB: case CMD_SYSTEM: case CMD_QUIT: /* * unhandled commands. cases included here to avoid compiler * warnings. */ return 0; } } return 0; } static char *tdb_convert_string(char *instring, size_t *sizep) { size_t length = 0; char *outp, *inp; char temp[3]; outp = inp = instring; while (*inp) { if (*inp == '\\') { inp++; if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { temp[0] = *inp++; temp[1] = '\0'; if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { temp[1] = *inp++; temp[2] = '\0'; } *outp++ = (char)strtol((const char *)temp,NULL,16); } else { *outp++ = *inp++; } } else { *outp++ = *inp++; } length++; } *sizep = length; return instring; } int main(int argc, char *argv[]) { cmdname = ""; arg1 = NULL; arg1len = 0; arg2 = NULL; arg2len = 0; if (argv[1] && (strcmp(argv[1], "-l") == 0)) { _disable_lock = 1; argv[1] = argv[0]; argv += 1; argc -= 1; } if (argv[1]) { cmdname = "open"; arg1 = argv[1]; do_command(); cmdname = ""; arg1 = NULL; } switch (argc) { case 1: case 2: /* Interactive mode */ while ((cmdname = tdb_getline("tdb> "))) { arg2 = arg1 = NULL; if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { arg1++; arg2 = arg1; while (*arg2) { if (*arg2 == ' ') { *arg2++ = '\0'; break; } if ((*arg2++ == '\\') && (*arg2 == ' ')) { arg2++; } } } if (arg1) arg1 = tdb_convert_string(arg1,&arg1len); if (arg2) arg2 = tdb_convert_string(arg2,&arg2len); if (do_command()) break; } 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; } if (tdb) tdb_close(tdb); return 0; } ldb-2.0.8/lib/tdb/tools/tdbtorture.c0000660000000000000000000002367413573675413017271 0ustar rootroot00000000000000/* this tests tdb by doing lots of ops from several simultaneous writers - that stresses the locking code. */ #include "replace.h" #include "system/time.h" #include "system/wait.h" #include "system/filesys.h" #include "tdb.h" #ifdef HAVE_GETOPT_H #include #endif #define REOPEN_PROB 30 #define DELETE_PROB 8 #define STORE_PROB 4 #define APPEND_PROB 6 #define TRANSACTION_PROB 10 #define TRANSACTION_PREPARE_PROB 2 #define LOCKSTORE_PROB 5 #define TRAVERSE_PROB 20 #define TRAVERSE_READ_PROB 20 #define CULL_PROB 100 #define KEYLEN 3 #define DATALEN 100 static struct tdb_context *db; static int in_transaction; static int error_count; static int always_transaction = 0; static int hash_size = 2; static unsigned loopnum; static int count_pipe; static bool mutex = false; static struct tdb_logging_context log_ctx; #ifdef PRINTF_ATTRIBUTE static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); #endif static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) { va_list ap; /* trace level messages do not indicate an error */ if (level != TDB_DEBUG_TRACE) { error_count++; } va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); fflush(stdout); #if 0 if (level != TDB_DEBUG_TRACE) { char *ptr; signal(SIGUSR1, SIG_IGN); asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); system(ptr); free(ptr); } #endif } static void fatal(const char *why) { perror(why); error_count++; } static char *randbuf(int len) { char *buf; int i; buf = (char *)malloc(len+1); for (i=0;i ldb

tdb

TDB is a Trivial Database. In concept, it is very much like GDBM, and BSD's DB except that it allows multiple simultaneous writers and uses locking internally to keep writers from trampling on each other. TDB is also extremely small.

Download

You can download the latest releases of tdb from the tdb directory on the samba public source archive.

Discussion and bug reports

tdb does not currently have its own mailing list or bug tracking system. For now, please use the samba-technical mailing list, and the Samba bugzilla bug tracking system.

Download

You can download the latest code either via git or rsync.

To fetch via git see the following guide:
Using Git for Samba Development
Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory.

To fetch via rsync use these commands:
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
and build in tdb. It will find the replace library in the directory above automatically. ldb-2.0.8/lib/tdb/wscript0000660000000000000000000002057113573675413015176 0ustar rootroot00000000000000#!/usr/bin/env python APPNAME = 'tdb' VERSION = '1.4.2' import sys, os # find the buildtools directory top = '.' while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: top = top + '/..' sys.path.insert(0, top + '/buildtools/wafsamba') out = 'bin' import wafsamba from wafsamba import samba_dist, samba_utils from waflib import Options, Logs, Context import shutil samba_dist.DIST_DIRS('lib/tdb:. lib/replace:lib/replace buildtools:buildtools third_party/waf:third_party/waf') tdb1_unit_tests = [ 'run-3G-file', 'run-bad-tdb-header', 'run', 'run-check', 'run-corrupt', 'run-die-during-transaction', 'run-endian', 'run-incompatible', 'run-nested-transactions', 'run-nested-traverse', 'run-no-lock-during-traverse', 'run-oldhash', 'run-open-during-transaction', 'run-readonly-check', 'run-rescue', 'run-rescue-find_entry', 'run-rdlock-upgrade', 'run-rwlock-check', 'run-summary', 'run-transaction-expand', 'run-traverse-in-transaction', 'run-wronghash-fail', 'run-zero-append', 'run-fcntl-deadlock', 'run-marklock-deadlock', 'run-allrecord-traverse-deadlock', 'run-mutex-openflags2', 'run-mutex-trylock', 'run-mutex-allrecord-bench', 'run-mutex-allrecord-trylock', 'run-mutex-allrecord-block', 'run-mutex-transaction1', 'run-mutex-die', 'run-mutex1', 'run-circular-chain', 'run-circular-freelist', 'run-traverse-chain', ] def options(opt): opt.BUILTIN_DEFAULT('replace') opt.PRIVATE_EXTENSION_DEFAULT('tdb', noextension='tdb') opt.RECURSE('lib/replace') opt.add_option('--disable-tdb-mutex-locking', help=("Disable the use of pthread robust mutexes"), action="store_true", dest='disable_tdb_mutex_locking', default=False) def configure(conf): conf.env.disable_tdb_mutex_locking = getattr(Options.options, 'disable_tdb_mutex_locking', False) if not conf.env.disable_tdb_mutex_locking: conf.env.replace_add_global_pthread = True conf.RECURSE('lib/replace') conf.env.standalone_tdb = conf.IN_LAUNCH_DIR() conf.env.building_tdb = True if not conf.env.standalone_tdb: if conf.CHECK_BUNDLED_SYSTEM_PKG('tdb', minversion=VERSION, implied_deps='replace'): conf.define('USING_SYSTEM_TDB', 1) conf.env.building_tdb = False if not conf.env.disable_python and \ conf.CHECK_BUNDLED_SYSTEM_PYTHON('pytdb', 'tdb', minversion=VERSION): conf.define('USING_SYSTEM_PYTDB', 1) if (conf.CONFIG_SET('HAVE_ROBUST_MUTEXES') and conf.env.building_tdb and not conf.env.disable_tdb_mutex_locking): conf.define('USE_TDB_MUTEX_LOCKING', 1) conf.CHECK_XSLTPROC_MANPAGES() conf.SAMBA_CHECK_PYTHON() conf.SAMBA_CHECK_PYTHON_HEADERS() conf.SAMBA_CONFIG_H() conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() def build(bld): bld.RECURSE('lib/replace') COMMON_FILES='''check.c error.c tdb.c traverse.c freelistcheck.c lock.c dump.c freelist.c io.c open.c transaction.c hash.c summary.c rescue.c mutex.c''' COMMON_SRC = bld.SUBDIR('common', COMMON_FILES) if bld.env.standalone_tdb: bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' private_library = False else: private_library = True if not bld.CONFIG_SET('USING_SYSTEM_TDB'): tdb_deps = 'replace' if bld.CONFIG_SET('USE_TDB_MUTEX_LOCKING'): tdb_deps += ' pthread' bld.SAMBA_LIBRARY('tdb', COMMON_SRC, deps=tdb_deps, includes='include', abi_directory='ABI', abi_match='tdb_*', hide_symbols=True, vnum=VERSION, public_headers=('' if private_library else 'include/tdb.h'), public_headers_install=not private_library, pc_files='tdb.pc', private_library=private_library) bld.SAMBA_BINARY('tdbtorture', 'tools/tdbtorture.c', 'tdb', install=False) bld.SAMBA_BINARY('tdbrestore', 'tools/tdbrestore.c', 'tdb', manpages='man/tdbrestore.8') bld.SAMBA_BINARY('tdbdump', 'tools/tdbdump.c', 'tdb', manpages='man/tdbdump.8') bld.SAMBA_BINARY('tdbbackup', 'tools/tdbbackup.c', 'tdb', manpages='man/tdbbackup.8') bld.SAMBA_BINARY('tdbtool', 'tools/tdbtool.c', 'tdb', manpages='man/tdbtool.8') if bld.env.standalone_tdb: # FIXME: This hardcoded list is stupid, stupid, stupid. bld.SAMBA_SUBSYSTEM('tdb-test-helpers', 'test/external-agent.c test/lock-tracking.c test/logging.c', tdb_deps, includes='include') for t in tdb1_unit_tests: b = "tdb1-" + t s = "test/" + t + ".c" bld.SAMBA_BINARY(b, s, 'replace tdb-test-helpers', includes='include', install=False) if not bld.CONFIG_SET('USING_SYSTEM_PYTDB'): bld.SAMBA_PYTHON('pytdb', 'pytdb.c', deps='tdb', enabled=not bld.env.disable_python, realname='tdb.so', cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) if not bld.env.disable_python: bld.SAMBA_SCRIPT('_tdb_text.py', pattern='_tdb_text.py', installdir='python') bld.INSTALL_FILES('${PYTHONARCHDIR}', '_tdb_text.py') def testonly(ctx): '''run tdb testsuite''' ecode = 0 blddir = Context.g_module.out test_prefix = "%s/st" % (blddir) shutil.rmtree(test_prefix, ignore_errors=True) os.makedirs(test_prefix) os.environ['TEST_DATA_PREFIX'] = test_prefix env = samba_utils.LOAD_ENVIRONMENT() # FIXME: This is horrible :( if env.building_tdb: # Create scratch directory for tests. testdir = os.path.join(test_prefix, 'tdb-tests') samba_utils.mkdir_p(testdir) # Symlink back to source dir so it can find tests in test/ link = os.path.join(testdir, 'test') if not os.path.exists(link): os.symlink(ctx.path.make_node('test').abspath(), link) sh_tests = ["test/test_tdbbackup.sh test/jenkins-be-hash.tdb"] for sh_test in sh_tests: cmd = "BINDIR=%s %s" % (blddir, sh_test) print("shell test: " + cmd) ret = samba_utils.RUN_COMMAND(cmd) if ret != 0: print("%s sh test failed" % cmd) ecode = ret break for t in tdb1_unit_tests: f = "tdb1-" + t cmd = "cd " + testdir + " && " + os.path.abspath(os.path.join(blddir, f)) + " > test-output 2>&1" print("..." + f) ret = samba_utils.RUN_COMMAND(cmd) if ret != 0: print("%s failed:" % f) samba_utils.RUN_COMMAND("cat " + os.path.join(testdir, 'test-output')) ecode = ret break if ecode == 0: cmd = os.path.join(blddir, 'tdbtorture') ret = samba_utils.RUN_COMMAND(cmd) print("testsuite returned %d" % ret) if ret != 0: ecode = ret pyret = samba_utils.RUN_PYTHON_TESTS(['python/tests/simple.py']) print("python testsuite returned %d" % pyret) sys.exit(ecode or pyret) # WAF doesn't build the unit tests for this, maybe because they don't link with tdb? # This forces it def test(ctx): Options.commands.append('build') Options.commands.append('testonly') def dist(): '''makes a tarball for distribution''' samba_dist.dist() def reconfigure(ctx): '''reconfigure if config scripts have changed''' samba_utils.reconfigure(ctx) ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs0000660000000000000000000002372213573675413017616 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_context_pop_use: void (struct tevent_context *, const char *) _tevent_context_push_use: bool (struct tevent_context *, const char *) _tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_abort: void (struct tevent_context *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_double_free: void (TALLOC_CTX *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_context_is_wrapper: bool (struct tevent_context *) tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_req_set_profile: bool (struct tevent_req *) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs0000660000000000000000000001276112406075657017626 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs0000660000000000000000000001276112406075657017627 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs0000660000000000000000000001305312406075657017623 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs0000660000000000000000000001317212406075657017626 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs0000660000000000000000000001375612406075657017637 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs0000660000000000000000000001375612406075657017640 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs0000660000000000000000000001453512406075657017635 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs0000660000000000000000000001453512406075657017636 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs0000660000000000000000000001500212406075657017625 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs0000660000000000000000000001500212406075657017626 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs0000660000000000000000000001535312406075657017627 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs0000660000000000000000000001547012406075657017630 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs0000660000000000000000000001547012412743715017623 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs0000660000000000000000000001547012474026560017624 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs0000660000000000000000000001547012475451205017624 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs0000660000000000000000000001547012536700232017620 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs0000660000000000000000000001601412617125507017622 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs0000660000000000000000000001601412661701312017614 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs0000660000000000000000000001601412661701615017623 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs0000660000000000000000000001601412746331032017620 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs0000660000000000000000000001701512757257013017622 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs0000660000000000000000000001724712775624157017641 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs0000660000000000000000000001724713123203631017614 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs0000660000000000000000000001724713134750322017623 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs0000660000000000000000000001724713202267000017614 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs0000660000000000000000000001724713226330227017625 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs0000660000000000000000000001735013243766350017632 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs0000660000000000000000000002372213444661620017630 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_context_pop_use: void (struct tevent_context *, const char *) _tevent_context_push_use: bool (struct tevent_context *, const char *) _tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_abort: void (struct tevent_context *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_double_free: void (TALLOC_CTX *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_context_is_wrapper: bool (struct tevent_context *) tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_req_set_profile: bool (struct tevent_req *) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs0000660000000000000000000002372213573675413017641 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_context_pop_use: void (struct tevent_context *, const char *) _tevent_context_push_use: bool (struct tevent_context *, const char *) _tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_abort: void (struct tevent_context *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_double_free: void (TALLOC_CTX *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_context_is_wrapper: bool (struct tevent_context *) tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_req_set_profile: bool (struct tevent_req *) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs0000660000000000000000000002372213573675413017642 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_context_pop_use: void (struct tevent_context *, const char *) _tevent_context_push_use: bool (struct tevent_context *, const char *) _tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_req_oom: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) _tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_abort: void (struct tevent_context *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_double_free: void (TALLOC_CTX *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_have_events: bool (struct tevent_context *) tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_common_threaded_activate_immediate: void (struct tevent_context *) tevent_common_wakeup: int (struct tevent_context *) tevent_common_wakeup_fd: int (int) tevent_common_wakeup_init: int (struct tevent_context *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) tevent_context_is_wrapper: bool (struct tevent_context *) tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_num_signals: size_t (void) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_running: bool (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_queue_wait_recv: bool (struct tevent_req *) tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) tevent_req_received: void (struct tevent_req *) tevent_req_reset_endtime: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_req_set_profile: bool (struct tevent_req *) tevent_sa_info_queue_count: size_t (void) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) tevent_signal_support: bool (struct tevent_context *) tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) tevent_update_timer: void (struct tevent_timer *, struct timeval) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs0000660000000000000000000001276112406075657017556 0ustar rootroot00000000000000_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) _tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) _tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) _tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) _tevent_loop_once: int (struct tevent_context *, const char *) _tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) _tevent_loop_wait: int (struct tevent_context *, const char *) _tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) _tevent_req_callback_data: void *(struct tevent_req *) _tevent_req_cancel: bool (struct tevent_req *, const char *) _tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) _tevent_req_data: void *(struct tevent_req *) _tevent_req_done: void (struct tevent_req *, const char *) _tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) _tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) _tevent_req_notify_callback: void (struct tevent_req *, const char *) _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_backend_list: const char **(TALLOC_CTX *) tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) tevent_common_check_signal: int (struct tevent_context *) tevent_common_context_destructor: int (struct tevent_context *) tevent_common_fd_destructor: int (struct tevent_fd *) tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_common_loop_immediate: bool (struct tevent_context *) tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) tevent_common_loop_wait: int (struct tevent_context *, const char *) tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) tevent_context_init: struct tevent_context *(TALLOC_CTX *) tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) tevent_fd_get_flags: uint16_t (struct tevent_fd *) tevent_fd_set_auto_close: void (struct tevent_fd *) tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) tevent_loop_allow_nesting: void (struct tevent_context *) tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) tevent_queue_length: size_t (struct tevent_queue *) tevent_queue_start: void (struct tevent_queue *) tevent_queue_stop: void (struct tevent_queue *) tevent_re_initialise: int (struct tevent_context *) tevent_register_backend: bool (const char *, const struct tevent_ops *) tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) tevent_req_is_in_progress: bool (struct tevent_req *) tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) tevent_req_received: void (struct tevent_req *) tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) tevent_set_abort_fn: void (void (*)(const char *)) tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) tevent_set_debug_stderr: int (struct tevent_context *) tevent_set_default_backend: void (const char *) tevent_signal_support: bool (struct tevent_context *) tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) tevent_timeval_compare: int (const struct timeval *, const struct timeval *) tevent_timeval_current: struct timeval (void) tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) tevent_timeval_is_zero: bool (const struct timeval *) tevent_timeval_set: struct timeval (uint32_t, uint32_t) tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) tevent_timeval_zero: struct timeval (void) tevent_wakeup_recv: bool (struct tevent_req *) tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) ldb-2.0.8/lib/tevent/Makefile0000660000000000000000000000135313573675413015751 0ustar rootroot00000000000000# simple makefile wrapper to run waf WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` WAF_BINARY=$(PYTHON) $(WAF_BIN) WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) all: $(WAF) build install: $(WAF) install uninstall: $(WAF) uninstall test: $(WAF) test $(TEST_OPTIONS) dist: touch .tmplock WAFLOCK=.tmplock $(WAF) dist distcheck: touch .tmplock WAFLOCK=.tmplock $(WAF) distcheck clean: $(WAF) clean distclean: $(WAF) distclean reconfigure: configure $(WAF) reconfigure show_waf_options: $(WAF) --help # some compatibility make targets everything: all testsuite: all check: test # this should do an install as well, once install is finished installcheck: test etags: $(WAF) etags ctags: $(WAF) ctags ldb-2.0.8/lib/tevent/bindings.py0000660000000000000000000000733513573675413016466 0ustar rootroot00000000000000#!/usr/bin/python # # Python integration for tevent - tests # # Copyright (C) Jelmer Vernooij 2010 # # ** NOTE! The following LGPL license applies to the tevent # ** 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 . import signal from unittest import TestCase, TestProgram import gc import _tevent class BackendListTests(TestCase): def test_backend_list(self): self.assertTrue(isinstance(_tevent.backend_list(), list)) class CreateContextTests(TestCase): def test_by_name(self): ctx = _tevent.Context(_tevent.backend_list()[0]) self.assertTrue(ctx is not None) def test_no_name(self): ctx = _tevent.Context() self.assertTrue(ctx is not None) class ContextTests(TestCase): def setUp(self): super(ContextTests, self).setUp() self.ctx = _tevent.Context() def test_signal_support(self): self.assertTrue(type(self.ctx.signal_support) is bool) def test_reinitialise(self): self.ctx.reinitialise() def test_loop_wait(self): self.ctx.loop_wait() def test_add_signal(self): sig = self.ctx.add_signal(signal.SIGINT, 0, lambda callback: None) self.assertTrue(isinstance(sig, _tevent.Signal)) def test_timer(self): """Test a timer is can be scheduled""" collecting_list = [] # time "0" has already passed, callback will be scheduled immediately timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) self.assertTrue(timer.active) self.assertEqual(collecting_list, []) self.ctx.loop_once() self.assertFalse(timer.active) self.assertEqual(collecting_list, [True]) def test_timer_deallocate_timer(self): """Test timer is scheduled even if reference to it isn't held""" collecting_list = [] def callback(t): collecting_list.append(True) timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) gc.collect() self.assertEqual(collecting_list, []) self.ctx.loop_once() self.assertEqual(collecting_list, [True]) def test_timer_deallocate_context(self): """Test timer is unscheduled when context is freed""" collecting_list = [] def callback(t): collecting_list.append(True) timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) self.assertTrue(timer.active) del self.ctx gc.collect() self.assertEqual(collecting_list, []) self.assertFalse(timer.active) def test_timer_offset(self): """Test scheduling timer with an offset""" collecting_list = [] self.ctx.add_timer_offset(0.2, lambda t: collecting_list.append(2)) self.ctx.add_timer_offset(0.1, lambda t: collecting_list.append(1)) self.assertEqual(collecting_list, []) self.ctx.loop_once() self.assertEqual(collecting_list, [1]) self.ctx.loop_once() self.assertEqual(collecting_list, [1, 2]) if __name__ == '__main__': TestProgram() ldb-2.0.8/lib/tevent/configure0000770000000000000000000000065713573675413016225 0ustar rootroot00000000000000#!/bin/sh PREVPATH=`dirname $0` if [ -f $PREVPATH/../../buildtools/bin/waf ]; then WAF=../../buildtools/bin/waf elif [ -f $PREVPATH/buildtools/bin/waf ]; then WAF=./buildtools/bin/waf else echo "tevent: Unable to find waf" exit 1 fi # using JOBS=1 gives maximum compatibility with # systems like AIX which have broken threading in python JOBS=1 export JOBS cd . || exit 1 $PYTHON $WAF configure "$@" || exit 1 cd $PREVPATH ldb-2.0.8/lib/tevent/doc/img/tevent_context_stucture.png0000660000000000000000000005260012406075657023346 0ustar rootroot00000000000000‰PNG  IHDR-^ÆÕ¸×UGIDATxÚí½w\TGÛÿOï¤I D, Ñ;Š4–[ ¶ƒ±Ý&Æ’¦b¬Ñ<‰1¶X"Ñ;v%±5‚ EEEEP ŠbC$¿Ïã|³¿}¶¹,,ì.Ÿ÷¼ØSæœ3sÍõ™kΜ£¿ !„êÈY@!„:D!„:D!„P‡!„P‡!„ C>¼páÂÎ;W­Z5oÞ¼©S§&½`Ú´iß}÷ݦM›Nœ8‘ŸŸÿüùs–!„P‡*‡¬¬¬¥K—¾ýöÛþþþ¦¦¦&R¿@z pvvîØ±ã¨Q£~úé§Û·oS–!„:T>ž›ô‚‰'<¸sçÎááávvvÆÿ€mllºtéòõ×_#N*++cùBuH™™™3fÌ 433Úƒ0hàÀË—/?}útqqqiiés)Ê^ ½ „úùçŸ?úè£ÈÈHkkk‰ uïÞý÷߇ȱ !„:$ËÑ£Gû÷ïïääÍ€ü ²ùøãÏž=ûôéS¡7åJM"N7oÞ\°`A‡¬¬¬„ µlÙ299ùþýû !„:ôÿb (èOCÔòÆo¤¤¤ÝÉÉÉßßÿÔ©Sz7w΃bcc---ûöí{çΆt„Rsu())ÉÑѱI“&×®]Óë—+¸ù~ýúY[[¿ýöÛº?ØB¨CÿKff¦XPuóæÍ°øé… ‚ƒƒ-,,¶nÝÊõŠ!DtHŒ‘{çw &€˜={¶““S‹-®_¿Î±s„¢Ó:tôèÑÚµk[ZZ9rD§f«÷îÝ 311Y¶lçû!„Ö¡Áƒ#9rdaa¡!=ö¢E‹\\\¢££srrh„¢£:$Þ ÙÚÚ¦¥¥Øè²ââ∈SSÓ-[¶ð-!„è¨Í™3ÇÙÙ9>>Þ ?üœ}º···Ïš5k ï¿ÿ>??¿äädÉ’Ûø?22ÒÞÞ¾mÛ¶iiiÏž=+o *Ø·o_LL ‡ö}¬¬¬¦OŸÎ™!DçtèñãÇõë×711ùõ×_ òÏÌÌÌÀÀ@KKËsçÎՄϤ!DÏtŒ7ÎÞÞ^LQjxOž””äèèøúë¯çååÑ!DuèìÙ³vvvéééöÿáǯ¼ò ¢½7r:BÑQ 666†7ZAŒPˆŠŠR±N+!„êס#GŽx{{[YY½tM =¢¨¨HCK—.åÛ„¢Ó:TVVöÖ[oY[[2¤  À0žyîܹÎÎΆ²³³9BBtZ‡À… ÌÍÍ·nÝZ]ÓžV"™™™uêÔÁãp¡BÑ“'OvttlÖ¬™ @x‡¿9B S‡îÝ»233›2e þ×ß§]³fM­Zµœ o !„²Çûúú"’Ø´i“žvgedd„‡‡›˜˜,_¾œÃ!DÏt¨¬¬lêÔ©ŽŽŽçϟ׻`ÂÓ©S' ‹øøøÛ·o³à !DÏt””” 0ÀÆÆ¦M›6z·jܨQ£ìììš4irùòeŽ‘#„½Ô!““Wnff†¨BÞó#’srrrvvÞ³gÔ”¥N!úªCàÏ?ÿ 211yï½÷ uÿ ,Xàêêjii¹nݺG±È !D¿u¨¬¬,55500PHÑíÛ·u¹›K"B?ýôÇ&Bˆ!è¢@Šâããoݺ¥›R4iÒ$'''ˆÐ÷ß_\\ÌÂ&„Ñ!™¨¨M›6—/_Ö©t}FŒaooÏHˆB S‡„ýùçŸfff¤mÛ¶éÈwEíÛ·‡9;;ÿüóÏ|'D!†©CBŠrrrúõëgcccmm””Tí³-¬Y³FDiMš49xð LˆG!Ô¡—PRR2iÒ$GGGccãæÍ›ïÝ»·Z¼fffÿþýmmmŒŒâãã³³³9s!„ÔÑáÇ5jdfffaa1|øðË—/WÙzEEEE_|ñ…··7 ggç•+WrT!„Ô,Rt÷îÝO?ýÔÅÅz`mmýá‡Þ¼yS«AÉÇ¿ÿþûàà`³¼õÖ[—.]2˜õú!„:Tn :çÏŸïÓ§tÈØØØÞÞ¾ÿþû÷ï¯ôžºÌÌLhž¿¿?äÇÈÈ(**j×®]?f‰BHÖ!‰>|ø7Þj$F Lš4 õìÙ³Š¤œ››»pḸ8$ BÊ+V¬@(ÆYã!„:ôÿU±ÑçŸîççgjj AÂß   ÄÄÄU«V;wNͩޮ]»¶}ûvÈXtt´äIYZZvéÒ1УG¨@„BR%HŠ”””wß}7$$ÄÌÌLDHÀÍÍ-22²gÏž ãÇŸ2eJÒ >ùä“!C†tíÚ5""ÂÑѧíòÓ©S§ùóççåå•––R!„:TŽðÊéûï¿0`€’TcddäààЮ]»áǯX±âÆÏž=£üBu¨4éþýûçÎÛ¶mÛòåËgÏžgmm5qâÄE‹mܸ155qOIIÉóP~!„:¤YÌŸ?ßÙÙyôèÑ’,!B¡U_}õtè?ÿùÏ_ýÅ‚!„êuˆBuˆBuˆ:D!„:D!„:D"„B"„B¢B¡B¡Q‡!„P‡!„P‡¨C„B¨C„B¨CÔ!B!Ô!B!Ô!ê!„ê!„êuˆBuˆBuˆ:DˆbŽ=:{öì$RµìܹóÑ£G,—êÊjê}SMw1:j«««1©Z^êvX.ZÍjê}SMw1ºVÖ¨QQQãÇŸL´Oll¬µµµ::ÄrÑ^VS‡è›jº‹ÑÁ²=ztAAAÑ>óçÏWÇí°\´šÕÔ!ú¦šîbt°¬Y t-ÃY.ZÍjê}ó÷L#¡Q‡XÒÌæËš:Db ¤ob¾ñžU™™9iÒ¤€€€«W¯ªsüÆ[·níèè¸`Á‚û÷ï+L§N:¦ÿ••¥¥›WvÐ!]+ ²š:Dߤ÷u ‚.†e­&M›6533322º|ùòKþý÷ß½½½×­[WXX8a„ðððììl…éãÿ‹/–––¦¤¤Ô®]åhgg·eË–'Ož(,eeVqëÖ­Ÿ~úéwÞñðð¸råŠô®ÒÉÜ¿讕‹YM¢oÒõ: 9g%&&º¸¸´jÕ*==]²«‚.F_Ê://Ϩ½ˆá¥<{öL>“•1°±±A âÿç/P–Ž(kñYY<)) -hɱcǤKÏîçç·k×®Ç+¼h—.]^yåKKKe7)}­ÊÒ!–‹Âr)WVS‡è›t½HˆŽŽÆé Ð-‰†UÐÅèKY¯_¿¾V­Zêä³öPX. 366Vv¤t:òiÂ뉡¡¡”¥íÛU\Gª6HmèËEa¹P‡jÕœ:°mÛ6OOÏo¾ù¦¸¸-/ü?kÖ,I·žÁëЭ[·"""LMMõ¥¬U©º¬ÅƘ˜[[ÛvíÚåææª©C/½t¥ëË…:TÓu¨FÕ#FÀúwìØñôéSäC@@@\\ÂÁ¢C]ºtÝM(n777ñ-99922ÒÞÞ¾mÛ¶iiik×®…<‹núÖ­[Ã|8tôÈ‘#!ˆ¨¿¿ll¬Ìˆòº˜íÛ·+Œ‡©899I|\BB‚ä}¬f»ÆC3gάˆ¿ëÚµ+¤.&&&;;;''§iӦ׮]»ð300°E‹ˆ¤ñ¿$e§¨(kÄgˆ;“““?~ Õ÷óó“.2õËZE:/õwÂå!Oììì¤,•¢‚ýr/DXÅœ¹,™r¡†×_Ž¿5¼lܸÑÝÝ}Ñ¢Eå·­ÚÅ(¼Ï’’$îíímee5hÐ dˆdÄf»v·–×߉~?´zõê…’‚6Š©©)J°OŸ>wîÜ‘Œ€l£Á!ýi¡ÂSîÝ»Ã@Öý­ï‡X. Ë…:d ̘1íkT*xRÖøèV›6m°·ÿþ2—«ÜqÛÑЖ×ÍvU¼lÞ¼ƀ삇}ö쮵téÒÄO;wÎÈÈv»{öì0`€¤÷Ur{ò§ˆ€ÀPF2?Å)ˆ>½¼¼>6lØVtàÀé™]ä‘NDò:AY:ò1½xU)ÞYJ÷mBcÐRaf’sž®%b¹(,ê!ðÇøøø˜››C'fÏž]Ãë€ //¯wïÞÐæ:œ:u꥽16Ÿ‚9(œ$ŒS­ˆ µPþ™Þ-ùÎ.É)"MéP†Â3eéÈ\éÿE&åÜÜ\ع:×Uxº6tˆå¢°\¨CzÏÝ»w£££ÍÌÌ>øà䆊¾šR$à™ç­9:d¨¨ÿ~Q×âºZ*êÞ3bÄ;;;Éj¬Zu1Ô!êuˆ:Dú?$''»»»ÛÛÛ8p@¼Ga éaaa6J(כּ 4°´´´¶¶ÖàÜòÞ°å lý!]+ ²š:¤[\»v-44ÔÄÄdîܹ’Á`¬Zu1Ô! (UNE’ªšÖ ÃY.ZÍjênÙP¯^½¬¬¬ºté"ýe ë€V] u¨&Ã~9]Èjên•“‹‹‹··÷éÓ§¥0gjŽE±¬©CÔ!ÖÀjãäÉ“þþþ&&&«W¯–ùÈŸu€:D¨CÔ!Ö@íR\\üÚk¯™››:T~9Öê¡Q‡XµËøñãíííÃÃÃÅW¢Ì™®CQQQª—! •…Š ÎY.U–ÕÔ¡êgûöížžž(¡””ùùIY´íbtP‡ŒI¢l‚s–K•e5u¨šÉÍÍk{O:U,Ä:PÅ.F§P67Ñ*Êf^g¹TMVS‡ª“²²² Í#=6ë@Uº]3 R-°\ª1«©CÕÉ’%KÜ^pâÄ ÊÐpµêb!Õ u¨ÚÈÈÈ666þá‡>|H[$„P‡¨CUÇãÇccc-,,  ½D!„P‡¨CUARR’££cHHHff&;Ž!Ô!êP•²oß>ooossóÍ›7«^;ŽB¨CÔ¡J¦°°°Y³f¦¦¦&Làw©„Bªj†jkk}ãÆ Ú!„P‡ª”5kÖ¸»»;::þñÇ2˹Buˆ:¤]²²²êׯobb‚'}ðàú'=ztöìÙœ§§*Ù¹s§.ýJ“ yP‡¨CåÑO÷îÝ---{ôè‘——WÞœquuå$=U‰ŽÛ!M‚æA¢•›9sæàé|}}Ïž=+½Æú95~üxÎÓ£mbccuvTš̓:D*©©©P SSÓõë×?~üX³œ=ztAA'éÑ6óçÏ×};¤IÐ<¨CÔ¡rPTTÔªU+33³‘#G2gt½Èmšsž:Ä.cÆŒ±··å•W®^½ªÙÔ 4}Ú!M‚9ObkȦM›<<Eßuˆ&¡¬|ËÊÊ]bª{TÌcÇŽI7JpK~~~»ví’Ѫ§æA¢ý/§OŸ011Y¾|yÅ׸S‘3ëׯ¯U«–ŒçÕ6ê_´ŠoOÞklÛ¶ÍÓÓó›o¾)..†‹Áÿ³fͺÿ¾ëMBµI@ÄÆÐÐÐÌÌLiÄv™£Q‡ô•Gµk×ÎÜÜ|РAùùùÚË™[·nEDD˜ššV¥ÓQÿ¢U{ò^cĈ¶¶¶;vìxúô)rƒ¸¸8éù, L‡hê„ÈØÃ@=ÍÍÍ¥Q‡ P‡>ýôS‡zõê]ºt©RÖ¸S–3]ºt±´´D=AÅvss»zõ*6&''GFFÚÛÛ·mÛ6--míÚµD¯wëÖ­Å›*xgÜ!¶¬Zµ ª)sʳgÏÐNœ2eJ``à¹sç’’’¼¼¼|||pVxQ…È™’’"ÒÄ)’ô/\¸0}útooo¤¿fÍÜÞûï¿ö²ŸŸŸ¸œHJÙÂM;v¬C‡¯½öZNN޼×hÙ²¥™™®‚‚@ËàÁ¯\¹R¹Ž¦´´tΜ9¾¾¾pm‰‰‰ÙÙÙ’V¶f»hÚ3 Qèééé±±±¸™J‹Ô!êðo¿ý†* ûÞ¾};ÚàZÍáX¥ßÌ㢸ú† à,Po¡…ðn¨ØÝºukРü¯ÐEœØ»wïãÇ—””ÈŸrýúõæÍ›Ã}#å©S§¢2ïÝ»Lj]òU†Ì‘Mš4i¢V7mÚTü¿`Á‚Û·o‹Þ3ø\~çàÁƒpCâr  Û%),Y²dË–-¸a<©¼×ÀÁÆÆÆ’-8gI¿ÆPæh¢££'Nœ¨æ—sçÎuqq1z.7xðà‚‚‚Šì’ æ32dî'$$$è\]]MLLh˜„DoCÉpÊ´iÓÄpVêuÈ øÎ;°l´õݽ{· rF¦žôë×ÏÚÚ ÷ œØµÿ~Ô[¸3áéà†~üñÇ{÷î);­K1R!¤KÝÜÜ\xp…uû¥½"’4•¥¯ìr ïM¤OÔD$!cuêÔ‘Þ‚,,,ÔÑ¡rMpÙ¨Q#ÜžÑ?XYYI.¡Ù.雑Ìgj$MB“ÖRø‰,[¶ìáÇÔ!êÞ0ª š´666­[·®Äq¨p_~ù¥š:T¿~}8,ÑØHî­U«V¶¶¶Ø…ÿÇŒ#J®ì™”¥jætT'¢â§šw¨pKãÆá­p®è‘„tÇ‘2G£l Q´Äå㡆 J+ ¢a‰¢h¶K:š9sæ;#Ö=n>àH)Œ‡h/5 iƒoݺÕÃÃÃÞÞ~×®]¾¾¾Ô!ê~ðòåËkÕª…GHMM­¬5îöìÙoõꫯ*›âW¦žˆæÿÎ;å»,Xçµxñâ… ®[·®¸¸Xõ)ºãtÔ¼C…[†W{äȸ*øYÿØØX™WÓ Š)DåsöìÙNNNEIHH¼rÐl—tãF¼Ù¥RÌ›7Oͦ MB…‰ùàééiffF¢éqgff¢n ¶hÑ"I}®Ož|½$ü¸jïµ»{÷ntt44õƒ>¨ ]BÏ7nŒgD¤¸páBéw4}5Qÿ-…ë© IP‡ D‡nÞ¼ùñÇ‹©m¡ø'!!!99¹  Ò¢lБŠ”ФóçÏOž<¹Q£FpÖP#77·qãÆ•ë+ôJgĈ_ägÏ,h‚Íž=[|&Ò¬Y³ÔÔT™•ŠhúÔ!êuˆ:TŽž%D*¾¾¾¢¶I“&ß~ûmaa¡:»úšôÛo¿õë×Ñ7ÔhÊ”)bˆmç”ÕÝÝÝÞÞþÀ¯qwõêÕ.]ºXYY!¨3fÌ;wäD—M?,,ÌF U<å3hР‚okkku®.îÜò\ˆ&aHæQ£uhÇŽ‘‘‘V @QQQ¿üòKqq±6äA¨QzzºDÂÃÃSRR*ku¸víZhh(²¹sçJ÷¡• dQ`` ñññÙ¸q£²÷^ºlú¥Ê©Þ›Ñø`êP5 ƒ1ªC(’Ñ£G;88@ @›7o~øð¡¶¡FˆE5j„`ÂÂÂâã?®ÄÙtTÛh¯^½Ä ”‘þ(R}ŠŠŠF…ƒfwëÖMõÄ\4}ºxšsž:¤Š'Nˆ0¡ÉÔ©Sóó󫲋 ×B!Ö¶‚ ¶oßA´¶ßÁ]\\¼½½OŸ>­ÁµcPk䘭­í—_~ùÒ%Ãiút44 æ|¸²fÖ‘çäÉ“þþþxäÕ«W—w9‚رø/""âСCêô%ÒôéhhÌyêb.\èææfdd4f̘¼¼¼ª) #E999qqq–––~~~; ‚âââ×^{ ¡ÌСCågéWÍÍ›7{õê…¨6lذÜÜ\5sŒ¦OGC“`ÎS‡‹«««™™ÙôéÓÅtñºÀÝ»wûôécmm­%)?~¼½½}xx¸ø¨[ý·lÙR·n]„kžžžëÖ­+×bá’ ®ˆC*—N:)›UV×¼!M‚æQ£uhÁ‚!Dßÿýƒtê‘=z4xð`[[[HQåvÐmß¾*+,ר}ºuëÖP/Žš ç‹ÐL&UˆÂu†tšÍ£Fë*€¿¿?³fÍzé@¯êí Cˆ­]»v7nܨà»+œ>`ÀhILLŒêé„%@ü/^ìåå…¼jРÁž={4ž}®ŒTº\oY:4š«C7oÞë^;¶°°PÇŸíúõë"‚?~|¿+Z²d‰Û Ä´ó/=>//¯_¿~¶¶¶¡Aƒ!ßôb BÑi‚ÿíÛ·/b‚öíÛÃÅëE‹`ïÞ½b2ì­[·j<ÛBFFFpp0å‡~Pg|Áo¿ýfffÝZ¾|¹nv]BˆþéÐܹs===;¦½¯s*½ûbòäÉŽŽŽ†Ë—/k ?޵°°0`€ôbÊþì³ÏÄbϯ½öÚ©S§ô%£!D×uèÚµk 4011A¿\cŽ«{÷>úè# zçÄL !!!™™™ªeìüùó111–––-¨Ñ_ýÅNdB©4zçwlllÔ‰ tßÿaœ‹‹ ”r½§Ù·oŸ···¹¹ùæÍ›UŒ2€Þ@ž}|| ÓP¬;wJ¯²L!¤¢:tôèÑÚµk;;;«ù–^×€NtïÞ‘J¹Fý6kÖÌÔÔt„ *Î*((4hXDµÿþ9$B*Y‡zôè'w\5³Yk5$:w:1tèP[[Ûèèè7n(;æÀfffNNNß}÷Æ @¢h#Ξ=›ÓT;;wîäEZÔ¡?þøÃÛÛÛÁÁ!--M[ú‰âââ,,,¦L™¢ÎW¨kÖ¬qwwwttÄã+kðôéÓéÓ§CØŒ¡Uˆµ7Ç+} ý‹2¾úê+±’/©^8Âvuè½÷ÞCX0|øpÝÿ`H5bùÔzõê]½zUõ‚¬¬¬úõ뛘˜ ’+œµtêÔI,¢:nÜ8m/uA_Cÿ¢Â6ÄDsãÇç4ÕBll,gœÓ®ݼy388ØÒÒòÈ‘#úøfH„5-[¶„rüúë¯*à0ñ2©Gyyyò¬[·. *åïï¿iÓ¦*h,Ó×п¨¶Ñ£GpŽƒjaþüùœ[»:´xñb´Äãââ4[uT×øüóχ ¦"¶›3g¬Ê××÷ìÙ³2ý÷îÝùöööFFF={öDTT5ÚL_Cÿ¢Ú6èY†¬C]»v“jƤ‡òòòrwwWöMkjj*ÈÔÔtýúõ2c¯=Ú¬Y3sssè,¯*çÖ£¡Ó¿Ð6X5T‡233á”mll222 ã“ÌgÏž½òÊ+&&& »æ -­Zµ2339r¤tÀ„ çË/¿¬U«–±±qddä‘#GªxÙY:ý mƒEPCuhÙ²ennníÛ·7ŒN9Á|`gg§pn…1cÆ ÖPIdÈÎÎîÞ½»µµ5‚¤Q£Fݾ}»ê%™†NÿRCl£OŸ>¯¾úêÍ›7+1M´§'Mš€zŸuêÔ1ý‡¬¬,õÓQv"«§vuèã?vppøä“Otg¹ÕŠ#FÍõêÕ Š"½}Ó¦MþöìÙ# w6…„„Àìj×®«kB#ú­ú½ö/†g-[¶¬\ÛhÞ¼¹™™™‘‘ÑåË—ñ388ÿ_¼x±´´4%%U厶é–-[¤ûH¤­BFé ‚‚‚$IQ‡ªB‡:vìhaa±nÝ:™¥&//FP®&Œ<çÎóññÃB #Ù»711™9s¦xñóàÁ„GaØ\çÎ/\¸PÃék*âk$Ç&&&º¸¸´jÕ*==]²K¯ý‹Š›¬”úRÅ•ôù *÷–ž={&]¸Â6ÄÿeeeÈ71‡$š¡ÇŽ“¶ <…ŸŸß®]»¤ ôéÔ!­ëÚþõë×766>yò¤Ž|¾º~ýúZµjI[€fÔ­[>KòY®d=‹ØØØ[·na ŽŒðhÖ¬YÕÒ×TÄ×HˆŽŽ†8%$$4mÚTº!¢¿þEÅMVV}©–JZ¹H®|ACÄÆÐÐPÖÒÆ‰í2ÏBªRÊÈÈ@Ü€ õÚµkºp£P±¨]ÅM¼C‡æææ’0|Ñ¢E®®®h A™àÎ.\èéé F„´ÿ~W-¢¯Ñ)_³mÛ6ë7ß|S\\Œ.þG Cz&Ó¡J¬/ÕRI«Ò6ÄÆ˜˜[[ÛvíÚI¿§U³:tÈÛÛû_ÿú—^Jrrrdd¤½½}Û¶máÐ×®]‹ª.ºV[·n-1b„ƒƒ¶¬ZµJõçŸûöíƒY 5˜õÁƒKJJºtébii ÀénnnV$]·‹/¼j¾xLLLD #\ÒéÓ§ÅG©Ë—/ǹ½{÷Æ.ˆÐ!CpÏ:2J¾¦â¾¶/³cÇ4,(ô¸¸8éï” L‡dê‹xm¦A%•9 5D S¦L 00¯X±BýùFÅ£ÁùâDx1ü…»üí·ßTL~Z.P]?~üàÁƒ»wïÞ¹sµ¾žÞÿìÙ³éééDŽ9ràÀ={öà1‘lÚ´ ÉÏ?ÿŒø‘Á?üðí·ß~ýõ×ÿó?ÿóÅ_@2•M¸I_£¦¯ÂÁ×ã1EAçàÐ¥;UÄCü±ü,¨(5y“kذ¡´¢àö$Š¢Ù.ùxѼômÄÅÅ©iPI•R)¶ 2nÜ8DÃ0¿Aƒ‰’ôéb8Ìœ9sP7ÑÜD)ˆoÏU\ýÌ™3-[¶DÌ -A¬¬‰Ê"2ÄÓÓÆIÒÓÐÁéÀá¢];Œ²ÃOHÜ ¼†|“M!bÙ=üÍÍͽ~ýzTT”Â~91Þá3ÒG³ú¥«9È<œ²¨ü8wðàÁÇ÷Ýwßyçöïß¿wïÞ={öÄsuêÔ wÞ¦MøqÜI“&MÐzÅ).\Í%«›››““ÄmÃpM•c¢¢Í«ŽÑ×(»C”/ HL ö÷÷•¥Ð¿¨˜^VþygÏž K(Š$Ôx— Ê&cUXOežHƒJªì”J± Ѥ8qâ*j臗>¹?üí$´`E’ŽWG=EÜ µFKEÙ]½T‡D>£º‰E–©Czó~hãÆîîî"¼€áöéÓq€d/ Pÿ{X1µRƒI!Ù·ÞzK¤&º/à1ÑúƒùB*Ð&EšpL>>>;v¼té’:o‰Äû!ܧðï¢S¾\©™`ee#ÆUàd½¼¼üüüЇt………EDD >GGG·nݺmÛ¶:t€ÔuëÖ ²‡'‚¾ýöÛ¨™Ã† 9r$Ô@x$¨ŽÑ×(»Ca¢‹-Òê¸mDðH‚Šò‚ÙK/¯Ù®ŠôÙJ×”¬•Tá)÷î݃!!¯Ä—…2?e.ªºEÌ]róæM4ò`~2IM:5##Í#4$¢úê¨_¢+åðá₆"Eécä Žº{÷né˜'OžÄÇÇ£D¨CÕ©Cÿýïa‚ÿþ÷¿Õ/‡æÃÒ¥KCBB¬­­;wî ë‘~ƒ k0`€šã¿EjPÁ€€¢¢óçÏ‹Ô6oÞŒ‘‘‘©©©¢;ƒ-zQ[Ô·-ÆËI^‡@&L˜€p±Â?ü°bÅŠÕ«WÿüóÏ6lÀ!uhªïÝ»÷àÁƒð}p©§N:wî\ff&¼*Â5´©!ÕhÅ£íÛ…s,UÎsP±}š¾éCï¡ap:{´d>Œ«,ÿë•”u¥ìÒX‡¤ë ÌRƒJªðQÝlÕMæ§ÌEUÜ92•.** ÿüòË/°I™¤BCC¥û`¥å¡Ö*®¾råJ ÁãtïÞ)Ã6|}}¥‘ïB®@¼"•v ¨×h·iÉNˆZ:täÈ”¨Â÷ŸT¿òÖ.…©‰Ø"Ù+*’´£W'ñ!C†ØØØ :TÒâââòÍ7ß u¬æÊ4º3N¾F_#ÈËËCĉBG ŠÆ„ŒµÞ| ÒõEãJ*ŠLu“ù)Q¯QÅEÅ?òI¡Á„ƨèîFãÍGÐK¯.“²Ì1òÝû*Z™2NªR}èÈt1XÖóæÁ™ŠAÃb´xýõ×e7}aøéNBewnx:¤ïìÞ½û×_EëPë7Z¶lYñé]ÊÕ«¬ÎéÔ!-êÐß/ÆÔš››Ÿ9sFGæ—«,Äs¥¥¥ MjÞ¼¹›››ø0ó»ï¾ÓµEÿèkªÀ×P‡t „Ñ“'OFƒþçÁƒ3gÎTsÀ-uÈ t¨{÷îh¥*\2®‚„……Ù(AÛSvŠÅý$óæ!B{ÁдiÓºuë&b#üS½lÓ×P‡ À6*XÍE¿««««]‹-~ùå—JYx¥Aƒpk¨éåõ6âq,_Àõ‡ªN‡Ægoo¯pɸ ¢âM¾¶xË–-:tŒÙýñÇaë...‡^¶l™¿¿¿xQñÃ?èH`D_£U_£×þE—o²‚Õ\Òïªf'°wU)'R‡´«C›7o†ËîÒ¥‹ôtúŽ,'=OL|РAðDbq6ÄIo¼ñ†Œzöì©æXpúýõ5zí_èY®CðÔÁÁÁŽŽŽðÅ:2ótśʌ]¾s玘ßpâĉþàùøø@м¼¼–/_^]+±ÒÐ™í´ ÚIÖ¡¿ÿyEôóÏ?ëÈ’¬áNPPƒƒƒ˜ÞFz×îÝ»===ñ°b]"ì½råJ=¬¬¬ F½{÷ÎÊʪ®Àˆ†Îl§m°j®}ùå—Èb5¿fÕ}æÍ›‡Ç‰‹‹“žÐEáË#«üýbRÎ%K–Ô®]Räíí½zõjõg±£¡Ó¿ð&i'¤tèòåËbY”³gÏÀèm1‡ÍÒ¥Kö³!æƒDYXXôíÛW2 éÒ¥K8QFýúõ»zõjg þEõMFEEMœ81‰Tbé VO-êèÕ«\ðçŸ.†Ò_ÒÒÒ|||jÕª% wäÁ®蘈L²½¤¤äÛo¿õôôÄ.óºuëª20¢¯¡QmƤZQ6 1©4JNNvww¬¢¦§ˆõ[ß}÷]e‹Œ V¬Xáææ†º}äÈé)=ðìP©Î;#¢255}ë­·²³³«&Cèkè_”!¿©®B*M‡?~,ÖT†7|ðàž>çÍ›7ƒƒƒØ:tHõ”h–ÄÄD<µüòzŒ¾þúkFÐfÉbÕô5ô/ÕBÑ('ZÔ!°víÚZµjéuH$Æ ÄÇÇ«3à"??_,_=~üxùox‘;vÑ Aƒnܸ¡Õla §!¤¦ëˆöíÛ[XXL™2E,&­_\»v Átå÷ß—YãUûöíóööÆ#oÚ´Iá´FOŸ>7ož»»;£   ÿþ÷¿†1´BtQ‡ÀÁƒ}}}]]]?®ƒ3R«æí·ß¶±±0`€ôbÿüs„PИóçÏ+›¦úÌ™3íÚµsE2$''‡ÍgBÑŠÁ½>ÜÎήM›6Ú\¶nÝêéééì윚šZ.E$F%ÄÇÇ«06wî\777FuêÔŸÁÒ°!¤’uܾ};**ÊÜÜ\zçòóó###MMMçÍ›'½´š\¼xÒùæ›oTÌy UNOO‡B[XX Þ{ï½ÜÜ\F„RÉ:öîÝëããcmm½mÛ¶§OŸêþãõíÛw«p5ùé§Ÿë8::>|XÅ@;¨ÎãÇgΜéêê ݪW¯ÞöíÛBH%ë¼íŒ3œœœBBBþüóOQ´`ÁÑ#§z¬¶êG:t¨­­-bÁ7n¼ô`dKëÖ­-^0räȼ¼<F„Ri:ô÷‹hzöìiee™••¥³NvýúõÞÞÞfffŸ-»   Y³fHjìØ±/ý¤òèÑ£iÓ¦Aÿ…††¦¤¤èEìH!ú¡CàîÝ»íÚµC{ ]XžGž?þø#((ÈØØø³Ï>«”Eü<U377߸q£:½mP£cÇŽµlÙ§ £Þÿý;wîh¬ÙG={6'Ú1`vîÜ©k_ËÒêh:­C ;;[ô>µiÓæêÕ«:8p@ .>|¸ê)|4è ÈÈÈPGzqJqqñäÉ“q±aÆ»wïÖ,0úꫯ\]]9ËŽ£ƒ³Ñêhº®CÒRÔ¼yó³gÏêÈ»¢;vˆ‰J+Q„ƒºtébiiÙ«W/õWÁ€>|XŒ3Ĺ~øa~~~ye[2Ïéøñã9ÑŽ«›³©Òêhz CBŠÄ`åúõëëÂ[U«VyyyAÛGŽY¹"$¸|ùrݺu!råšjªƒƒ?ùäGGGÜ[DDľ}ûÊ•WÂ#Œ=ÅYv Œùóçëæê´:Z ~èxWôïÿÛÊÊ Šš””T]ß¡Â888M˜0A{ºfÍšZµjáB//U†çϟ㔦M›"0Bv}ôÑGê+%×2`t¶piu´@½Ñ¡¿_Œ ›>}ºx ÒºuëS§NUqÝÑ£G_}õU„e666?þø£ŠN+åEѰaÃlmm›5kvýúõòž{ÿþý‰'BÆWMš49xð :óÝÑ#Ð ðÆuèåvïÞ½uëÖ555ussûôÓOoß¾]ƒ>|ø?ÿó?pëAAA»wﮂOGQZQQQfffï¿ÿ¾%‡Àhß¾}7F "‘W/M„^€7F¨CjIQvvöСCíìì  ~~~óæÍ»{÷®–Ô!ך5kÂÃÃÍÍÍáЪr¹î?þø£víÚ¸î/¿ü¢Á4ÛÈ“{÷î‰uùWÍ›7?|ø°ŠÀH=BŸ>}ªÊ/ãT•dffNš4) R¹·T§NÓÈÊÊÒì`ê­N{V§/hT¹ÉA 8 zÉLLL F(ŒœœœJTdÖòåË[´haiiiddÔ²eK„AU¼æ„dÖ¬YNNNxÀsçÎiöt8 w=³µµMJJRö©“^{…Ë V%b))˜ÊåË—+÷–‚ƒƒ‘ìÅ‹¥;¢ ]\\Zµj•žž.ÙUúDí’;¡Ñê*hu)))hCWÐú—™aYZu„ðè²UzŠðÑOŸ>E°Ò A”Úûhõ÷ï߯ xNÃ#äàÑ£G‡ æãã#’Eú«V­zðàAµ|½„gìÖ­´ðßÿþ·úøåó y2fÌA\NA¤ÂPòòò`XåjUõ/úüÕ땟ÒuO[Ró…G®Ò >>>::n1:œQvv¶êSôQ‡hu:buˆE>=<<Ž;&ÝîARh(ïÚµKº™®›h¤¥tÅô6?ÿüs§N Õ&/€·…מ?þž={à»_Z0> |²Û¶móôô³³£Lñ?âfé‰Þ C‡hu:eup¶bchhhff¦´WÄv™k–I2™’žžß*ü,„Dh’……Ä*õöÛo# ˜4i’˜^b„ PÎ;7jÔ"Sp°¤0vìØ´´4„Ÿ:2ƒ„V ã>pà€ÆS©ŠŒ*((1b„ÐìV­Z?~\’ 2C¹uëVDD‚œÕrѪôê? |²(A[[Û;v \Fa¡ñ‡vnåz4uçÌ™ãëë‹k%&&"ä’¸Ív•K‡huºfubcLL J¶]»vÒk P‡þ“‚tæÌ™E‹ <9nmmýÒ©& BPø¾}û"$ºtéê6Ñ©9„Äò€(þ&Mš”w·ÂÀ jÑŸ‰ÀM颢"†"æw€U‰aŠâhrrrdd$NoÛ¶-4{íÚµh•‹>bÄ‘0wá.¡Ø²jÕ*„­2§@ÿЪš2eJ``à¹sçÐ8ðòòòññÁa8XáE"IÇHþ¿pá%ÞÞÞHpÍš5¸Ÿ÷ßZîçç'ÒWÿHqù›ÛSSSQ'‘o .ôððuOú–DO=HÓÊÊ ­œÕ«W#W'WÅUä«tË–-Qv¸sað8ù|åÊ•ÊõsçÎuqq1zª *”ä[4Ív•K‡huºfub#šû±±±HdàÀùùùÔ¡—GHÏ|êÔ©7.[¶ 5dòäÉ“^çûý÷ßoÞ¼ùìÙ³ÅÅÅhÄéšöÈp÷îÝ-ZÀûŒ=ºâ‰'… ½ûî»Ð6F¯½öÚÉ“'¿üòK…†"<ô«òíÛ·£önذ55§^½zhö¢juëÖ ò‡(r'öîÝ!WII‰ü)ÔæÍ›‹·¬S§NÍÉÉÙ»w/Ž»ä/ª éWµ’ÿ,XpûömÑ…ªŽôQÕÅ4²"}õTø¼bûµk×êׯj‰Ç_±b*¶ÌmˆzˆÊoccƒ4:T»vmwwwœ¨N®Š«ÈWiì‚‹—lÁ¸œt¿2/ЫW¯O?ýTÍÙ'5jÛ0ú¸3É%4Û%™Ø´S§N §{¡ÕéšÕIô ݵ¦M›&š°Ô!uã$eü­?9rDŒžX¿~}¥ŒÜƒQB‰ayh9::²!K Eƪúõëßwƒ…»»öïß›F+L4á#~üñGñJá)’·¬C%ÐæææÂs©Ùá ýªVa‚ ÓWÿHÏ;a´"áÄŸ¾@þ6Äa;wFjð"YÉxV5sU>êÔ©#½XXX¨£CÑÑÑðMjÎ>Ù°aCiEAXr ÍvIîDfbSF«Ó}«“Ö„M"M´ïfQ‡j°§9sæ ,¡Fã*eôÒD»,11 ¤¾G@s ‹&•@’Z«V­váÿ1cƈ®§È¤,ýSýŽog©Ÿ¾ŠŸÊn¾qãÆ¨À/M%ÖCûöíE¯ˆÂP3‹$×Å‘â} ¼<»t'’Šxèã?–ŸƒbùxQ‹“““DQ$ý0ší’ÄC3gΔ\:..NÙô—´:²:iB>oݺÕÃÃЏk×.___êP ¢¤¤D̳׭[7é÷ÒŒ6nÜcRÖ4–±*Ñ-2™#Åê´‹/^¸páºuë$³);E/<‚²›¯[·®èâPø™3gZ¶lÙ´iSTÝÚµk+»5³ˆ—…ˆá5àsýýýËʼ7VèTL'ªÐØfÍšåíí {4hèÕ©È.…ý*¦¿¤Õé”ÕÉô¿¡ìD¶{zzš™™Q‡jhö6hÐ1b#顺ŒÄô}êx„®]»¢…“““[‡»»ð300°E‹h…áI ÊNÑ  ìæ;uêdaa‘œœüøñc”‹ŸŸŸÄAHŸÞ¦MsssÄhŸª¸5³ Ñàîî¾hÑ"mÛ†Uˆ6²|ð­Ù.õÇ)ÐêtÍêäß¡ Qpvvv ¤80A¸!DÄûöíSgS5QÑ2/ŸÑhêÕ«ŒUøAOCqŸ>}îܹ#9­`´ÖÑ,•~‰¥ð”{÷îÁ}À^Ož< Ÿ%óSæ¢Ên[ú,ܹŠ%?Oœ8¡þ‘ð§ÊžW|ŠyúôéC‡!À)ØrêÔ)éÔÂÂÂpnJJÊáÇEËT¼áS3Wå«4n ÎŽ.£ÿþ¬Ë^ ¼:D«Ó)«ƒAóvïÞ-ísž}åÊ•pð È™îÝ»£ŠÂ#"Q½h Q‡*™¢¢¢W_}q÷ˆ# µíDO‹ôÐvÕÝ2 ;däO)•Bþ§üERªÕ髤êç•l—|* Ù"ó ’cÄ?ê窲ž"‘”Âü1 ¢ÕéŽÕÉß¼4¹¹¹2šMª);vÌ××m“µk×Êvª\@ª‘òNÜb0:DôËê¨C5´wN|yZ»víÓ§OW|7=uˆ:D¨C¤|”””ôêÕËÊÊêõ×_¯ø0n]öaaa6J¨âù˜«ž XZZZ[[«ó°"£,_Àõ‡huUcuúbÔ!m‘jjj:{öì ãÖePªƒ/âr=¬²ƒ©C´:íY¾X uH‹ˆ‘—¶¶¶{öì©È0nö0Ô!‚¦i1—‰]DDÄÕ«W5ÆM@/À#Ô!¢!EEE­[·6776l˜ÆÃ¸éèxc„:D4çøñãb÷êÕ«5ÆM@/À#Ô!¢9eee¢¤½¼¼N:¥Á0nqzTTÔĉ“ˆa¡l™qO´:Z uÈ@xö왘ëIf•èrycb ([ÔCtˆ¥C ¤7nÜ 3551c†X*Q}d†!†‡Âu†ªZ-:d€lÚ´ÉÃÃÃÆÆæ÷ß/×0î2RÐÁþdB ¤à‹¢±cÇÚÛÛ7lØðÊ•+úµö9!„P‡ û÷ï¿öÚkæææC‡-((`†Bu¨ª9yò¤ŸŸŸ©©éÊ•+uí•!„P‡ Ÿ²²²¯¿þZ¬Ÿ––VfÄ"„êníéÓ§µµuÇŽsss™!„ê©jnÞ¼njj:mÚ´òã&„ê©¶nÝêáá¨è·ß~{úô)3„B"UJYYÙ¸qãìííCCC³²²8Œ›B"U̓Ú¶mknnþÎ;ïp7!„:Dªôôô€€SSÓåË—?|øB¡‘*¥¬¬lÑ¢E...îîî'Ožä0nBuˆT5Оþýû[[[·k׎ø !Ô!R äää4jÔÈÔÔ4))‰Ã¸ !Ô!R ìØ±ÃÃÃÃÊÊj×®]ÆM¡‘ª¦¬¬lâĉ 4à0nBuˆTÅÅÅ111 ùùùÌBuˆT5§OŸ 411ùñÇ9Œ›B"UMYYÙwß}çêêZ«V­'Np7!„:DªšçÏŸ0ÀÚÚºmÛ¶·nÝb†B¨C¤ªÉÍ͈ˆ0554iÒ½{÷˜!„ê©jvíÚåééiii¹}ûvã&„P‡HUSVVöÉ'Ÿ888Ô«WïÒ¥KÆM¡‘ªæÑ£GíÛ··°°8p ‡qB¨C¤8{ö¬Æ=xðàI“&%ɱcÇÈ•ü‰G={6Wçø~øáþýû46B¨CD1K–,quu5VÂèÑ£ÿúë/ù³¾úê+…gñxùã!ó_|ñ¥ˆêQÌóçÏcbbÌÍÍŒŒFŽ9éÿ²mÛ6…íý#GŽÌ˜1c’<^æxgggd¬2¹"„P‡Èÿ2þ|¸KˆPAAA™ O)S—>~Þ¼yÈ[ê!Ô!¢Š¯¾úо’yKuˆÐW ¢ƒNY÷!„:D¨CÚEu÷!„:DØf'„P‡Ûì„B"„B"„B¨C„B¨C„BuˆŠ"&>þ?ÿù$ {cbb¦NŠbofff=powïÞÅaH *(oÊŽdáB"ºÎ¥K—: pƒ¤áâ¡""Âxï½÷¦H¿Z½zõ¤I“®_¿Ž&))iòäÉ"‚„ôïßÿæÍ›8}Ó¦MÐ'ɘº‰'":IOOúô)Î’¿ÄÄD¤#ь޽{ïß¿‹8iÔ¨QW¯^'B« jOž<‘¿7Gjç2'„:Dªˆ & † xðàAxx8¢8ô°°°H>âi×®ÝG}Ý!H‡ 9?ÆÿŸ~úéöíÛ¡ï¿ÿ~Û¶mOŸ>- SpØîÝ»…®Èƒ³»H‚$DW-Z´ôÝ!P[»v-nIü2dˆè¯“¿7eGj ç2'„:Dª¨Í%=(`Û¶mC‡½}û6"¤fÍšI$áÎ;uëÖMNNÂÁhܸ±äƒÖèèh—×_ýûï¿/**’ %ÏÏÏïÕ«â$eWï×¯ßæÍ›EšàÃ?4h®.~¾ùæ›§N’ýûä“OÄ`n™{SqdEtˆsUB"UÑfG`!yÏ/úÎ;Ÿ½÷Þ{’Ÿˆ?$/‡ Q/^D˜*,,„@ iÁYHDr˜<õëׇlˆÿùå—W^yå‡~(..[$=„Hyøðá8@(®Ì½©8’:DuˆhW‡*î+ûöí»páÂû÷ï#âùì³Ï¦M›&Rƒê,Y²díÚµŸ~úiAAÁøñãW®\)Qˆ#F|üñÇø+ÆÅõèÑ’õÊÌÌ|ã7öíÛ':âptEÒ]&O‹- i>\´hQŸ>}zöìùÅ_|ðÁ"š ß°aÂ)<éÀq ܌̽©8’:Duˆèºݸq£K—.7^±b…D3UÄÆÆ6  Êi×®]ZZšä­O|||×®]Ïž=+¶¤§§CQìíí!B§OŸ–~¥tüøqÓÄmݺ5äóæÍ»wïÞ˜1c:wîŒ ‰S |ÞÞÞHò6räȸ¸8¡p2÷¦âHê!Ô!¢ë:ô÷‹¾,ȉèU“Þ(ü”ß+ù‰]ÊQ=íö–¾@&’•œ"öŠ Iï’¹7GR‡¡=Ð!¼%„:Dè+u ®?DuˆP‡ª®?Duˆ°ÍN¡¶Ù !„:D!„:D!„P‡!„P‡!„ê!Ú…ëB"¤:áúC„P‡ÛìÕ¬CüF˜êa›:DuˆÐW2o !Ô!B_ɼ%„:Dè+™·„ꡯdÞB"ô•ç2'„:D¨CÕ ç2'„:D4o³‹ïŠ’äPö¥W}馛îèJ’dô}~÷õù¼îyÏSͶÕÔãñÇzý8¯çt¶×£×yóúË$&á`r€É&ðŒLnqqñ€Ø,--ñßà‘šœ ÕˆÍÛ·oùoð¨M®´´ô-ÀŸ)))ÁäÀä­!î L09ÀäšÝÝÝŠŠŠ[©ªªÚÛÛÃä“{HVVVÒÓÓ}>ß­JMMM¥¥¥­¯¯cr€É= ûûûN§srr2޲###©©©‡‡‡˜`r€×ëu»ÝqÏÉÉ©­­Åä“»o677å Ä]C¿Ô°½½É&w#ýêèèp:/_¾,--ÕŸºýÛ…0DÕÁ)))§§§mmmv»ýÅ‹zoƒÎÎN9l~~>îÎøý~©¡«« “LîzDË”¨ÍÍ͉HeffMN OGEøTxttTdnaaAÂ999êÈÂÂB‰žŸŸÇÝ™ããc©¡  “Lîf§úã«F“3FC¡Pd–ÕjUa»ÝnÌŠU¿ÔƒÉ&w “3I‰|Øz“¬¸;£Õ0±L®´´ôçÍââ"¿8“KT“Ssr¡Pè;“ sr ×_€É=¼ÉY,–H]SŠfbrj\0Œ»'ggg‰»Nî9ÏÉar€É= ê%ƒ0“ËÎΖ”………ÓÓÓ>¨RSSõÁ0–UÑÈwWÅíŒZf€ÔÐÑÑ‘ˆ&÷œ×É©+€É&wïçùw²²²ŒF•‘‘a³Ù^¿~}vvæt:Å®ÔçâŒ% ‹nooKÀ¸OWQQ‘èÚ £ÂÐÐÔ ar˜&wßÔÕÕ•––Æ]Üãñx½ÞõL“L.±9::JKK£ìää$û®br˜ÜC²±±!B611q«R>Ÿ/==}ee%q=“Ãä“{ ÔÔÔܪHeeåÞÞ^B{ &‡É&˜&ð{L®¤¤ä€?#w&‡É@˜@,09L¯É---½ˆÜ!˜¿8à‘š`r€É`r˜&€É`r€É`r˜&€É`r€É=çççoÞ¼±Ûíuuu¿µ!‡Ã!#ñÁÁÁãùÌÏÏ[ryy+*}¾“ÝZå [,–ããcî{L0¹;£²²rxx8 eddüÖ†ÄáÜn÷cû–——ÇŠŠxÝUŸåôóòò¸é19ÀänÁÐиZ¬ÜéééÚÚÚû9Û±±±®®®Çö3øøñc¬¨ô¹»»ûNšššº«ª09€garûûû¹¹¹_¿~šûãÇŒŒŒû9Ûúúú………Çö3‘][[3‰~ùòå Ÿ>&p¯&777çr¹,‹ÚRÝ(m¯_¿NNN¶ÙljîgrrR-ó ;RQ]]­³UâÒÒRaa¡”òx<âyÆãM²L”Þ¦¤¤¬¬¬È¿¡PȤÂíímé¼/á`0øêÕ+»Ý.5˜œc$r.­­­ê©A%J»ïÞ½KMMs]^^NJJR+á$=--M—Œ:Îõõõââb©-;;[ΘµÎX}ª¤HKK‹¾ìóóóüÀäày™œøÁêêêÕÏõøÚÏ$Åív‹º‰LˆFˆ©ôááam‘H ^¯WG?~ü(²òíÛ7 û|>Ñ—›dÅâôô´¬¬¬««ëäääèèHŠÜ¤-‘¹ÆÆF9¾²²RNjzzZŒÓüˆiIµ>|¸¸¸m’°êIyyyOOT+‚XUUÕÜܬŽÿòåK}}½.×ÌÌÌlkkƒ”ÚFFFT…æuFíƒt^Èîî®”ªxõ“€çhr………J€4âEEE¢*ÚßßßÒҢµµµ¢>±ªêîîRá­­-q]‰`³Ù®Í2¡¦¦fttTGEãDn®­p``àÓ§OMMM*wvvVDÊü5’ër¹677ÃÒŒsiƦSSS:+,*¢¦Z×X­Vó:cõáýû÷r©'&&òòò¾ÿ÷³¸¸øÇs¥¤¤DLNþýb#~ð‹àQ›œ¸B~~þçÏŸÂ1??/z$ªTPPÐÚÚªÚív“/hH=z‘œÈS ÐYÁ`Ðáp\› ŸÏgœÜWÓcRaYY™(šñHµ¶,Ö9“ã#çÞÃêI>ÁívïïïÇŠŠuéçÎW?Ÿí¾|ùҼΨ}Pç•••e±XÎÏÏ}^ oß¾å+À£6¹«ŸöŠŠŠÄ–T4##CL¨¼¼¼··w{{[¶ººªÖœÅªÄétêhjjª1wbb¢¡¡áÚ¬X”––{ÒÑÑ‘™™ym["gâ:ccc*]¢jm™É9IOO÷ûýa‰âXÆW:$,²¥ÂbiúiidTŒÙãñ«êû‰yQû '’’’"ò*¦ø‹ï—(““ËûàϨ9KLàQ›œü¦VsQÁ`P¤A%ŠýÙÙÙQOúo8m¶ìLœC¿Âi’ ãã×OŸ>IC­­­×¶5;;›ŸŸ¯Ó§¦¦tc£9Æ8Q·°°pvvfìÉÉɉ¸àúúºŠŽ·µµ‰À©GÌaÑééi±F£®½|ùRô7ììÂêŒÚ9/u""¬Æ§·q›£5po$ªÉuww‡B¡¥¥¥¬¬,•X\\ÜÕÕ%Æ é¢#"CêUÐÚÚZѿ߯f’ÂxýúµÑ*¤µ¢n_üÏøM5“¬XˆeŠiIÞ¿/B)'zÔÓÓc^¡ˆÔÄÄ„®DìGŠ+ŠuŽF<T%I£íííW?7–’(×A.]KK‹X£z6*õ‹ÎvvvŠiE.//+WÍÎÎÖ«ßLêŒÚ9/u©å¬å|Em#ù1Z&ð,LN°X,¹¹¹zhwwWÌÆjµfffÊïqÑ•îõz+**Ä¢ÄE"«ÊÉÉ1®Ù’Jòòò¤©jnnÎx¤IV,fff’““Å5%põs.ª¼¼\¯Ø‹UaØkrŒœ‚ÚÝ+Ö9Ó‘’‹#Mëul¢}III.—kxxXù™žB+--•úU#£rLuuµÍf“âr æLêŒÚ9/u;;;r MMM‘‹üžÀh-.7•\1ù™¼góx–¨vJJJXºÜlòçVUUUUÝÉ–n˜À7¹»BÄâõë×ü˜w¹+>þ,ûöí›üyÐÒÒb\ùh‡‹üÔâÊÊJzzº^„zC¦¦¦ÒÒÒôWܘÜ勵¿?Ö{€ÉÅAee¥tÌøåçÇô6òóÚN§3¾ Å‘‘‘ÔÔTãÜ-÷&wÇdeeÉèõéÓ§wïÞqõ1¹;Än·Gî#’ÿÿlr^¯×ívÇ][NNνíbŒÉ>– ðÞ(--}æû•-..ò‹09Àä~ÉäD•$ª>#¢&ᢢ¢k³L°X,a{à^ýüÊ`ät`ä{ Öæ655é ¢’Æ#}©Ÿj:ìÃ×÷|o€\~Q&˜Ü/™œÑŠ.//.e’eBVV–™->§¿Æ'£ºW¤Ééhrrr¬¬;YêwÃÓù}÷Æsž“Ãä“LînLÎf³IôââBç:Žk³L8==mnnV­¨3®~NÔIT=u½¡É©"úk)‘sr¿ø!•Ÿ“{ÎëäÔÀä“LîWM®¬¬L¢jõSo¡k’u-ËËËuuuZ•<¯ªª’zöööRSS¯5¹ÜÜ\ «}ØÔê:moj\0Œû"œ=ø:9L“L0¹Û±½½­”Ho†ûõëWå4çççïß¿·Z­×f™›âÎÎŽÄØô“““zu”Ô£v³U¯ˆŒŽ«ÖŽŽÔ*=A)`仫âvF-3^ý|'WjèèèàÞÀä“H˜Ñ:ò$‚ÏçËÊÊÁòx<Æ€˜g™41==-çr¹¾}û¦Ó‡††œN§Íf«««SÓia‰ì›q8js-)ÛÞÞ®TRù¨qŸ®¢¢"ѵFUÍRÃææ&÷&˜£õ}#:XZZwqS¯×˽É&Àhý¥¥¥ŽŽÆQvrr’}W19Àä­’ ²‰‰‰[•òù|ééé+++ܘ`rÏq´~<ÛøÔÔÔܪHeeåÞÞ÷&˜£5po`r€ÉÁÓ«JJJþø3rW`r˜`rc@,09L09x¼,--½ˆÍ ¿Ï‡É`r˜`r€É&€Éq)“Àä09L09¸ü~¿Ýn!xÀT“Là144TYYyWµmmmy<®*&€Éüvö÷÷sss¿~ýzWöööra19Lào¶¶¶&''Ûl¶W¯^IÊöö¶„­VëÅÅECCCjjª6³×¯_«#»»»u ¡PèÝ»wrXFFÆòòrRRÒåååää¤Ô w80¯A«iEYY™Ôÿd®üâââ3Ù¯ìþáJJJä_¶n»ÏùkÒ˜ÀXYYÉÎÎþðი“™„UúÖÖVUU•ßïÅÅÅ’²ººêv»ÅÏÄÒDþìv»:òôô´¼¼¼§§çèè( J©ææf•5<<¬ÔP«†0"›VœŸŸ;Χ7SÀo˜@<ˆ{¹\®ÍÍÍȬ¾¾¾ÞÞÞ?~¨èññqQQ‘¯¢ýýý---*ÜÐÐ :¨ ÖÖÖ~ùòE‡ÅÛ®­Á¼iÏç3zá“1¹ÒÒR¶2ƒ0JJJ09Là:;;›šš¢f‰^ý¬§§g~~~kkëÇ­­­———’.‰aI«««U  Ùíö½½=ó®mZÓÜÜ<==ýôLŽÑ¸709€xHOO÷ûý‘éâX………Æ”ŒŒ ‡ÃQ^^ÞÛÛ»½½mô¶ •°Ø¡ ¯®®º\®kk¸¶ico­“Làÿc±XŒc ggg˜­¯¯;ÒÝÙÙQPm6›N<99Q[__WÑÁÁÁÆÆÆkk#²iíˆEEEŒÖ¿›ÍÍÍööö”””ĺ’±º½»»[QQq«ªªªªôD2÷&ð¨ñx<ýýý¡PèèèHÄKÆB•þæÍ½¾MQ\\ÜÕÕ%ž'ççç«ul‡#H¢ßïïîîniiY[[SÏ[kkk§§§%½¯¯Ï¤†0"›¾úù®CMMÍÓÕáhít:ï' âp‘Ý^YYIOO÷ù|·ªjjj*--MÿA½€É<ê™ ‘9‹Å’œœl\î–½¿¿6·!îeµZ333etQSw‚8YRR’Ëå–h}}½ž–óz½­­­'''&5„ÙôÌÌŒ~•O¿‹Éý&ijÑä"»-w‘Xiä_7add$55õa·Áä09ÀäâúÝ—€&ÙmùCÂívÇ][NNNmm-÷&€ÉÝw·777%<00wmýýýRƒÉ«9˜&˜Üã5¹•••—/_Úíö7oÞè¬ýýýššI´Z­n·{~~^iSGG‡Óé<88"¥¥¥æõ¯®®fddØl¶žž£2Ž©ôŠŠ õ„]Õœ’’rzzÚÖÖ&í¾xñ¸í„sss%]?‚WéVÝ‹¿ß/5tuuqo`r‰gr¢2UUU~÷îÊm²X,¢Y_¿~•ô´´´+ÃÛsssR*33Ó¼~QÀ­­- |ÿþ]»—R1‘<•˜““sexýbttTdnaaAg]ý|ýYÎëõ^^^ŽŒŒM®°°PÂçççq_„ããc©¡  à¡~ ÿðÿ ¾ýœ7+[\\ä·`r€ÉÅcr*¼½½-ᬬ,mrZÔ$]YF¹á+Rª­­-,±¸¸8l£ª«hï1HØjµªpSS“~*Òi&˜|Ý”SSçerR_¾|©¯¯×Åâñ]¨¨}ΫÙÝÝ•‚RÕ¼ú€Éý>ä'+Z?::GY¹KÙw“L œÂÂB㳤«Ÿë~ŠŠŠÔúñ«Ÿé¥åµµµ±6ÿÿû—þVBCCƒqÚ)ìÙb___oo¯š?»–ššã(('r£PüFw[°Ùl*000ðéÓ§¦¦&•;;;«ºjr¦Æ¡×årE>Ï29©ÎÎΩ©)ãBÅêÃû÷†&&&òòò¾ÿÎhlllˆÉOíV¥ä/“ôôtãíÉar€ÉüÍTòóó?þlTùùy#‘¤‚‚‚ÖÖVýÐÐn·Çúv†È„q¶`ÿåË—W?§úÂYêù0Eiié Ç'ÌŒ“[âaâjÚ`DԀΠƒú+eee¢hÆ#ÕÚ²XgjD55¥[Œu¦FäãDÝÂÂÂÙÙ™ÉI·µµ‰À EFã»PQû /«ñéí] W%%%üµ[&ÇØ˜<"“ëîî…BKKKúc ÅÅÅ]]]â ’.""¤±ÕÖÖŠˆøý~5‡dD”B} Udtt4;;[/êr8@@ª’‚ÒVKK‹–~ŒøæÍ›X ï¢N‰iIUïß¿­=êééÑÝVUíïï‹qêï·‰H×$IW¥¸Ò©XgjÄãñHUrÀÑÑ‘4ª¾þorRR¿ÏçëììÓŠãBE태—89k9_QÛÈE~¿2\Ä“cìL‘É©Çsssõ Ðîî®8ÕjÍÌÌ”_Ù":*ÝëõVTTˆ?‰…„Õ#e«««m6[RR’`\&†$‰.—kxxX©Œq¶ITƸ†Ìœ™™™ääd1N ¨¹(©J/’nçååI·¥ósssºTØkrŒœˆÚÝ+Ö™Ó‘’K$Mk59©ÒÒR©_õ02ß…ŠÚ9/u;;;r MMM‘‹üâC´þ-@läÁä09L09Àä“L09€øy<ýÀä“Àä09L09Àä“€;àì쬫«+55Õf³•——ßü#‹ÅÅÅgµÅÛŸÜ–gûBLà±344TYYùëõÔÖÖJUêÛÎ[[[Æýå?l l ‚É$ûûû¹¹¹_¿~½óš­Vk™\iié“ßÜ¢©©INSþeŸòÌ7êÅäî€ÃÃÃÖÖÖääd›ÍöêÕ+IÙÞÞ–°ØÒÅÅECCCjjª6³×¯_«#õ®hB(z÷î–‘‘±¼¼œ””tyy999)5èYó4±š6rvv&‚˜p&Çh ܘÀ³²²’ýáÃ1'2 «ô­­­ªª*¿ßŠ‹‹%euuÕív‹Ÿ‰¥‰üÙívuäééiyyyOOÏÑÑQ0”RÍÍÍ*kxxX©¡"V aD6†T+f´L“xÖˆ{¹\®ÍÍÍȬ¾¾¾ÞÞÞ?~¨èññqQQ‘¯¢ýýý---*ÜÐÐ :¨ ÖÖÖ~ùòE‡ÅÛ®­Á¼é0666¼^/£õsFîØööö”””°ôÝÝÝŠŠŠ[U%3ìííqo`r IgggSSSÔ¬ÒÒR£ŸõôôÌÏÏomm}øð¡   µµU½| ‰aI«««U  Ùív=LƪáÚ¦|ÿþ]Äñüü“{ΈÃÙ+äžIOO÷ù|·ªjjj*--m}}{“H“ˆlZ"*¼¼¼\ZZŠÉý"{{{êå=—ý&·¹¹)a¹Iâ®MþH &SŘ&ð‘!PdÎb±$''—»egg‡m¢°»»+îeµZ333eÔQSw‚VRR’Ëå–h}}½ž–óz½­­­'''&5„Ùt]]]ØgTEæ0¹_$77W_O§Ó©ÇÆÆ222l6›üàôOauuU%öôô(yŠZ6‘Åcµ%wcGG‡8âééi[[›Ýnñâ…qó KÓ’>33c4¹ÎÎN ÏÏÏÇ}5äï ©AþÒx¨{Cþ8yæ»\,..br€ÉÝfÚãÏ(•‰x}ÿþ]999*Ýívomm]ý|ÝDùÂA,¢Ú–H¡ªvttTdnaaÁØq8ùóàòòrddÄØÂÂB ÿÊ{0ÇÇÇRCAAÁCݶW/&˜ÜíL®¸¸8lpUé‹¥­­Í¼¬ Q‹Gm+ò= ëÍ<šššôЋ‹ ã‘bx¿ø¨W5ë‡÷po<ç99L0¹;09µ!GäaYYY’žm|qøæ&µx¬¶"MNG“““ceݼ3æWãA¶€cœº˜`r¿dr‹E¢êI¨‘ÓÓÓææfu°~'ææòµx¬¶LLN …B‘YjNNgÅ}5pN“Ãä“û%“óx<­ªªº¸¸ØÛÛ Ûñvyy¹®®N»Îm§ÁŠÇjËÄäÔkêeµºNÛ›Z' ã¾ggg»N“Ãä“»‡CMŒItrrR¯Z³Z­z/5‰îìì\ýüøHfffÔ²æ¾Y]â—ÆBÌ£ªf©!êĘ&ðD‡û•Ïèÿ&ËËËcEE¼îªÏrúyyyŒÖÑÁ_ù^´Çãñz½è1˜&O¡¡¡ÊÊÊÛfýJµæŒ=ȧSÍùøñc¬¨ôÙøÅã_ajj*7GGGiii£££q”œœdßULàŽÙßßÏÍÍýúõë­²~¥Úk©¯¯_XXxlª¶¶vmmÍ$uw×{>}Fë{`ccC„lbbâV¥|>_zzúÊÊÊÃz &‡É@077çr¹ÔÇŒ/è‰]½~ý:99Ùf³©YŸÉÉIµÀ+ò Á¨Y‘5DmΤÚX J%)))2ÔÉ¿Æ=,--J…Gí º½½-ã% _½ze·Û¥“3äðð°µµU#5¨Di÷Ý»w2Ngdd,//'%%©•p’ž––¦ËFFNçúúzqq±Ô–m°cÕ«R•iiiÑðæÛC=íÑÚ›{îÉÁÁAMMÍ­ŠTVVÞÉ2JL“€§˜ÁêêêÕÏ•øZ¤$Åív‹c‰Fˆ@èÏ4 k‡#,+V Q›3©6ŒÓÓÓ²²²®®®“““££#‘!ãB¢?Š©ì>ŸOrUºÈ\cc£/¤´>==]]]mÞO#bZRí‡...D›$¬zR^^ÞÓÓ#ÕŠ VUU577«ã¿|ùR__¯‹‡EÅ5333ÛÚÚÄ ¥¶‘‘U¡yQû W'²»»+¥ª[½úÀh ܘ$<………Æw÷®~®Ç/**™PÑþþ~ýé‡ÚÚZ‘ž¨õ³LjˆlμÚ0jjjŒ«ŽDãDnTxkkKüF7ªfeT```àÓ§OMMM*wvvVíÔdÒOäº\®È÷ŒsiƦSSS:+,*¢¶O”þˆ¬:cõáýû÷CCCyyyß¿o¬*))ùàÏÈ]Éarˆ%äççþüÙ¨óóó"F"I­­­ú¡¡ÝnúÐ',+V Q›3©6 ŸÏgœÜWÓ#¢tn0t8*\VV&Šf¨óÊÊʲX,ñmÓÎ.é`&‡É@bpzzZTT¤?|•‘‘!T^^ÞÛÛ«¶W¬®®ªÕf‘„eŪ!js&Õ†QZZj¬­££CÓUûúÿÄÄDCCƒDÎÄuÆÆÆTºDÕÚ²kû©HOO÷ûýa‰âXê›a ‹l©°Xš~Z‘õx<ƪú~b^gÔ>ȉ¤¤¤ˆ¼Š) Þœ¥¥¥·±‘;“ÃäàQ#¿ªÔ,T0]P‰â=ÆcvvvÔ3¾ÁÁÁÆÆÆ¨õ„eŪ!js&Õ†a\«þéÓ§úúúÖÖV¶ÄMüF½.:;;›ŸŸ¯Ó§¦¦ôÄ^¬~‘cŒu gggÆžœœœˆ ®¯¯«èøøx[[›ÜÐÐPdtzzZ¬Ñ¨k/_¾µ ;»°:£öAÎKˆ«ñé-`rðŒL®»»; ÉßYYY*±¸¸¸««K\AÒEDDƒÔK µµµ""~¿_Í! ËŠUCÔæLªœÓ’âïß¿ÿ=êééÑÝV‹íö÷÷E õ÷ÛD¤Œß€û‘âJ§bõÓˆÇ㑪䀣£#iTí¶îp8€$J·åŒZZZÄÕ³Q©ßçóuvvŠiEª=:ÅÕFGG³³³õê7“:£öAÎK œœµœ¯¨mä"?Àäà‰›œ`±Xrssõ Ðîî®8ÕjÍÌÌ|ûö­ˆŽJ÷z½âOb!aõ„eŪ!js&Õ†133“œœ, («ŸsQåååz4š——'JÓsssºTØkrŒ´¨v÷ŠÕO#bZ"RÒgiZ¯cíKJJr¹\ÃÃÃÊÏôZii©Ô¯z•cª««m6›—S6.˜3©3jä¼ÔYìììÈ)455E.òL“Ãäööv19µ’“xÖ×××ÛíöÌÌÌøv¥ƒ{F}QOþÅänÇãÙd ž9CCC•••wRUuuµzgerr2##ƒkûøùÇüG19ù“H<ö÷÷sssï|þLd.))‰ËûøaÀoçðð°µµ599Ùf³©­{···%lµZ/..ô÷¢ÅÌ^¿~­Ž4î¥!jõîÝ;9,##cyyY4ëòòrrrRjÐ[˜× ‰Õ´‘?ŽŒŒðƒ{ü,..ŠÆÉ¿˜Àoaee%;;ûÇbN"dz/­­­ªª*¿ßŠ‹‹¯~î#âv»ÅÏÄÒDþôG¤OOOËËË{zzŽŽŽ‚Á ”jnnVYÃÃÃJ ±j#²iÅùùùçÏŸ;;;õ÷h Áäîq/—Ë¥¿«l¤¯¯¯··Wäùøø¸¨¨HS°¿¿_B¹¡¡AtP¬­­Õ›|HX}hÚ¼ó¦ÿÏ~’••%FÈÏ“xîtvv655EÍ*--5úYOOÏüüüÖÖÖ‡ Z[[Õ'”%1ì!iuuµ „B!»Ý®?:«†k›ÖH…ëë냃ƒ999üì09€çNzzºßïLÇ*,,4¦ddd8ŽòòòÞÞÞíím£·mll訄ÅUxuuÕår][õMGÂë˜\Y,ãÄØÂ‚Úlmvv¶¾¾>ìHctggG=B5~׿ääDï& 666^[C‘M‡!­TTTð³Ãäž;G}¡íèèHÄK‹ÿÍ›7z}›¢¸¸¸««K+’Ä­­­ÂÂÂìììP(¤,**RÒµˆ~YattTdnaaAg]Ýf¦Íx¤ü *ÂÔ××wqq!N)é_¾|1ÏRóa‚tòòò²ººZÂïÞ½3otggGú/bzrr"Q)èr¹ô{¦MJJRç.¢f±X$,V'5§¥¥z²r%%z~~÷OóøøXjˆ|7“Àä๛\qqqØŽì*]©Xgg§Šnll|øðÁ¤HäË Ùú“SÊ®DÔ$,6ižÖµµ5 gee]Ûnww·Ùßß/á`0hù‰z éóù^½z¥“ËÌÌÔ]•c" ;Y»Ýþ‹Ï‹UýRÏÍÊbŸýë_åߨ’käÿ÷c©öÃæÊE÷œû_ÿõ_ÿöoÿö?ÿó?0÷¿ÿû¿cý%ö›rå/ÆÈW <÷¹›œùÕùÏÿüOÉ\Œò»s@ä#ðG’+=š;77÷›rÿã?þ£´´T~Ñ$P®ü"ÜXÏ~_îÈȈËå {æx[“ÙŠåêù©ÿêëëõü\¬"‘&KnnhrF’nÕÐ$ËXƒr eÂÞÞžh™\O wuuI5553^d©sll,///Ö š\‡øÿþŽv&?åù—‘¬¡¡¡¨µ=ÎÜþç–Üý×½çÜú§z„¹---‘‹ÜÉš+ʳÊ}î&÷Ü~Þæ¹ü.xü¿ÍÍsMƧ››œè‹D·¶¶"|÷îd‰ÄÈÐküZ¬"wnr⑾¸¸ÐY‡ãÚ¬Ènè,sêêêä`ùKC,mww·µµU¢KKKÉÉÉz:gmmMl/??uuõ†&§¤Óøœ:>“»ÕœÜÀÀ€ôSþ‰ZÛïË5ùëâÑæþî¿ÄëïÒß÷WºyîãœÑx¨ùæä⟓{¨Üß73lžû8gÑê™Âc~Â+×ä™ÑÍMÎãñH´ªªJ¬hoo/555lšJ~éë÷ܹ̋ɕ••)µ’°´%áúúúk³T ʜ俀êêMšVKß^¾|)§,Qù%«,P×,ˆHâÑÑ‘É F]' ãþÅuvvÆ:9Àäž&c¼¨‰šQS Ë&''õr7«ÕÚÒÒb<¸²²RÒ¿}ûfLŒZD­Ê$ k4a¥”Z‰ÁˆË¾ÿ^ÚÚØØ0ZWÔ,ýâ…È\cc£„———oxÝ”¤Ž«¨ZhœTl"yªê☟l仫a[{™GÕ´ÔÐÑÑÉ&ðÜMnzz:)))??_oè944¤Þܬ«« ›:òûýj­X‘EÂ^€‹F6ýwSÄ‹bQYYY"jâXê›&šXYªøðð°tÏårÍÌÌÜüº‰«éIPé¶Ô¯Ÿá "ˆR­ÛíV¯÷JýÒ´ùɪ¹=£†míeUW[jØÜÜÄä“xî&÷ôÁ=¾o ‹ïª'¶ñ!ªêõzù)&€ÉarÀÑÑQZZÚèèhe'''Ùw09LîYpzzj\²öxØØØ!›˜˜¸U)ŸÏ—žž¾²²ÂO09LîQ`‹ÍÝV~ŸíÞ„ƒƒƒ¨‹M¨¬¬4YYˆÉ`rÏ‹¿þõ¯×~ “~Ê€É=ÞßzæM`Œ~Ê€É=FÖ××M>å Àü”“Æxà§ ˜0Æ?eÀäžç_RRò<]äç‹É`rðdMž˜&O¥¥¥·ð<ÛŽ09Àä“»Øã0¹D…=“KTØã09Àä“Àä“L09L.1aÀäöxL.QaÀä“L“L09Àä0¹Ä„=“KTØã0¹D…=“L09L09Àäà“[\\ü 6KKKüçx¤&§>œ ‹·oßòŸàQ›\iié[€?SRR‚É$€É1Z÷&˜`r‰ÉîînEEÅ­ŠTUUíííar€É=$+++ééé>ŸïV¥¦¦¦ÒÒÒÖ××19Àä†ýý}§Ó999GÙ‘‘‘ÔÔÔÃÃCL0¹ÀëõºÝçääÔÖÖbr€ÉÝ7›››r⮡¿¿_jØÞÞÆä QMÎï÷ëoÒ666£¯_¿–êëëUôßÿýß;::œNçÁÁÁË—/KKK¯~>⬩©±ÛíV«ÕívÏÏÏ+ÍêììLMMýþý»Çã‘Üææfm`±²ccc6›­¢¢B*WE"Û•J¤Kª¹_9ñ®®.LÕä„ñ$‘§““‰^^^º\.ýB¨D“’’DªRRR”ÒÍÍ͉effJnnn®Åb‘ܯ_¿JVZZš$ê#gff¤xuuµ„ß½{gž%H¢DWWWÅó$““c,bl·°°PRÎÏÏã>ëããc©¡  “€69¡»»[zÕßß/á`0hù‰zòèóù^½zõ·Sú‰ñE19¥V*WJI  ©#UúÚÚš„³²²Ì³„âââ°­«bµk·Ûun|¨žH=˜$¶Éíí퉄¹\. wuu‰âÔÔÔHT4nvvÖhT‘J466–——é^Fg²Z­×fI ªŸE¶µ'·þ š~<&×ÔÔôdzgqq‘ß €ÉÝ‚ºº:õSœlww·µµU¢KKKÉÉÉ———±üimmMü/??uu5–É©¨Ãá¸6KlR¢[[[ךœš“üE“{„sr¥¥¥yöÈ¥à7`r·@-tÓ¯loo+Ǫ¯¯71*Ñ8I9:: ËUaeZ;;;®ªªº6Ëãñ¨èÅÅÅÞÞ^jjj¬vÕ:¹`0÷ùž=ÎurÏ|N“L.N”H«¨Zµ¦wPP¯DíS"(|ûöM»×èè¨[cc£„———Z5krrRÏÊX­Ö–––XíF¾»*ngÔ2ó¨¤†ŽŽŽÇfrÏ|œº˜`r·fllLÌL¿:==-:uqqa40ã ‚™Ífs»Ý[[[bK.—kiiI<<<,¹’833ó×%v–044¤^¤­««SSnQÛUS†Æ}ºŠŠŠ¤7Œª†¤†ÍÍML“x &w—'û„;yYáêçÂ>õ 8><×ë}„ƒÉar€É=}“;::JKK£ìää$û®br˜\NOO•®ß<+666DÈ&&&nUÊçó¥§§¯¬¬È‡Éñ£É&˜&€É`r˜&˜&€É`r˜ÜcÃápÈppÀ¥Àä0¹_åøø¸¾¾Þn·gff~ýúõw7'çv»¹Ï09€gmrCCC•••¿^Ouuu(šœœÌÈÈøÝÝëêêâ>Ã䞯ÉíïïçææÞíšÈ\RRÒïîy}}ýÂÂ÷&ð¤LnnnÎårY,µ§QÚ^¿~œœl³Ùº»»%errÒjµê?MÊj¶··¥¸”º¸¸hhhHMM<æãÇ###±$ïÝ»wR*##cyyY„ïòòò&í*å°”””••ùWjÓYKKK………Ò1ÇóãÇÝU9^ÂÁ`ðÕ«Wv»]j0¹ €É<°É‰š¬®®J`~~^[‘¤¸ÝnQ71§ÃÃCq•><<,Šc^6Œ­­­ªª*¿ßŠ‹‹uúùùùçÏŸ;;;gff¢<==-//ïéé9::µ’Jš››oØ®”-++ëêê:99‘âÒ®×ë5ºcvvö·oß$ìóùt¯DæåøÊÊJ©zzºººÚü‚&ð&WXX¨œFs||\TT$B£¢ýýý---*\[[+6cR6’¾¾¾ÞÞ^5ïõ§þIVV–r²HVVVtTšþòåË Û­©©ÕQѸ>h³Óg'Øl6øôéSSS“Êmkk3¿ €É<¤É‰ äççþüY§ôôôÌÏÏ‹ñˆý´¶¶ªgš¡PÈn·ïíí™”¤´´Ô(d©m}}}pp0'''2W:öSO]Û®Ï端¯7Š©¸Ú÷ïßUTD-èÜ`0èp8T¸¬¬LÍx¤ZZë‚<ÿx®”””ˆÉÉ¿@l–––ø ðdMîêç³È¢¢" ÍÈȹ)//ïííÝÞÞÖ‡­®®ªed&eÃã),,4o=êëâm:*áÎÎζ+îhìvGGGff¦Ž†­Õ›˜˜hhhP]µX,cccºçN§S-­‹uAÕ¼@,Þ¾}ËoX€§irò[^M/ƒÁôôt•(Bc33fr@ÀãñX­ÖœœœÙÙYíd"‹§§§mmmRðÅ‹Æ]¢ö³³³SjžŸŸûšøý~©¡«« “Àäûh&UJ³ÄÛ¾ÿ.½E›ÛíÞÚÚ’€JZÖ„Q1¯×{yy922b,¸¾¾.×××wqqQ^^.éê{Îb‡ê°ÑÑQ‘¹……cbõ³°°P¢çççq_ããc©¡  €{“H0“+..ÛBJ¥[,–¶¶6ó²&455éG–blÆ‚¢wVß>‡“pQQÑU´#$,ÎgÞOñÅ_|n«Ú Ûbä~î ¹Jl>»¸¸Èï Àä“‹ÓäD•¢šPVV–¤ggg‹Ï©MØnerÉÉÉaNÕ½¤f£®EšœŽÆêç¬À3öá>ïÒÒR6Ÿ•KÁï Àä“‹Óä,‹DÕƒT#§§§ÍÍÍêàöööÛj“ª6 E´Ùl¾¸¸ÐY‡ãZ“‹ÕOå…º¡¸¯ sr÷&˜`r¿jrG¢UUU¢V{{{©©©Æƒ———ëêê´åÜÜäÔëRüêï+í´o•••IXmȦ¼Ö××_kr±ú©ÖɃÁ¸/ÈÙÙëäð?&˜`r·Àáp¨É-µ:mrrR?ç²Z­---Ú¢ÔÞ»¢M™™™QËš0>>®ôèèèH-†”~}ýúUeŸŸ¿ÿ^ÝØØ¸úû›‚"£±úùQËÌ£W?_¤•:::¸709Àäûh===”””ŸŸ¯·r:6›­®®NOnIÏåHq8—ËõíÛ·XeMjÅüÔvXR{{»26Áçóeee‰y<ý‘°·"_nˆÚÏíím9À¸O—X¦èÚ £ªZ©ass“{“L€Ñú¾±+--»¸Ø¤×ëåÞÀä“`´~ŽŽŽÒÒÒFGGã(;99ɾ«˜`rŒÖÉÆÆ†ÙÄÄÄ­Jù|¾ôôô••î L09€ç5ZÛbó ý988¨©©¹U‘ÊÊÊ›,øãÞÀä“L€{“Lm *))aG&Cî L“L` ˆ&‡É&—¥¥¥·±ÑßÒÃä09L“Àä“L09L“Àä“L09¸‡Cþƒƒ.&€Éüggg]]]©©©6›­¼¼|ÿw·(çv»¹ò˜&Ïš¡¡¡ÊÊÊ_¬¤¶¶Vê¹¼¼”ðÖÖV~~þïîöØØ˜¸#?>L“ƒçËþþ~nnîׯ_ï¶Z«Õú»{^__¿°°ÀO“ÀäàI177çr¹,‹ÚÍÓ(m¯_¿NNN¶ÙlÝÝÝ’299)Ê¥÷ý4)«ÙÞÞ–âRêâ⢡¡!555ò˜³³3±Ã¨} …BïÞ½“RËËËIIIjïÚvƒƒƒrXJJÊÊÊŠü+µé¬¥¥¥ÂÂBé˜Çãùñã‡îª/á`0øêÕ+»Ý.5˜\Àä“x`DMVWW%0??¯­HRÜn·¨›˜Óáá¡8JÅ1/ÆÖÖVUU•ßïÅÅÅ‘H>|ˆL?==-//ïéé9::µ’Jš››oØ®”-++ëêê:99‘âÒ®×ëÕ¹?~ÌÎÎþö후}>Ÿî•È\cc£_YY)õOOOWWW›_Àä“xH •ÓhŽ‹ŠŠDhT´¿¿¿¥¥E…kkkÅfLÊFÒ×××ÛÛ«æ½"ÙØØ0:–‘†††•••¦¿|ùrÃvkjjFGGuTšÐ²(f)§ÏN°Ùl*000ðéÓ§¦¦&•;;;ÛÖÖf~A–ÅÅÅ?ž+%%%brò¥%~Å`rðÄAÉÏÏÿüù³Néé陟Ÿãû)((hmmUÏ4C¡ÝnßÛÛ3)Iii©QÈŒ|ÿþ]tíüü<2K:öSO]Û®Ï端¯7Š©¸š´¥¢"j@@çƒA‡Ã¡Âeee¢hÆ#ÕÒºXä‘ÌKÄâíÛ·üŠÀäàészzZTT$¤¢"7ååå½½½ÛÛÛú°ÕÕUµŒÌ¤lb<………Q³ÖÖÖÚÚÚb)‘x󮮠qꮳ³ó†íŠ;»ÝÑÑ‘™™©£akõ&&&Ä&UW-ËØØ˜î¹ÓéTKëb]Gbrr¾oþŒš³Ää09xê7è_þ¢\* ¦§§«Dã1;;;ê±æàà`cc£yÙ0fggÓcÆ)7ó1F?ñNNNÄ¢Ö××oØ®±ì§OŸ¤­­­:%l‰›Ûí§T]5~ ejjJ÷<Öy$&Çh ܘ<_“ëîî…BKKKYYY*±¸¸¸««ëììLÒÇÇÇÅoÔ*·ÚÚÚééi¿ßß×׫loÞ¼1®«S Hµ*¼¼¼\ZZYÐáp©\š“VZZZÄ·ÔóÖkÛ½Ó’Þ¿/ö)744ÔÓÓ£ÏNui_Ä´¿¿_¥·µµMLLèJDã¤xoo¯Éa´L“x`“,Knn®žôÚÝÝY±Z­™™™2ˆÁ¨t¯×[QQ!btrr«lÙÙÙaû7ÔÕÕ…-噋,(”””är¹†‡‡•Wéi¹kÛ™™INNÉ“ÀÕÏ7'¤¬^Þ'g———'g'ç877gìªñ59FÎWíîë‚0ZG²¹¹ÙÞÞž’’ò”š“@îü[©ªª2®(åÞÀä`´v:æù»[Äá~ws+++ééé±V‚Æbjj*---Ö_8˜&ðGëP(tŸ&÷»›Ûßß7\!pFFFRSS¹709€„­ïÓä~ws^¯×ívÇ]<''§¶¶–{“ÀäÍÍM©y`` îúûû¥†ùr &€É&¿Z­¬¬¼|ùÒn·¿yóFgíïï×ÔÔH¢Õju»ÝóóóJ˜:::œNçÁÁ‰ú.sKKK¹¹¹RÏÌÌL˜ÉÇ#õçääÌÎÎj'“&RRRNOOÛÚÚ¤à‹/ŒûŒeddØl¶ŠŠ ýŽNgg§Ô¬:~¿_jèêêâÞÀäÉäDb...ªªª$üîÝ;•%úe±XD•¾~ý*éiiiW†·æææ¤”ñ3ÎQÙÙÙóz½———###F“[__‡ëë듦ËËË%]}ùO¿‡1::*2·°° aQ=UJéàêêê÷ïßé………ºÉ 9>>– ¸709€D29ÞÞÞ–°þ쟘œ5õ)c‘¾ÐÔÔ¤Yб›½“°úJŽ8œ„‹ŠŠ®¢½!aq>...û2ŽJ_üÅ綪ݰQßç½!׊Ígù]˜`rñ˜\˜3)¹ËËË3v«µnÉÉÉaõGu¯ËËKcÓ‘½ÒQ9&jëw²/ìôïùÞ(--eóY¹ü®L0¹xLNMJ9][[s¹\ùùù«««q›œÅb‘ƒÕ–¸aem6›„/..t–nÚÄäT…[[[a )/Ô Å}5˜“{(09Àä“û%“[__—pKK‹ŠŠÆITí¥·Éåææê­AÔÊ6í[eeej½ÝÕß¼êÍsMLÎãñH¸ªªJŠìíí¥¦¦ªtµN. Æ})ÎÎÎX'÷àÿA09Àä“»bBÒ«™™õÆCzzº^§f¹¶··Õ·oßÔk77¹ññq¥Gb„j1œ ôKU+Yçççïß¿·Z­Wó@@dtrrR?‰“"Ú;#ß]·3j™yôêç‹´RCGG÷&˜@bŒÖ{{{6›M¼M¬ÈøÃè訤»Ýî­­-ñ—˵´´¤-J¿q-CCC‡Cm‡åt:ÛÛÛ•± >ŸOê!óx<ú;#ao3D¾Ü J=Ò·ºº:= §^×0îÓUTT$ݾaTU+5lnnro`r€É0Zß7"v7ù¾],Ä&½^/÷&˜£õptt”––6::GÙÉÉIö]Åä“`´~H666DÈ&&&nUÊçó¥§§¯¬¬po`r€É<¯ÑÚ›éÏÁÁAMMÍ­ŠTVVîííqo`r€É0Z÷&˜<Ѫ¤¤„™ ¹+09L09H€ ˜&˜<^–––ÞÄFQ“Àä09Àä“L09Àä09L“L‡Ã!pppÀ¥Àä“€_Åï÷Ûív›ïg[zq8·ÛÍeÇä“xÖ UVVÞIU[[[ç~º=66ÖÕÕÅ“Làù²¿¿Ÿ››ûõë×;©mpp°··÷~z^__¿°°ÀO“LàI177çr¹,‹ÚÊ(m¯_¿NNN¶ÙlÝÝÝ’299iµZõæQ&e5ÛÛÛR\J]\\444¤¦¦sËÊÊ–——Mú …Þ½{'¥222äȤ¤¤ËËË›´«MQKIIYYY‘¥6µ´´TXX(óxŸO÷Jd®±±Qޝ¬¬”ú§§§«««Í/`r€É<$………Êi4ÇÇÇEEE"4*ÚßßßÒҢµµµb3&e#éëëëííUó^FD¡ŒRICCÃÊÊŠŽJÓ_¾|¹a»555£££:*÷áÃm–¢qúì›Í¦Ÿ>}jjjR¹³³³mmmæ09Àä”üüüÏŸ?딞žžùùy1±Ÿ‚‚‚ÖÖVõL3 Ùíö½½=“²‘”––…LÓÜÜ<==«”t ì ¦ž»¶]qÄúúz£˜Š«}ÿþ]EEԀΠƒ‡C…ËÊÊDÑŒGª¥u±.Èý³¸¸øÇs¥¤¤DLNþýb³´´Äï4Lž§§§EEE"@*š‘‘!rS^^ÞÛÛ»½½­[]]UËÈLʆ!ÆSXX5+==]+V—ÄÛ666tTÂ7lWÜÑØíŽŽŽÌÌL [«711ÑÐРºj±XÆÆÆtÏN§ZZë‚<Ô¼@,Þ¾}Ë/4LžÓ/µ¿üEM/ƒAQ+•(Bc>– ¸709€69Q%‰ªïЍIXoéa’e‚Åbikk K,..ŽœŒ|AÂâŽ*ÜÔÔ¤€ŠJüõ¥~ªé°MD¸709€39£]^^]Ê$Ë„¬¬,92;;[|NíÕ&HÁ¨îir:šœœ+ëN–úÝðt09L0¹Çkr6›M¢:×áp\›eÂééiss³j¥½½]%Z,‰ª§®749UD-%rNî?¤Âœ&ð&WVV&QµšzˆY__mÖµ,//×ÕÕiUòxjܧ«¨¨Htí†QU³Ô°¹¹É½É0Zß7¢ƒ¥¥¥q1õz½Ü˜£õptt”––6::GÙÉÉIö]Åä­’ ²‰‰‰[•òù|ééé+++ܘÀs­m±¹çžÔÔÔܪHeeåÞÞ÷&Àh ܘ<ÝѺ¤¤ä€?#w&‡É@˜@,09L/KKKobsÃïóar€É&˜&˜@¢p~~þæÍ»Ý^WW—p¿¼¼ôûý79²  àÇü¸19€'Eeeåððp(ÊÈÈH¬žƒÁÑÑÑ<22òñãG~ܘÀÓazzúÿµwíýqÇ¿df&»I]$‘I™˜™9vÑÝt‘n2“LÆÑE’ŒÌLºØMÒÕt“$éf’d2’t‘D’™IÌd232I2ßßû÷=|Ìô[¿‹ïæù¸˜Ï¿ó9çô¹èå윳™™™N<òJ¥ %€¶8þùùÙï÷³â$9º„„›ÁÁÁ‡‡‡Ž;r pš¦e2™¶¶aÑIrtƒ©©)õ›Q¯¯¯Fãåå¥Ûí6™L‡£á®²&]ßÊf³f³YÆ~~þþ~£ýåå% Ùl6é ‡Ãj¼ƒ®ëF»ßï7,—˽v»ÝëõªÁÑh4 ¶þ, ëN’ K¤R©ééiUÝÙÙ‘Àt}}-åd2©iZ+]Md2ŸÏwvv–N§MnooÇÇÇ÷÷÷¿¾¾$º©huss#ó' ‰}¹¤,Ÿg{{ÛpttdµZr¡Pèé鹿¿oëdew²‹N’ K„Ãá­­-•º$?•J%Õk6›ìjncc#‰¨ x•JE™š'/,,HAZ†††6—cSw¶U«Uu.‹Éñ´{²ÇÇÇ* ‚$@Çs:ê&¹ùùùt:­ºÊårooï]Íy½Þ››U][[K¥R’ ‰„ËåÒuýëëKÚWVVdßf¯ÉÉI£¼´´”Íf²¦iRm÷de/’#Yt’Ý Z­öõõ©ªºÍ°··~ìjBRšÛí®o”(á,‰¨X&¾}'ÜÕÕ•±ë“““ååeÕn±X$äµ{¾£££±XŒu'ÉÐ ’Éäììl}<ªï¿»»û±« [õó‹†ÛÔžžž...Œvãâœáüüüýý] oooV«5—Ë9N£EÍS,Û:Ù‡‡“ÉT(Xw’Ý  ¨ª¦iûûû¿ÿ<[:77Ç[éjbqqÑØª~žÕÕUÉdµZmwwWò™q Ãá9¥±T*mnnªoN%ÞIhnx¸¡!YºÝn—ËÕ¼¬ëz4eÑIrt‰±±±UÍçó&“IÖééiýÈ&]MØívI~ óÈ 2„³X,¦.³=>>J˜“Ðf³ÙêßKòïñ_¿âàï?ß“ÖW=ú÷Ûr.—óz½­¿C$9þjÅb1 uèÁûý~ …­×u½R©°è$9ºD<¯æ ³ììì´þs«2¸\.³â$9:ÞÈÈH­V;<<\__ïܳÈçó-¾O$N×?K’ÌçóÙl¶ÿ+Æ™ÿjäHr É€$’I›ï ÁŠñ°¥IEND®B`‚ldb-2.0.8/lib/tevent/doc/mainpage.dox0000660000000000000000000000326112406075657017351 0ustar rootroot00000000000000/** * @mainpage * * Tevent is an event system based on the talloc memory management library. It * is the core event system used in Samba. * * The low level tevent has support for many event types, including timers, * signals, and the classic file descriptor events. * * Tevent also provide helpers to deal with asynchronous code providing the * tevent_req (tevent request) functions. * * @section main_tevent_tutorial Tutorial * * You should start by reading @subpage tevent_tutorial, then reading the * documentation of the interesting functions as you go. * * @section main_tevent_download Download * * You can download the latest releases of tevent from the * tevent directory * on the samba public source archive. * * @section main_tevent_bugs Discussion and bug reports * * tevent does not currently have its own mailing list or bug tracking system. * For now, please use the * samba-technical * mailing list, and the * Samba bugzilla * bug tracking system. * * @section main_tevent_devel Development * You can download the latest code either via git or rsync. * * To fetch via git see the following guide: * * Using Git for Samba Development * * Once you have cloned the tree switch to the master branch and cd into the * lib/tevent directory. * * To fetch via rsync use this command: * * rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tevent . * */ ldb-2.0.8/lib/tevent/doc/tevent_context.dox0000660000000000000000000000600312775624157020642 0ustar rootroot00000000000000/** @page tevent_context Chapter 1: Tevent context @section context Tevent context Tevent context is an essential logical unit of tevent library. For working with events at least one such context has to be created - allocated, initialized. Then, events which are meant to be caught and handled have to be registered within this specific context. Reason for subordinating events to a tevent context structure rises from the fact that several context can be created and each of them is processed at different time. So, there can be 1 context containing just file descriptor events, another one taking care of signal and time events and the third one which keeps information about the rest. Tevent loops are the part of the library which represents the mechanism where noticing events and triggering handlers actually happens. They accept just one argument - tevent context structure. Therefore if theoretically an infinity loop (tevent_loop_wait) was called, only those arguments which belong to the passed tevent context structure can be caught and invoked within this call. Although some more signal events were registered (but within some other context) they will not be noticed. @subsection Example First lines which handle mem_ctx belong to talloc library knowledge but because of the fact that tevent uses the talloc library for its mechanisms it is necessary to understand a bit talloc as well. For more information about working with talloc, please visit talloc website where tutorial and documentation are located. Tevent context structure *event_ctx represents the unit which will further contain information about registered events. It is created via calling tevent_context_init(). @code TALLOC_CTX *mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { // error handling } struct tevent_context *ev_ctx = tevent_context_init(mem_ctx); if(ev_ctx == NULL) { // error handling } @endcode Tevent context has a structure containing lots of information. It include lists of all events which are divided according their type and are in order showing the sequence as they came. @image html tevent_context_stucture.png In addition to the lists shown in the diagram, the tevent context also contains many other data (e.g. information about the available system mechanism for triggering callbacks). @section tevent_loops Tevent loops Tevent loops are the dispatcher for events. They catch them and trigger the handlers. In the case of longer processes, the program spends most of its time at this point waiting for events, invoking handlers and waiting for another event again. There are 2 types of loop available for use in tevent library:
  • int tevent_loop_wait()
  • int tevent_loop_once()
Both of functions accept just one parameter (tevent context) and the only difference lies in the fact that the first loop can theoretically last for ever but the second one will wait just for a single one event to catch and then the loop breaks and the program continue. */ ldb-2.0.8/lib/tevent/doc/tevent_data.dox0000660000000000000000000000707312461161556020066 0ustar rootroot00000000000000/** @page tevent_data Chapter 3: Accessing data @section data Accessing data with tevent A tevent request is (usually) created together with a structure for storing the data necessary for an asynchronous computation. For these private data, tevent library uses void (generic) pointers, therefore any data type can be very simply pointed at. However, this attitude requires clear and guaranteed knowledge of the data type that will be handled, in advance. Private data can be of 2 types: connected with a request itself or given as an individual argument to a callback. It is necessary to differentiate these types, because there is a slightly different method of data access for each. There are two possibilities how to access data that is given as an argument directly to a callback. The difference lies in the pointer that is returned. In one case it is the data type specified in the function’s argument, in another void* is returned. @code void tevent_req_callback_data (struct tevent_req *req, #type) void tevent_req_callback_data_void (struct tevent_req *req) @endcode To obtain data that are strictly bound to a request, this function is the only direct procedure. @code void *tevent_req_data (struct tevent_req *req, #type) @endcode Example with both calls which differs between private data within tevent request and data handed over as an argument. @code #include #include #include struct foo_state { int x; }; struct testA { int y; }; static void foo_done(struct tevent_req *req) { // a->x contains 10 since it came from foo_send struct foo_state *a = tevent_req_data(req, struct foo_state); // b->y contains 9 since it came from run struct testA *b = tevent_req_callback_data(req, struct testA); // c->y contains 9 since it came from run we just used a different way // of getting it. struct testA *c = (struct testA *)tevent_req_callback_data_void(req); printf("a->x: %d\n", a->x); printf("b->y: %d\n", b->y); printf("c->y: %d\n", c->y); } struct tevent_req * foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx) { printf("_send\n"); struct tevent_req *req; struct foo_state *state; req = tevent_req_create(event_ctx, &state, struct foo_state); state->x = 10; return req; } static void run(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { struct tevent_req *req; struct testA *tmp = talloc(ev, struct testA); // Note that we did not use the private data passed in tmp->y = 9; req = foo_send(ev, ev); tevent_req_set_callback(req, foo_done, tmp); tevent_req_done(req); } int main (int argc, char **argv) { struct tevent_context *event_ctx; struct testA *data; TALLOC_CTX *mem_ctx; struct tevent_timer *time_event; mem_ctx = talloc_new(NULL); //parent if (mem_ctx == NULL) return EXIT_FAILURE; event_ctx = tevent_context_init(mem_ctx); if (event_ctx == NULL) return EXIT_FAILURE; data = talloc(mem_ctx, struct testA); data->y = 11; time_event = tevent_add_timer(event_ctx, mem_ctx, tevent_timeval_current(), run, data); if (time_event == NULL) { fprintf(stderr, " FAILED\n"); return EXIT_FAILURE; } tevent_loop_once(event_ctx); talloc_free(mem_ctx); printf("Quit\n"); return EXIT_SUCCESS; } @endcode Output of this example is: @code a->x: 10 b->y: 9 c->y: 9 @endcode */ ldb-2.0.8/lib/tevent/doc/tevent_events.dox0000660000000000000000000002565012406075657020467 0ustar rootroot00000000000000/** @page tevent_events Chapter 2: Tevent events @section pools Tevent events Ok, after reading previous chapter we can start doing something useful. So, the way of creating events is similar for all types - signals, file descriptors, time or immediate events. At the beginning it is good to know about some typedefs which are set in tevent library and which specify the arguments for each callback. These callbacks are: - tevent_timer_handler_t() - tevent_immediate_handler_t() - tevent_signal_handler_t() - tevent_fd_handler_t() According their names it is obvious that for creating callback for e.g. time event, tevent_timer_handler_t will be used. The best way how to introduce registering an event and setting up a callback would be example, so examples describing all the types of events follow. @subsection Time Time event This example shows how to set up an event which will be repeated for a minute with interval of 2 seconds (will be triggered 30 times). After exceeding this limit, the event loop will finish and all the memory resources will be freed. This is just example describing repeated activity, nothing usefull is done within foo function @code #include #include #include #include struct state { struct timeval endtime; int counter; TALLOC_CTX *ctx; }; static void callback(struct tevent_context *ev, struct tevent_timer *tim, struct timeval current_time, void *private_data) { struct state *data = talloc_get_type_abort(private_data, struct state); struct tevent_timer *time_event; struct timeval schedule; printf("Data value: %d\n", data->counter); data->counter += 1; // increase counter // if time has not reached its limit, set another event if (tevent_timeval_compare(¤t_time, &(data->endtime)) < 0) { // do something // set repeat with delay 2 seconds schedule = tevent_timeval_current_ofs(2, 0); time_event = tevent_add_timer(ev, data->ctx, schedule, callback, data); if (time_event == NULL) { // error ... fprintf(stderr, "MEMORY PROBLEM\n"); return; } } else { // time limit exceeded } } int main(void) { struct tevent_context *event_ctx; TALLOC_CTX *mem_ctx; struct tevent_timer *time_event; struct timeval schedule; mem_ctx = talloc_new(NULL); // parent event_ctx = tevent_context_init(mem_ctx); struct state *data = talloc(mem_ctx, struct state); schedule = tevent_timeval_current_ofs(2, 0); // +2 second time value data->endtime = tevent_timeval_add(&schedule, 60, 0); // one minute time limit data->ctx = mem_ctx; data->counter = 0; // add time event time_event = tevent_add_timer(event_ctx, mem_ctx, schedule, callback, data); if (time_event == NULL) { fprintf(stderr, "FAILED\n"); return EXIT_FAILURE; } tevent_loop_wait(event_ctx); talloc_free(mem_ctx); return EXIT_SUCCESS; } @endcode Variable counter is only used for counting the number of triggered functions. List of all available functions which tevent offers for working with time are listed here together with their description. More detailed view at these functions is unnecessary because their purpose and usage is quite simple and clear. @subsection Immediate Immediate event These events are, as their name indicates, activated and performed immediately. It means that this kind of events have priority over others (except signal events). So if there is a bulk of events registered and after that a tevent loop is launched, then all the immediate events will be triggered before the other events. Except other immediate events (and signal events) because they are also processed sequentially - according the order they were scheduled. Signals have the highest priority and therefore they are processed preferentially. Therefore the expression immediate may not correspond exactly to the dictionary definition of "something without delay" but rather "as soon as possible" after all preceding immediate events. For creating an immediate event there is a small different which lies in the fact that the creation of such event is done in 2 steps. One represents the creation (memory allocation), the second one represents registering as the event within some tevent context. @code struct tevent_immediate *run(TALLOC_CTX* mem_ctx, struct tevent_context event_ctx, void * data) { struct tevent_immediate *im; im = tevent_create_immediate(mem_ctx); if (im == NULL) { return NULL; } tevent_schedule_immediate(im, event_ctx, foo, data); return im; } @endcode Example which may be compiled and run representing the creation of immediate event. @code #include #include #include struct info_struct { int counter; }; static void foo(struct tevent_context *ev, struct tevent_immediate *im, void *private_data) { struct info_struct *data = talloc_get_type_abort(private_data, struct info_struct); printf("Data value: %d\n", data->counter); } int main (void) { struct tevent_context *event_ctx; TALLOC_CTX *mem_ctx; struct tevent_immediate *im; printf("INIT\n"); mem_ctx = talloc_new(NULL); event_ctx = tevent_context_init(mem_ctx); struct info_struct *data = talloc(mem_ctx, struct info_struct); // setting up private data data->counter = 1; // first immediate event im = tevent_create_immediate(mem_ctx); if (im == NULL) { fprintf(stderr, "FAILED\n"); return EXIT_FAILURE; } tevent_schedule_immediate(im, event_ctx, foo, data); tevent_loop_wait(event_ctx); talloc_free(mem_ctx); return 0; } @endcode @subsection Signal Signal event This is an alternative to standard C library functions signal() or sigaction(). The main difference that distinguishes these ways of treating signals is their setting up of handlers for different time intervals of the running program. While standard C library methods for dealing with signals offer sufficient tools for most cases, they are inadequate for handling signals within the tevent loop. It could be necessary to finish certain tevent requests within the tevent loop without interruption. If a signal was sent to a program at a moment when the tevent loop is in progress, a standard signal handler would not return processing to the application at the very same place and it would quit the tevent loop for ever. In such cases, tevent signal handlers offer the possibility of dealing with these signals by masking them from the rest of application and not quitting the loop, so the other events can still be processed. Tevent offers also a control function, which enables us to verify whether it is possible to handle signals via tevent, is defined within tevent library and it returns a boolean value revealing the result of the verification. @code bool tevent_signal_support (struct tevent_context *ev) @endcode Checking for signal support is not necessary, but if it is not guaranteed, this is a good and easy control to prevent unexpected behaviour or failure of the program occurring. Such a test of course does not have to be run every single time you wish to create a signal handler, but simply at the beginning - during the initialization procedures of the program. Afterthat, simply adapt to each situation that arises. @code #include #include #include static void handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { // Do something usefull printf("handling signal...\n"); exit(EXIT_SUCCESS); } int main (void) { struct tevent_context *event_ctx; TALLOC_CTX *mem_ctx; struct tevent_signal *sig; mem_ctx = talloc_new(NULL); //parent if (mem_ctx == NULL) { fprintf(stderr, "FAILED\n"); return EXIT_FAILURE; } event_ctx = tevent_context_init(mem_ctx); if (event_ctx == NULL) { fprintf(stderr, "FAILED\n"); return EXIT_FAILURE; } if (tevent_signal_support(event_ctx)) { // create signal event sig = tevent_add_signal(event_ctx, mem_ctx, SIGINT, 0, handler, NULL); if (sig == NULL) { fprintf(stderr, "FAILED\n"); return EXIT_FAILURE; } tevent_loop_wait(event_ctx); } talloc_free(mem_ctx); return EXIT_SUCCESS; } @endcode @subsection File File descriptor event Support of events on file descriptors is mainly useful for socket communication but it certainly works flawlessly with standard streams (stdin, stdout, stderr) as well. Working asynchronously with file descriptors enables switching within processing I/O operations. This ability may rise with a greater number of I/O operations and such overlapping leads to enhancement of the throughput. There are several other functions included in tevent API related to handling file descriptors (there are too many functions defined within tevent therefore just some of them are fully described within this thesis. The declaration of the rest can be easily found on the library’s website or directly from the source code):
  • tevent_fd_set_close_fn() - can add another function to be called at the moment when a structure tevent fd is freed.
  • tevent_fd_set_auto_close() - calling this function can simplify the maintenance of file descriptors, because it instructs tevent to close the appropriate file descriptor when the tevent fd structure is about to be freed.
  • tevent_fd_get_flags() - returns flags which are set on the file descriptor connected with this tevent fd structure.
  • tevent_fd_set_flags() - sets specified flags on the event’s file descriptor.
@code static void close_fd(struct tevent_context *ev, struct tevent_fd *fd_event, int fd, void *private_data) { // processing when fd_event is freed } struct static void handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { // handling event; reading from a file descriptor tevent_fd_set_close_fn (fd_event, close_fd); } int run(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, int fd, uint16_t flags, char *buffer) { struct tevent_fd* fd_event = NULL; if (flags & TEVENT_FD_READ) { fd_event = tevent_add_fd(event_ctx, mem_ctx, fd, flags, handler, buffer); } if (fd_event == NULL) { // error handling } return tevent_loop_once(); } @endcode */ ldb-2.0.8/lib/tevent/doc/tevent_queue.dox0000660000000000000000000002277612775624157020321 0ustar rootroot00000000000000/** @page tevent_queue Chapter 5: Tevent queue @section queue Tevent queue There is a possibility that the dispatcher and its handlers may not be able to handle all the incoming events as quickly as they arrive. One way to deal with this situation is to buffer the received events by introducing an event queue into the events stream, between the events generator and the dispatcher. Events are added to the queue as they arrive, and the dispatcher pops them off the beginning of the queue as fast as possible. In tevent library it is similar, but the queue is not automatically set for any event. The queue has to be created on purpose, and events which should follow the order of the FIFO queue have to be explicitly pinpointed. Creating such a queue is crucial in situations when sequential processing is absolutely essential for the successful completion of a task, e.g. for a large quantity of data that are about to be written from a buffer into a socket. The tevent library has its own queue structure that is ready to use after it has been initialized and started up once. @subsection cr_queue Creation of Queues The first and most important step is the creation of the tevent queue (represented by struct tevent_queue), which will then be in running mode. @code struct tevent_queue* tevent_queue_create (TALLOC_CTX *mem_ctx, const char *name) @endcode When the program returns from this function, the allocated memory, set destructor and labeled queue as running has been done and the structure is ready to be filled with entries. Stopping and starting queues on the run. If you need to stop a queue from processing its entries, and then turn it on again, a couple of functions which serve this purpose are: - bool tevent_queue_stop() - bool tevent_queue_start() These functions actually only provide for the simple setting of a variable, which indicates that the queue has been stopped/started. Returned value indicates result. @subsection add_queue Adding Requests to a Queue Tevent in fact offers 3 possible ways of inserting a request into a queue. There are no vast differences between them, but still there might be situations where one of them is more suitable and desired than another. @code bool tevent_queue_add(struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data) @endcode This call is the simplest of all three. It offers only boolean verification of whether the operation of adding the request into a queue was successful or not. No additional deletion of an item from the queue is possible, i.e. it is only possible to deallocate the whole tevent request, which would cause triggering of destructor handling and also dropping the request from the queue. Extended Options Both of the following functions have a feature in common - they return tevent queue entry structure representing the item in a queue. There is no further possible handling with this structure except the use of the structure’s pointer for its deallocation (which leads also its removal from the queue). The difference lies in the possibility that with the following functions it is possible to remove the tevent request from a queue without its deallocation. The previous function can only deallocate the tevent request as it was from memory, and thereby logically cause its removal from the queue as well. There is no other utilization of this structure via API at this stage of tevent library. The possibility of easier debugging while developing with tevent could be considered to be an advantage of this returned pointer. @code struct tevent_queue_entry *tevent_queue_add_entry(struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data) @endcode The feature that allows for the optimized addition of entries to a queue is that a check for an empty queue with no items is first of all carried out. If it is found that the queue is empty, then the request for inserting the entry into a queue will be omitted and directly triggered. @code struct tevent_queue_entry *tevent_queue_add_optimize_empty(struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data) @endcode When calling any of the functions serving for inserting an item into a queue, it is possible to leave out the fourth argument (trigger) and instead of a function pass a NULL pointer. This usage sets so-called blocking entries. These entries, since they do not have any trigger operation to be activated, just sit in their position until they are labeled as a done by another function. Their purpose is to block other items in the queue from being triggered. @subsection example_q Example of tevent queue @code #include #include #include struct foo_state { int local_var; int x; }; struct juststruct { TALLOC_CTX * ctx; struct tevent_context *ev; int y; }; int created = 0; static void timer_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { // time event which after all sets request as done. Following item from // the queue may be invoked. struct tevent_req *req = private_data; struct foo_state *stateX = tevent_req_data(req, struct foo_state); // processing some stuff printf("time_handler\n"); tevent_req_done(req); talloc_free(req); printf("Request #%d set as done.\n", stateX->x); } static void trigger(struct tevent_req *req, void *private_data) { struct juststruct *priv = tevent_req_callback_data (req, struct juststruct); struct foo_state *in = tevent_req_data(req, struct foo_state); struct timeval schedule; struct tevent_timer *tim; schedule = tevent_timeval_current_ofs(1, 0); printf("Processing request #%d\n", in->x); if (in->x % 3 == 0) { // just example; third request does not contain // any further operation and will be finished right // away. tim = NULL; } else { tim = tevent_add_timer(priv->ev, req, schedule, timer_handler, req); } if (tim == NULL) { tevent_req_done(req); talloc_free(req); printf("Request #%d set as done.\n", in->x); } } struct tevent_req *foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *name, int num) { struct tevent_req *req; struct foo_state *state; struct foo_state *in; struct tevent_timer *tim; printf("foo_send\n"); req = tevent_req_create(mem_ctx, &state, struct foo_state); if (req == NULL) { // check for appropriate allocation tevent_req_error(req, 1); return NULL; } // exemplary filling of variables state->local_var = 1; state->x = num; return req; } static void foo_done(struct tevent_req *req) { enum tevent_req_state state; uint64_t err; if (tevent_req_is_error(req, &state, &err)) { printf("ERROR WAS SET %d\n", state); return; } else { // processing some stuff printf("Callback is done...\n"); } } int main (int argc, char **argv) { TALLOC_CTX *mem_ctx; struct tevent_req* req[6]; struct tevent_req* tmp; struct tevent_context *ev; struct tevent_queue *fronta = NULL; struct juststruct *data; int ret; int i = 0; const char * const names[] = { "first", "second", "third", "fourth", "fifth" }; printf("INIT\n"); mem_ctx = talloc_new(NULL); //parent talloc_parent(mem_ctx); ev = tevent_context_init(mem_ctx); if (ev == NULL) { fprintf(stderr, "MEMORY ERROR\n"); return EXIT_FAILURE; } // setting up queue fronta = tevent_queue_create(mem_ctx, "test_queue"); tevent_queue_stop(fronta); tevent_queue_start(fronta); if (tevent_queue_running(fronta)) { printf ("Queue is runnning (length: %d)\n", tevent_queue_length(fronta)); } else { printf ("Queue is not runnning\n"); } data = talloc(ev, struct juststruct); data->ctx = mem_ctx; data->ev = ev; // create 4 requests for (i = 1; i < 5; i++) { req[i] = foo_send(mem_ctx, ev, names[i], i); tmp = req[i]; if (req[i] == NULL) { fprintf(stderr, "Request error! %d \n", ret); break; } tevent_req_set_callback(req[i], foo_done, data); created++; } // add item to a queue tevent_queue_add(fronta, ev, req[1], trigger, data); tevent_queue_add(fronta, ev, req[2], trigger, data); tevent_queue_add(fronta, ev, req[3], trigger, data); tevent_queue_add(fronta, ev, req[4], trigger, data); printf("Queue length: %d\n", tevent_queue_length(fronta)); while(tevent_queue_length(fronta) > 0) { tevent_loop_once(ev); printf("Queue: %d items left\n", tevent_queue_length(fronta)); } talloc_free(mem_ctx); printf("FINISH\n"); return EXIT_SUCCESS; } @endcode */ ldb-2.0.8/lib/tevent/doc/tevent_request.dox0000660000000000000000000002107113573675413020646 0ustar rootroot00000000000000/** @page tevent_request Chapter 4: Tevent request @section request Tevent request A specific feature of the library is the tevent request API that provides for asynchronous computation and allows much more interconnected working and cooperation among functions and events. When working with tevent request it is possible to nest one event under another and handle them bit by bit. This enables the creation of sequences of steps, and provides an opportunity to prepare for all problems which may unexpectedly happen within the different phases. One way or another, subrequests split bigger tasks into smaller ones which allow a clearer view of each task as a whole. @subsection name Naming conventions There is a naming convention which is not obligatory but it is followed in this tutorial: - Functions triggered before the event happens. These establish a request. - \b foo_send(...) - this function is called first and it includes the creation of tevent request - tevent req structure. It does not block anything, it simply creates a request, sets a callback (foo done) and lets the program continue - Functions as a result of event. - \b foo_done(...) - this function contains code providing for handling itself and based upon its results, the request is set either as a done or, if an error occurs, the request is set as a failure. - \b foo_recv(...) - this function contains code which should, if demanded, access the result data and make them further visible. The foo state should be deallocated from memory when the request’s processing is over and therefore all computed data up to this point would be lost. As was already mentioned, specific naming subsumes not only functions but also the data themselves: - \b foo_state - this is a structure. It contains all the data necessary for the asynchronous task. @subsection cr_req Creating a New Asynchronous Request The first step for working asynchronously is the allocation of memory requirements. As in previous cases, the talloc context is required, upon which the asynchronous request will be tied. The next step is the creation of the request itself. @code struct tevent_req* tevent_req_create (TALLOC_CTX *mem_ctx, void **pstate, #type) @endcode The pstate is the pointer to the private data. The necessary amount of memory (based on data type) is allocated during this call. Within this same memory area all the data from the asynchronous request that need to be preserved for some time should be kept. Dealing with a lack of memory The verification of the returned pointer against NULL is necessary in order to identify a potential lack of memory. There is a special function which helps with this check tevent_req_nomem(). It handles verification both of the talloc memory allocation and of the associated tevent request, and is therefore a very useful function for avoiding unexpected situations. It can easily be used when checking the availability of further memory resources that are required for a tevent request. Imagine an example where additional memory needs arise although no memory resources are currently available. @code bar = talloc(mem_ctx, struct foo); if(tevent_req_nomem (bar, req)) { // handling a problem } @endcode This code ensures that the variable bar, which contains NULL as a result of the unsuccessful satisfaction of its memory requirements, is noticed, and also that the tevent request req declares it exceeds memory capacity, which implies the impossibility of finishing the request as originally programmed. @subsection fini_req Finishing a Request Marking each request as finished is an essential principle of the tevent library. Without marking the request as completed - either successfully or with an error - the tevent loop could not let the appropriate callback be triggered. It is important to understand that this would be a significant threat, because it is not usually a question of one single function which prints some text on a screen, but rather the request is itself probably just a link in a series of other requests. Stopping one request would stop the others, memory resources would not be freed, file descriptors might remain open, communication via socket could be interrupted, and so on. Therefore it is important to think about finishing requests, either successfully or not, and also to prepare functions for all possible scenarios, so that the the callbacks do not process data that are actually invalid or, even worse, in fact non-existent meaning that a segmentation fault may arise.
  • \b Manually - This is the most common type of finishing request. Calling this function sets the request as a TEVENT_REQ_DONE. This is the only purpose of this function and it should be used when everything went well. Typically it is used within the done functions. @code void tevent_req_done (struct tevent_req *req) @endcode Alternatively, the request can end up being unsuccessful. @code bool tevent_req_error (struct tevent_req *req, uint64_t error) @endcode The second argument takes the number of an error (declared by the programmer, for example in an enumerated variable). The function tevent_req_error() sets the status of the request as a TEVENT_REQ_USER_ERROR and also stores the code of error within the structure so it can be used, for example for debugging. The function returns true, if marking the request as an error was processed with no problem - value error passed to this function is not equal to 1.
  • Setting up a timeout for request - A request can be finished virtually, or if the process takes too much time, it can be timed out. This is considered as an error of the request and it leads to calling callback. In the background, this timeout is set through a time event (described in @subpage tevent_events ) which eventually triggers an operation marking the request as a TEVENT_REQ_TIMED_OUT (can not be considered as successfully finished). In case a time out was already set, this operation will overwrite it with a new time value (so the timeout may be lengthened) and if everything is set properly, it returns true. @code bool tevent_req_set_endtime(struct tevent_req *req, struct tevent_context *ev, struct timeval endtime); @endcode
  • Premature Triggering - Imagine a situation in which some part of a nested subrequest ended up with a failure and it is still required to trigger a callback. Such as example might result from lack of memory leading to the impossibility of allocating enough memory requirements for the event to start processing another subrequest, or from a clear intention to skip other procedures and trigger the callback regardless of other progress. In these cases, the function tevent_req_post() is very handy and offers this option. @code struct tevent_req* tevent_req_post (struct tevent_req *req, struct tevent_context *ev); @endcode A request finished in this way does not behave as a time event nor as a file descriptor event but as a immediately scheduled event, and therefore it will be treated according the description laid down in @subpage tevent_events .
@section nested Subrequests - Nested Requests To create more complex and interconnected asynchronous operations, it is possible to submerge a request into another and thus create a so-called subrequest. Subrequests are not represented by any other special structure but they are created from tevent_req_create(). This diagram shows the nesting and life time of each request. The table below describes the same in words, and shows the triggering of functions during the application run. Wrapper represents the trigger of the whole cascade of (sub)requests. It may be e.g. a time or file descriptor event, or another request that was created at a specific time by the function tevent_wakeup_send() which is a slightly exceptional method of creating @code struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct timeval wakeup_time); @endcode By calling this function, it is possible to create a tevent request which is actually the return value of this function. In summary, it sets the time value of the tevent request’s creation. While using this function it is necessary to use another function in the subrequest’s callback to check for any problems tevent_wakeup_recv() ) @image html tevent_subrequest.png A comprehensive example of nested subrequests can be found in the file echo_server.c. It implements a complete, self-contained echo server with no dependencies but libevent and libtalloc. */ ldb-2.0.8/lib/tevent/doc/tevent_thread.dox0000660000000000000000000002336512775624157020437 0ustar rootroot00000000000000/** @page tevent_thread Chapter 6: Tevent with threads @section threads Tevent with threads In order to use tevent with threads, you must first understand how to use the talloc library in threaded programs. For more information about working with talloc, please visit talloc website where tutorial and documentation are located. If a tevent context structure is talloced from a NULL, thread-safe talloc context, then it can be safe to use in a threaded program. The function talloc_disable_null_tracking() must be called from the initial program thread before any talloc calls are made to ensure talloc is thread-safe. Each thread must create it's own tevent context structure as follows tevent_context_init(NULL) and no talloc memory contexts can be shared between threads. Separate threads using tevent in this way can communicate by writing data into file descriptors that are being monitored by a tevent context on another thread. For example (simplified with no error handling): @code Main thread: main() { talloc_disable_null_tracking(); struct tevent_context *master_ev = tevent_context_init(NULL); void *mem_ctx = talloc_new(master_ev); // Create file descriptor to monitor. int pipefds[2]; pipe(pipefds); struct tevent_fd *fde = tevent_add_fd(master_ev, mem_ctx, pipefds[0], // read side of pipe TEVENT_FD_READ, pipe_read_handler, // callback function private_data_pointer); // Create sub thread, pass pipefds[1] write side of pipe to it. // The above code not shown here.. // Process events. tevent_loop_wait(master_ev); // Cleanup if loop exits. talloc_free(master_ev); } @endcode When the subthread writes to pipefds[1], the function pipe_read_handler() will be called in the main thread. @subsection More sophisticated use A popular way to use an event library within threaded programs is to allow a sub-thread to asynchronously schedule a tevent_immediate function call from the event loop of another thread. This can be built out of the basic functions and isolation mechanisms of tevent, but tevent also comes with some utility functions that make this easier, so long as you understand the limitations that using threads with talloc and tevent impose. To allow a tevent context to receive an asynchronous tevent_immediate function callback from another thread, create a struct tevent_thread_proxy * by calling @code struct tevent_thread_proxy *tevent_thread_proxy_create( struct tevent_context *dest_ev_ctx); @endcode This function allocates the internal data structures to allow asynchronous callbacks as a talloc child of the struct tevent_context *, and returns a struct tevent_thread_proxy * that can be passed to another thread. When you have finished receiving asynchronous callbacks, simply talloc_free the struct tevent_thread_proxy *, or talloc_free the struct tevent_context *, which will deallocate the resources used. To schedule an asynchronous tevent_immediate function call from one thread on the tevent loop of another thread, use @code void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, struct tevent_immediate **pp_im, tevent_immediate_handler_t handler, void **pp_private_data); @endcode This function causes the function handler() to be invoked as a tevent_immediate callback from the event loop of the thread that created the struct tevent_thread_proxy * (so the owning struct tevent_context * should be long-lived and not in the process of being torn down). The struct tevent_thread_proxy object being used here is a child of the event context of the target thread. So external synchronization mechanisms must be used to ensure that the target object is still in use at the time of the tevent_thread_proxy_schedule() call. In the example below, the request/response nature of the communication ensures this. The struct tevent_immediate **pp_im passed into this function should be a struct tevent_immediate * allocated on a talloc context local to this thread, and will be reparented via talloc_move to be owned by struct tevent_thread_proxy *tp. *pp_im will be set to NULL on successful scheduling of the tevent_immediate call. handler() will be called as a normal tevent_immediate callback from the struct tevent_context * of the destination event loop that created the struct tevent_thread_proxy * Returning from this functions does not mean that the handler has been invoked, merely that it has been scheduled to be called in the destination event loop. Because the calling thread does not wait for the callback to be scheduled and run on the destination thread, this is a fire-and-forget call. If you wish confirmation of the handler() being successfully invoked, you must ensure it replies to the caller in some way. Because of asynchronous nature of this call, the nature of the parameter passed to the destination thread has some restructions. If you don't need parameters, merely pass NULL as the value of void **pp_private_data. If you wish to pass a pointer to data between the threads, it MUST be a pointer to a talloced pointer, which is not part of a talloc-pool, and it must not have a destructor attached. The ownership of the memory pointed to will be passed from the calling thread to the tevent library, and if the receiving thread does not talloc-reparent it to its own contexts, it will be freed once the handler is called. On success, *pp_private will be NULL to signify the talloc memory ownership has been moved. In practice for message passing between threads in event loops these restrictions are not very onerous. The easiest way to to a request-reply pair between tevent loops on different threads is to pass the parameter block of memory back and forth using a reply tevent_thread_proxy_schedule() call. Here is an example (without error checking for simplicity): @code ------------------------------------------------ // Master thread. main() { // Make talloc thread-safe. talloc_disable_null_tracking(); // Create the master event context. struct tevent_context *master_ev = tevent_context_init(NULL); // Create the master thread proxy to allow it to receive // async callbacks from other threads. struct tevent_thread_proxy *master_tp = tevent_thread_proxy_create(master_ev); // Create sub-threads, passing master_tp in // some way to them. // This code not shown.. // Process events. // Function master_callback() below // will be invoked on this thread on // master_ev event context. tevent_loop_wait(master_ev); // Cleanup if loop exits. talloc_free(master_ev); } // Data passed between threads. struct reply_state { struct tevent_thread_proxy *reply_tp; pthread_t thread_id; bool *p_finished; }; // Callback Called in child thread context. static void thread_callback(struct tevent_context *ev, struct tevent_immediate *im, void *private_ptr) { // Move the ownership of what private_ptr // points to from the tevent library back to this thread. struct reply_state *rsp = talloc_get_type_abort(private_ptr, struct reply_state); talloc_steal(ev, rsp); *rsp->p_finished = true; // im will be talloc_freed on return from this call. // but rsp will not. } // Callback Called in master thread context. static void master_callback(struct tevent_context *ev, struct tevent_immediate *im, void *private_ptr) { // Move the ownership of what private_ptr // points to from the tevent library to this thread. struct reply_state *rsp = talloc_get_type_abort(private_ptr, struct reply_state); talloc_steal(ev, rsp); printf("Callback from thread %s\n", thread_id_to_string(rsp->thread_id)); /* Now reply to the thread ! */ tevent_thread_proxy_schedule(rsp->reply_tp, &im, thread_callback, &rsp); // Note - rsp and im are now NULL as the tevent library // owns the memory. } // Child thread. static void *thread_fn(void *private_ptr) { struct tevent_thread_proxy *master_tp = talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); bool finished = false; int ret; // Create our own event context. struct tevent_context *ev = tevent_context_init(NULL); // Create the local thread proxy to allow us to receive // async callbacks from other threads. struct tevent_thread_proxy *local_tp = tevent_thread_proxy_create(master_ev); // Setup the data to send. struct reply_state *rsp = talloc(ev, struct reply_state); rsp->reply_tp = local_tp; rsp->thread_id = pthread_self(); rsp->p_finished = &finished; // Create the immediate event to use. struct tevent_immediate *im = tevent_create_immediate(ev); // Call the master thread. tevent_thread_proxy_schedule(master_tp, &im, master_callback, &rsp); // Note - rsp and im are now NULL as the tevent library // owns the memory. // Wait for the reply. while (!finished) { tevent_loop_once(ev); } // Cleanup. talloc_free(ev); return NULL; } @endcode Note this doesn't have to be a master-subthread communication. Any thread that has access to the struct tevent_thread_proxy * pointer of another thread that has called tevent_thread_proxy_create() can send an async tevent_immediate request. But remember the caveat that external synchronization must be used to ensure the target struct tevent_thread_proxy * object exists at the time of the tevent_thread_proxy_schedule() call or unreproducible crashes will result. */ ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox0000660000000000000000000000052012617125507021005 0ustar rootroot00000000000000/** @page tevent_tutorial The Tutorial @section tevent_tutorial_introduction Introduction Tutorial describing working with tevent library. @section tevent_tutorial_toc Table of contents @subpage tevent_context @subpage tevent_events @subpage tevent_data @subpage tevent_request @subpage tevent_queue @subpage tevent_thread */ ldb-2.0.8/lib/tevent/doc/tutorials.dox0000660000000000000000000000400112406075657017607 0ustar rootroot00000000000000/** * @page tevent_queue_tutorial The tevent_queue tutorial * * @section Introduction * * A tevent_queue is used to queue up async requests that must be * serialized. For example writing buffers into a socket must be * serialized. Writing a large lump of data into a socket can require * multiple write(2) or send(2) system calls. If more than one async * request is outstanding to write large buffers into a socket, every * request must individually be completed before the next one begins, * even if multiple syscalls are required. * * To do this, every socket gets assigned a tevent_queue struct. * * Creating a serialized async request follows the usual convention to * return a tevent_req structure with an embedded state structure. To * serialize the work the requests is about to so, instead of directly * starting or doing that work, tevent_queue_add must be called. When it * is time for the serialized async request to do its work, the trigger * callback function tevent_queue_add was given is called. In the example * of writing to a socket, the trigger is called when the write request * can begin accessing the socket. * * How does this engine work behind the scenes? When the queue is empty, * tevent_queue_add schedules an immediate call to the trigger * callback. The trigger callback starts its work, likely by starting * other async subrequests. While these async subrequests are working, * more requests can accumulate in the queue by tevent_queue_add. While * there is no function to explicitly trigger the next waiter in line, it * still works: When the active request in the queue is done, it will be * destroyed by talloc_free. Talloc_free of an serialized async request * that had been added to a queue will trigger the next request in the * queue via a talloc destructor attached to a child of the serialized * request. This way the queue will be kept busy when an async request * finishes. * * @section Example * * @code * Metze: Please add a code example here. * @endcode */ ldb-2.0.8/lib/tevent/doxy.config0000660000000000000000000023645712406075657016500 0ustar rootroot00000000000000# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed # in front of the TAG it is preceding . # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = tevent # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 0.9.8 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, # Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, # Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields or simple typedef fields will be shown # inline in the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO (the default), structs, classes, and unions are shown on a separate # page (for HTML and Man pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can # be an expensive process and often the same symbol appear multiple times in # the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too # small doxygen will become slower. If the cache is too large, memory is wasted. # The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid # range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 # symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = . \ doc # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/img # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be ignored. # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NONE # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript # pieces of code that will be used on startup of the MathJax code. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search # engine library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id # of to a relative location where the documentation can be found. # The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4 will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images # or other source files which should be copied to the LaTeX output directory. # Note that the files will be copied as-is; there are no commands or markers # available. LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- # If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files # that can be used to generate PDF. GENERATE_DOCBOOK = NO # The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in # front of it. If left blank docbook will be used as the default path. DOCBOOK_OUTPUT = docbook #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN \ PRINTF_ATTRIBUTE(x,y)= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed # in the related pages index. If set to NO, only the current project's # pages will be listed. EXTERNAL_PAGES = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # manageable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES ldb-2.0.8/lib/tevent/echo_server.c0000660000000000000000000003422013226330107016737 0ustar rootroot00000000000000/** ** NOTE! The following liberal license applies to this sample file only. ** This does NOT imply that all of Samba is released under this license. ** ** This file is meant as a starting point for libtevent users to be used ** in any program linking against the LGPL licensed libtevent. **/ /* * This file is being made available by the Samba Team under the following * license: * * Permission to use, copy, modify, and distribute this sample file for any * purpose is hereby granted without fee. * * This work 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. */ #include #include #include #include #include #include #include #include #include "tevent.h" #include "talloc.h" /** * @brief Helper function to get a useful unix error from tevent_req */ static bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) { enum tevent_req_state state; uint64_t err; if (!tevent_req_is_error(req, &state, &err)) { return false; } switch (state) { case TEVENT_REQ_TIMED_OUT: *perrno = ETIMEDOUT; break; case TEVENT_REQ_NO_MEMORY: *perrno = ENOMEM; break; case TEVENT_REQ_USER_ERROR: *perrno = err; break; default: *perrno = EINVAL; break; } return true; } /** * @brief Wrapper around accept(2) */ struct accept_state { struct tevent_fd *fde; int listen_sock; socklen_t addrlen; struct sockaddr_storage addr; int sock; }; static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data); static struct tevent_req *accept_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int listen_sock) { struct tevent_req *req; struct accept_state *state; req = tevent_req_create(mem_ctx, &state, struct accept_state); if (req == NULL) { return NULL; } state->listen_sock = listen_sock; state->fde = tevent_add_fd(ev, state, listen_sock, TEVENT_FD_READ, accept_handler, req); if (tevent_req_nomem(state->fde, req)) { return tevent_req_post(req, ev); } return req; } static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); struct accept_state *state = tevent_req_data(req, struct accept_state); int ret; TALLOC_FREE(state->fde); if ((flags & TEVENT_FD_READ) == 0) { tevent_req_error(req, EIO); return; } state->addrlen = sizeof(state->addr); ret = accept(state->listen_sock, (struct sockaddr *)&state->addr, &state->addrlen); if (ret == -1) { tevent_req_error(req, errno); return; } smb_set_close_on_exec(ret); state->sock = ret; tevent_req_done(req); } static int accept_recv(struct tevent_req *req, struct sockaddr *paddr, socklen_t *paddrlen, int *perr) { struct accept_state *state = tevent_req_data(req, struct accept_state); int err; if (tevent_req_is_unix_error(req, &err)) { if (perr != NULL) { *perr = err; } return -1; } if (paddr != NULL) { memcpy(paddr, &state->addr, state->addrlen); } if (paddrlen != NULL) { *paddrlen = state->addrlen; } return state->sock; } /** * @brief Wrapper around read(2) */ struct read_state { struct tevent_fd *fde; int fd; void *buf; size_t count; ssize_t nread; }; static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data); static struct tevent_req *read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buf, size_t count) { struct tevent_req *req; struct read_state *state; req = tevent_req_create(mem_ctx, &state, struct read_state); if (req == NULL) { return NULL; } state->fd = fd; state->buf = buf; state->count = count; state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_handler, req); if (tevent_req_nomem(state->fde, req)) { return tevent_req_post(req, ev); } return req; } static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); struct read_state *state = tevent_req_data(req, struct read_state); ssize_t ret; TALLOC_FREE(state->fde); if ((flags & TEVENT_FD_READ) == 0) { tevent_req_error(req, EIO); return; } ret = read(state->fd, state->buf, state->count); if (ret == -1) { tevent_req_error(req, errno); return; } state->nread = ret; tevent_req_done(req); } static ssize_t read_recv(struct tevent_req *req, int *perr) { struct read_state *state = tevent_req_data(req, struct read_state); int err; if (tevent_req_is_unix_error(req, &err)) { if (perr != NULL) { *perr = err; } return -1; } return state->nread; } /** * @brief Wrapper around write(2) */ struct write_state { struct tevent_fd *fde; int fd; const void *buf; size_t count; ssize_t nwritten; }; static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data); static struct tevent_req *write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buf, size_t count) { struct tevent_req *req; struct write_state *state; req = tevent_req_create(mem_ctx, &state, struct write_state); if (req == NULL) { return NULL; } state->fd = fd; state->buf = buf; state->count = count; state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, write_handler, req); if (tevent_req_nomem(state->fde, req)) { return tevent_req_post(req, ev); } return req; } static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); struct write_state *state = tevent_req_data(req, struct write_state); ssize_t ret; TALLOC_FREE(state->fde); if ((flags & TEVENT_FD_WRITE) == 0) { tevent_req_error(req, EIO); return; } ret = write(state->fd, state->buf, state->count); if (ret == -1) { tevent_req_error(req, errno); return; } state->nwritten = ret; tevent_req_done(req); } static ssize_t write_recv(struct tevent_req *req, int *perr) { struct write_state *state = tevent_req_data(req, struct write_state); int err; if (tevent_req_is_unix_error(req, &err)) { if (perr != NULL) { *perr = err; } return -1; } return state->nwritten; } /** * @brief Wrapper function that deals with short writes */ struct writeall_state { struct tevent_context *ev; int fd; const void *buf; size_t count; size_t nwritten; }; static void writeall_done(struct tevent_req *subreq); static struct tevent_req *writeall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buf, size_t count) { struct tevent_req *req, *subreq; struct writeall_state *state; req = tevent_req_create(mem_ctx, &state, struct writeall_state); if (req == NULL) { return NULL; } state->ev = ev; state->fd = fd; state->buf = buf; state->count = count; state->nwritten = 0; subreq = write_send(state, state->ev, state->fd, ((char *)state->buf)+state->nwritten, state->count - state->nwritten); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } tevent_req_set_callback(subreq, writeall_done, req); return req; } static void writeall_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct writeall_state *state = tevent_req_data( req, struct writeall_state); ssize_t nwritten; int err = 0; nwritten = write_recv(subreq, &err); TALLOC_FREE(subreq); if (nwritten == -1) { tevent_req_error(req, err); return; } state->nwritten += nwritten; if (state->nwritten < state->count) { subreq = write_send(state, state->ev, state->fd, ((char *)state->buf)+state->nwritten, state->count - state->nwritten); if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, writeall_done, req); return; } tevent_req_done(req); } static ssize_t writeall_recv(struct tevent_req *req, int *perr) { struct writeall_state *state = tevent_req_data( req, struct writeall_state); int err; if (tevent_req_is_unix_error(req, &err)) { if (perr != NULL) { *perr = err; } return -1; } return state->nwritten; } /** * @brief Async echo handler code dealing with one client */ struct echo_state { struct tevent_context *ev; int fd; uint8_t *buf; }; static int echo_state_destructor(struct echo_state *s); static void echo_read_done(struct tevent_req *subreq); static void echo_writeall_done(struct tevent_req *subreq); static struct tevent_req *echo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, size_t bufsize) { struct tevent_req *req, *subreq; struct echo_state *state; req = tevent_req_create(mem_ctx, &state, struct echo_state); if (req == NULL) { return NULL; } state->ev = ev; state->fd = fd; talloc_set_destructor(state, echo_state_destructor); state->buf = talloc_array(state, uint8_t, bufsize); if (tevent_req_nomem(state->buf, req)) { return tevent_req_post(req, ev); } subreq = read_send(state, state->ev, state->fd, state->buf, talloc_get_size(state->buf)); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } tevent_req_set_callback(subreq, echo_read_done, req); return req; } static int echo_state_destructor(struct echo_state *s) { if (s->fd != -1) { printf("Closing client fd %d\n", s->fd); close(s->fd); s->fd = -1; } return 0; } static void echo_read_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct echo_state *state = tevent_req_data( req, struct echo_state); ssize_t nread; int err; nread = read_recv(subreq, &err); TALLOC_FREE(subreq); if (nread == -1) { tevent_req_error(req, err); return; } if (nread == 0) { tevent_req_done(req); return; } subreq = writeall_send(state, state->ev, state->fd, state->buf, nread); if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, echo_writeall_done, req); } static void echo_writeall_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct echo_state *state = tevent_req_data( req, struct echo_state); ssize_t nwritten; int err; nwritten = writeall_recv(subreq, &err); TALLOC_FREE(subreq); if (nwritten == -1) { if (err == EPIPE) { tevent_req_done(req); return; } tevent_req_error(req, err); return; } subreq = read_send(state, state->ev, state->fd, state->buf, talloc_get_size(state->buf)); if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, echo_read_done, req); } static bool echo_recv(struct tevent_req *req, int *perr) { int err; if (tevent_req_is_unix_error(req, &err)) { *perr = err; return false; } return true; } /** * @brief Full echo handler code accepting and handling clients */ struct echo_server_state { struct tevent_context *ev; int listen_sock; }; static void echo_server_accepted(struct tevent_req *subreq); static void echo_server_client_done(struct tevent_req *subreq); static struct tevent_req *echo_server_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int listen_sock) { struct tevent_req *req, *subreq; struct echo_server_state *state; req = tevent_req_create(mem_ctx, &state, struct echo_server_state); if (req == NULL) { return NULL; } state->ev = ev; state->listen_sock = listen_sock; subreq = accept_send(state, state->ev, state->listen_sock); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } tevent_req_set_callback(subreq, echo_server_accepted, req); return req; } static void echo_server_accepted(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct echo_server_state *state = tevent_req_data( req, struct echo_server_state); int sock, err; sock = accept_recv(subreq, NULL, NULL, &err); TALLOC_FREE(subreq); if (sock == -1) { tevent_req_error(req, err); return; } printf("new client fd %d\n", sock); subreq = echo_send(state, state->ev, sock, 100); if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, echo_server_client_done, req); subreq = accept_send(state, state->ev, state->listen_sock); if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, echo_server_accepted, req); } static void echo_server_client_done(struct tevent_req *subreq) { bool ret; int err; ret = echo_recv(subreq, &err); TALLOC_FREE(subreq); if (ret) { printf("Client done\n"); } else { printf("Client failed: %s\n", strerror(err)); } } static bool echo_server_recv(struct tevent_req *req, int *perr) { int err; if (tevent_req_is_unix_error(req, &err)) { *perr = err; return false; } return true; } int main(int argc, const char **argv) { int ret, port, listen_sock, err; struct tevent_context *ev; struct sockaddr_in addr; struct tevent_req *req; bool result; if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } port = atoi(argv[1]); printf("listening on port %d\n", port); listen_sock = socket(AF_INET, SOCK_STREAM, 0); if (listen_sock == -1) { perror("socket() failed"); exit(1); } addr = (struct sockaddr_in) { .sin_family = AF_INET, .sin_port = htons(port) }; ret = bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)); if (ret == -1) { perror("bind() failed"); exit(1); } ret = listen(listen_sock, 5); if (ret == -1) { perror("listen() failed"); exit(1); } ev = tevent_context_init(NULL); if (ev == NULL) { fprintf(stderr, "tevent_context_init failed\n"); exit(1); } req = echo_server_send(ev, ev, listen_sock); if (req == NULL) { fprintf(stderr, "echo_server_send failed\n"); exit(1); } if (!tevent_req_poll(req, ev)) { perror("tevent_req_poll() failed"); exit(1); } result = echo_server_recv(req, &err); TALLOC_FREE(req); if (!result) { fprintf(stderr, "echo_server failed: %s\n", strerror(err)); exit(1); } return 0; } ldb-2.0.8/lib/tevent/pytevent.c0000660000000000000000000005535213573675413016343 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Python bindings for tevent Copyright (C) Jelmer Vernooij 2010 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include #include "replace.h" #include #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #endif /* discard signature of 'func' in favour of 'target_sig' */ #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func void init_tevent(void); typedef struct { PyObject_HEAD struct tevent_context *ev; } TeventContext_Object; typedef struct { PyObject_HEAD struct tevent_queue *queue; } TeventQueue_Object; typedef struct { PyObject_HEAD struct tevent_req *req; } TeventReq_Object; typedef struct { PyObject_HEAD struct tevent_signal *signal; } TeventSignal_Object; typedef struct { PyObject_HEAD struct tevent_timer *timer; PyObject *callback; } TeventTimer_Object; typedef struct { PyObject_HEAD struct tevent_fd *fd; } TeventFd_Object; static PyTypeObject TeventContext_Type; static PyTypeObject TeventReq_Type; static PyTypeObject TeventQueue_Type; static PyTypeObject TeventSignal_Type; static PyTypeObject TeventTimer_Type; static PyTypeObject TeventFd_Type; static int py_context_init(struct tevent_context *ev) { /* FIXME */ return 0; } static struct tevent_fd *py_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location) { /* FIXME */ return NULL; } static void py_set_fd_close_fn(struct tevent_fd *fde, tevent_fd_close_fn_t close_fn) { /* FIXME */ } static uint16_t py_get_fd_flags(struct tevent_fd *fde) { /* FIXME */ return 0; } static void py_set_fd_flags(struct tevent_fd *fde, uint16_t flags) { /* FIXME */ } /* timed_event functions */ static struct tevent_timer *py_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location) { /* FIXME */ return NULL; } /* immediate event functions */ static void py_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ev, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location) { /* FIXME */ } /* signal functions */ static struct tevent_signal *py_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data, const char *handler_name, const char *location) { /* FIXME */ return NULL; } /* loop functions */ static int py_loop_once(struct tevent_context *ev, const char *location) { /* FIXME */ return 0; } static int py_loop_wait(struct tevent_context *ev, const char *location) { /* FIXME */ return 0; } const static struct tevent_ops py_tevent_ops = { .context_init = py_context_init, .add_fd = py_add_fd, .set_fd_close_fn = py_set_fd_close_fn, .get_fd_flags = py_get_fd_flags, .set_fd_flags = py_set_fd_flags, .add_timer = py_add_timer, .schedule_immediate = py_schedule_immediate, .add_signal = py_add_signal, .loop_wait = py_loop_wait, .loop_once = py_loop_once, }; static PyObject *py_register_backend(PyObject *self, PyObject *args) { PyObject *name, *py_backend; if (!PyArg_ParseTuple(args, "O", &py_backend)) return NULL; name = PyObject_GetAttrString(py_backend, "name"); if (name == NULL) { PyErr_SetNone(PyExc_AttributeError); return NULL; } if (!PyUnicode_Check(name)) { PyErr_SetNone(PyExc_TypeError); Py_DECREF(name); return NULL; } if (!tevent_register_backend(PyUnicode_AsUTF8(name), &py_tevent_ops)) { /* FIXME: What to do with backend */ PyErr_SetNone(PyExc_RuntimeError); Py_DECREF(name); return NULL; } Py_DECREF(name); Py_RETURN_NONE; } static PyObject *py_tevent_context_reinitialise(TeventContext_Object *self, PyObject *Py_UNUSED(ignored)) { int ret = tevent_re_initialise(self->ev); if (ret != 0) { PyErr_SetNone(PyExc_RuntimeError); return NULL; } Py_RETURN_NONE; } static PyObject *py_tevent_queue_stop(TeventQueue_Object *self, PyObject *Py_UNUSED(ignored)) { tevent_queue_stop(self->queue); Py_RETURN_NONE; } static PyObject *py_tevent_queue_start(TeventQueue_Object *self, PyObject *Py_UNUSED(ignored)) { tevent_queue_start(self->queue); Py_RETURN_NONE; } static void py_queue_trigger(struct tevent_req *req, void *private_data) { PyObject *callback = private_data, *ret; ret = PyObject_CallFunction(callback, discard_const_p(char, "")); Py_XDECREF(ret); } static PyObject *py_tevent_queue_add(TeventQueue_Object *self, PyObject *args) { TeventContext_Object *py_ev; TeventReq_Object *py_req; PyObject *trigger; bool ret; if (!PyArg_ParseTuple(args, "O!O!O", &TeventContext_Type, &py_ev, &TeventReq_Type, &py_req, &trigger)) return NULL; Py_INCREF(trigger); ret = tevent_queue_add(self->queue, py_ev->ev, py_req->req, py_queue_trigger, trigger); if (!ret) { PyErr_SetString(PyExc_RuntimeError, "queue add failed"); Py_DECREF(trigger); return NULL; } Py_RETURN_NONE; } static PyMethodDef py_tevent_queue_methods[] = { { "stop", (PyCFunction)py_tevent_queue_stop, METH_NOARGS, "S.stop()" }, { "start", (PyCFunction)py_tevent_queue_start, METH_NOARGS, "S.start()" }, { "add", (PyCFunction)py_tevent_queue_add, METH_VARARGS, "S.add(ctx, req, trigger, baton)" }, { NULL }, }; static PyObject *py_tevent_context_wakeup_send(PyObject *self, PyObject *args) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_context_loop_wait(TeventContext_Object *self, PyObject *Py_UNUSED(ignored)) { if (tevent_loop_wait(self->ev) != 0) { PyErr_SetNone(PyExc_RuntimeError); return NULL; } Py_RETURN_NONE; } static PyObject *py_tevent_context_loop_once(TeventContext_Object *self, PyObject *Py_UNUSED(ignored)) { if (tevent_loop_once(self->ev) != 0) { PyErr_SetNone(PyExc_RuntimeError); return NULL; } Py_RETURN_NONE; } static void py_tevent_signal_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { PyObject *callback = (PyObject *)private_data, *ret; ret = PyObject_CallFunction(callback, discard_const_p(char, "ii"), signum, count); Py_XDECREF(ret); } static void py_tevent_signal_dealloc(TeventSignal_Object *self) { talloc_free(self->signal); PyObject_Del(self); } static PyTypeObject TeventSignal_Type = { .tp_name = "tevent.Signal", .tp_basicsize = sizeof(TeventSignal_Object), .tp_dealloc = (destructor)py_tevent_signal_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; static PyObject *py_tevent_context_add_signal(TeventContext_Object *self, PyObject *args) { int signum, sa_flags; PyObject *handler; struct tevent_signal *sig; TeventSignal_Object *ret; if (!PyArg_ParseTuple(args, "iiO", &signum, &sa_flags, &handler)) return NULL; Py_INCREF(handler); sig = tevent_add_signal(self->ev, NULL, signum, sa_flags, py_tevent_signal_handler, handler); ret = PyObject_New(TeventSignal_Object, &TeventSignal_Type); if (ret == NULL) { PyErr_NoMemory(); talloc_free(sig); return NULL; } ret->signal = sig; return (PyObject *)ret; } static void py_timer_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { TeventTimer_Object *self = private_data; PyObject *ret; ret = PyObject_CallFunction(self->callback, discard_const_p(char, "l"), te); if (ret == NULL) { /* No Python stack to propagate exception to; just print traceback */ PyErr_PrintEx(0); } Py_XDECREF(ret); } static void py_tevent_timer_dealloc(TeventTimer_Object *self) { if (self->timer) { talloc_free(self->timer); } Py_DECREF(self->callback); PyObject_Del(self); } static int py_tevent_timer_traverse(TeventTimer_Object *self, visitproc visit, void *arg) { Py_VISIT(self->callback); return 0; } static PyObject* py_tevent_timer_get_active(TeventTimer_Object *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(self->timer != NULL); } struct PyGetSetDef py_tevent_timer_getset[] = { { .name = discard_const_p(char, "active"), .get = (getter)py_tevent_timer_get_active, .doc = discard_const_p(char, "true if the timer is scheduled to run"), }, {NULL}, }; static PyTypeObject TeventTimer_Type = { .tp_name = "tevent.Timer", .tp_basicsize = sizeof(TeventTimer_Object), .tp_dealloc = (destructor)py_tevent_timer_dealloc, .tp_traverse = (traverseproc)py_tevent_timer_traverse, .tp_getset = py_tevent_timer_getset, .tp_flags = Py_TPFLAGS_DEFAULT, }; struct TeventTimer_Object_ref { TeventTimer_Object *obj; }; static int TeventTimer_Object_ref_destructor(struct TeventTimer_Object_ref *ref) { ref->obj->timer = NULL; Py_DECREF(ref->obj); return 0; } static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self, struct timeval next_event, PyObject *callback) { /* Ownership notes: * * There are 5 pieces in play; two tevent contexts and 3 Python objects: * - The tevent timer * - The tevent context * - The Python context -- "self" * - The Python timer (TeventTimer_Object) -- "ret" * - The Python callback function -- "callback" * * We only use the Python context for getting the tevent context, * afterwards it can be destroyed. * * The tevent context owns the tevent timer. * * The tevent timer holds a reference to the Python timer, so the Python * timer must always outlive the tevent timer. * The Python timer has a pointer to the tevent timer; a destructor is * used to set this to NULL when the tevent timer is deallocated. * * The tevent timer can be deallocated in these cases: * 1) when the context is destroyed * 2) after the event fires * Posssibly, API might be added to cancel (free the tevent timer). * * The Python timer holds a reference to the callback. */ TeventTimer_Object *ret; struct TeventTimer_Object_ref *ref; ret = PyObject_New(TeventTimer_Object, &TeventTimer_Type); if (ret == NULL) { PyErr_NoMemory(); return NULL; } Py_INCREF(callback); ret->callback = callback; ret->timer = tevent_add_timer(self->ev, NULL, next_event, py_timer_handler, ret); if (ret->timer == NULL) { Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); return NULL; } ref = talloc(ret->timer, struct TeventTimer_Object_ref); if (ref == NULL) { talloc_free(ret->timer); Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); return NULL; } Py_INCREF(ret); ref->obj = ret; talloc_set_destructor(ref, TeventTimer_Object_ref_destructor); return (PyObject *)ret; } static PyObject *py_tevent_context_add_timer(TeventContext_Object *self, PyObject *args) { struct timeval next_event; PyObject *callback; double secs, usecs; if (!PyArg_ParseTuple(args, "dO", &secs, &callback)){ return NULL; } next_event.tv_sec = secs; usecs = (secs - next_event.tv_sec) * 1000000.0; next_event.tv_usec = usecs; return py_tevent_context_add_timer_internal(self, next_event, callback); } static PyObject *py_tevent_context_add_timer_offset(TeventContext_Object *self, PyObject *args) { struct timeval next_event; double offset; int seconds; PyObject *callback; if (!PyArg_ParseTuple(args, "dO", &offset, &callback)) return NULL; seconds = offset; offset -= seconds; next_event = tevent_timeval_current_ofs(seconds, (int)(offset*1000000)); return py_tevent_context_add_timer_internal(self, next_event, callback); } static void py_fd_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { PyObject *callback = private_data, *ret; ret = PyObject_CallFunction(callback, discard_const_p(char, "i"), flags); Py_XDECREF(ret); } static void py_tevent_fp_dealloc(TeventFd_Object *self) { talloc_free(self->fd); PyObject_Del(self); } static PyTypeObject TeventFd_Type = { .tp_name = "tevent.Fd", .tp_basicsize = sizeof(TeventFd_Object), .tp_dealloc = (destructor)py_tevent_fp_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; static PyObject *py_tevent_context_add_fd(TeventContext_Object *self, PyObject *args) { int fd, flags; PyObject *handler; struct tevent_fd *tfd; TeventFd_Object *ret; if (!PyArg_ParseTuple(args, "iiO", &fd, &flags, &handler)) return NULL; tfd = tevent_add_fd(self->ev, NULL, fd, flags, py_fd_handler, handler); if (tfd == NULL) { PyErr_SetNone(PyExc_RuntimeError); return NULL; } ret = PyObject_New(TeventFd_Object, &TeventFd_Type); if (ret == NULL) { talloc_free(tfd); return NULL; } ret->fd = tfd; return (PyObject *)ret; } static PyMethodDef py_tevent_context_methods[] = { { "reinitialise", (PyCFunction)py_tevent_context_reinitialise, METH_NOARGS, "S.reinitialise()" }, { "wakeup_send", (PyCFunction)py_tevent_context_wakeup_send, METH_VARARGS, "S.wakeup_send(wakeup_time) -> req" }, { "loop_wait", (PyCFunction)py_tevent_context_loop_wait, METH_NOARGS, "S.loop_wait()" }, { "loop_once", (PyCFunction)py_tevent_context_loop_once, METH_NOARGS, "S.loop_once()" }, { "add_signal", (PyCFunction)py_tevent_context_add_signal, METH_VARARGS, "S.add_signal(signum, sa_flags, handler) -> signal" }, { "add_timer", (PyCFunction)py_tevent_context_add_timer, METH_VARARGS, "S.add_timer(next_event, handler) -> timer" }, { "add_timer_offset", (PyCFunction)py_tevent_context_add_timer_offset, METH_VARARGS, "S.add_timer(offset_seconds, handler) -> timer" }, { "add_fd", (PyCFunction)py_tevent_context_add_fd, METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" }, { NULL }, }; static PyObject *py_tevent_req_wakeup_recv(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_received(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_is_error(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_poll(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_is_in_progress(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* FIXME */ Py_RETURN_NONE; } static PyGetSetDef py_tevent_req_getsetters[] = { { .name = discard_const_p(char, "in_progress"), .get = (getter)py_tevent_req_is_in_progress, .doc = discard_const_p(char, "Whether the request is in progress"), }, { NULL } }; static PyObject *py_tevent_req_post(PyObject *self, PyObject *args) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_set_error(PyObject *self, PyObject *args) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_done(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_notify_callback(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_set_endtime(PyObject *self, PyObject *args) { /* FIXME */ Py_RETURN_NONE; } static PyObject *py_tevent_req_cancel(TeventReq_Object *self, PyObject *Py_UNUSED(ignored)) { if (!tevent_req_cancel(self->req)) { PyErr_SetNone(PyExc_RuntimeError); return NULL; } Py_RETURN_NONE; } static PyMethodDef py_tevent_req_methods[] = { { "wakeup_recv", (PyCFunction)py_tevent_req_wakeup_recv, METH_NOARGS, "Wakeup received" }, { "received", (PyCFunction)py_tevent_req_received, METH_NOARGS, "Receive finished" }, { "is_error", (PyCFunction)py_tevent_req_is_error, METH_NOARGS, "is_error() -> (error, state)" }, { "poll", (PyCFunction)py_tevent_req_poll, METH_VARARGS, "poll(ctx)" }, { "post", (PyCFunction)py_tevent_req_post, METH_VARARGS, "post(ctx) -> req" }, { "set_error", (PyCFunction)py_tevent_req_set_error, METH_VARARGS, "set_error(error)" }, { "done", (PyCFunction)py_tevent_req_done, METH_NOARGS, "done()" }, { "notify_callback", (PyCFunction)py_tevent_req_notify_callback, METH_NOARGS, "notify_callback()" }, { "set_endtime", (PyCFunction)py_tevent_req_set_endtime, METH_VARARGS, "set_endtime(ctx, endtime)" }, { "cancel", (PyCFunction)py_tevent_req_cancel, METH_NOARGS, "cancel()" }, { NULL } }; static void py_tevent_req_dealloc(TeventReq_Object *self) { talloc_free(self->req); PyObject_DEL(self); } static PyTypeObject TeventReq_Type = { .tp_name = "tevent.Request", .tp_basicsize = sizeof(TeventReq_Object), .tp_methods = py_tevent_req_methods, .tp_dealloc = (destructor)py_tevent_req_dealloc, .tp_getset = py_tevent_req_getsetters, /* FIXME: .tp_new = py_tevent_req_new, */ }; static PyObject *py_tevent_queue_get_length(TeventQueue_Object *self, PyObject *Py_UNUSED(ignored)) { return PyInt_FromLong(tevent_queue_length(self->queue)); } static PyGetSetDef py_tevent_queue_getsetters[] = { { .name = discard_const_p(char, "length"), .get = (getter)py_tevent_queue_get_length, .doc = discard_const_p(char, "The number of elements in the queue."), }, { NULL }, }; static void py_tevent_queue_dealloc(TeventQueue_Object *self) { talloc_free(self->queue); PyObject_Del(self); } static PyTypeObject TeventQueue_Type = { .tp_name = "tevent.Queue", .tp_basicsize = sizeof(TeventQueue_Object), .tp_dealloc = (destructor)py_tevent_queue_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_getset = py_tevent_queue_getsetters, .tp_methods = py_tevent_queue_methods, }; static PyObject *py_tevent_context_signal_support(PyObject *_self, PyObject *Py_UNUSED(ignored)) { TeventContext_Object *self = (TeventContext_Object *)_self; return PyBool_FromLong(tevent_signal_support(self->ev)); } static PyGetSetDef py_tevent_context_getsetters[] = { { .name = discard_const_p(char, "signal_support"), .get = PY_DISCARD_FUNC_SIG(getter, py_tevent_context_signal_support), .doc = discard_const_p(char, "if this platform and tevent context support signal handling"), }, { NULL } }; static void py_tevent_context_dealloc(TeventContext_Object *self) { talloc_free(self->ev); PyObject_Del(self); } static PyObject *py_tevent_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { const char * const kwnames[] = { "name", NULL }; char *name = NULL; struct tevent_context *ev; TeventContext_Object *ret; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &name)) return NULL; if (name == NULL) { ev = tevent_context_init(NULL); } else { ev = tevent_context_init_byname(NULL, name); } if (ev == NULL) { PyErr_SetNone(PyExc_RuntimeError); return NULL; } ret = PyObject_New(TeventContext_Object, type); if (ret == NULL) { PyErr_NoMemory(); talloc_free(ev); return NULL; } ret->ev = ev; return (PyObject *)ret; } static PyTypeObject TeventContext_Type = { .tp_name = "tevent.Context", .tp_new = py_tevent_context_new, .tp_basicsize = sizeof(TeventContext_Object), .tp_dealloc = (destructor)py_tevent_context_dealloc, .tp_methods = py_tevent_context_methods, .tp_getset = py_tevent_context_getsetters, .tp_flags = Py_TPFLAGS_DEFAULT, }; static PyObject *py_set_default_backend(PyObject *self, PyObject *args) { char *backend_name; if (!PyArg_ParseTuple(args, "s", &backend_name)) return NULL; tevent_set_default_backend(backend_name); Py_RETURN_NONE; } static PyObject *py_backend_list(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *ret = NULL; PyObject *string = NULL; int i, result; const char **backends = NULL; ret = PyList_New(0); if (ret == NULL) { return NULL; } backends = tevent_backend_list(NULL); if (backends == NULL) { PyErr_SetNone(PyExc_RuntimeError); goto err; } for (i = 0; backends[i]; i++) { string = PyUnicode_FromString(backends[i]); if (!string) { goto err; } result = PyList_Append(ret, string); if (result) { goto err; } Py_DECREF(string); string = NULL; } talloc_free(backends); return ret; err: Py_XDECREF(ret); Py_XDECREF(string); talloc_free(backends); return NULL; } static PyMethodDef tevent_methods[] = { { "register_backend", (PyCFunction)py_register_backend, METH_VARARGS, "register_backend(backend)" }, { "set_default_backend", (PyCFunction)py_set_default_backend, METH_VARARGS, "set_default_backend(backend)" }, { "backend_list", (PyCFunction)py_backend_list, METH_NOARGS, "backend_list() -> list" }, { NULL }, }; #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, .m_name = "_tevent", .m_doc = MODULE_DOC, .m_size = -1, .m_methods = tevent_methods, }; #endif PyObject * module_init(void); PyObject * module_init(void) { PyObject *m; if (PyType_Ready(&TeventContext_Type) < 0) return NULL; if (PyType_Ready(&TeventQueue_Type) < 0) return NULL; if (PyType_Ready(&TeventReq_Type) < 0) return NULL; if (PyType_Ready(&TeventSignal_Type) < 0) return NULL; if (PyType_Ready(&TeventTimer_Type) < 0) return NULL; if (PyType_Ready(&TeventFd_Type) < 0) return NULL; #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); #else m = Py_InitModule3("_tevent", tevent_methods, MODULE_DOC); #endif if (m == NULL) return NULL; Py_INCREF(&TeventContext_Type); PyModule_AddObject(m, "Context", (PyObject *)&TeventContext_Type); Py_INCREF(&TeventQueue_Type); PyModule_AddObject(m, "Queue", (PyObject *)&TeventQueue_Type); Py_INCREF(&TeventReq_Type); PyModule_AddObject(m, "Request", (PyObject *)&TeventReq_Type); Py_INCREF(&TeventSignal_Type); PyModule_AddObject(m, "Signal", (PyObject *)&TeventSignal_Type); Py_INCREF(&TeventTimer_Type); PyModule_AddObject(m, "Timer", (PyObject *)&TeventTimer_Type); Py_INCREF(&TeventFd_Type); PyModule_AddObject(m, "Fd", (PyObject *)&TeventFd_Type); PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit__tevent(void); PyMODINIT_FUNC PyInit__tevent(void) { return module_init(); } #else void init_tevent(void); void init_tevent(void) { module_init(); } #endif ldb-2.0.8/lib/tevent/test_req.c0000660000000000000000000001641713444661620016302 0ustar rootroot00000000000000/* * Unix SMB/CIFS implementation. * * testing of some tevent_req aspects * * Copyright (C) Volker Lendecke 2018 * * ** NOTE! The following LGPL license applies to the tevent * ** 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 . */ #include "includes.h" #include "tevent.h" #include "torture/torture.h" #include "torture/local/proto.h" #include "lib/util/tevent_unix.h" #include "lib/util/tevent_req_profile.h" #include "lib/util/time_basic.h" struct tevent_req_create_state { uint8_t val; }; static bool test_tevent_req_create(struct torture_context *tctx, const void *test_data) { struct tevent_req *req; struct tevent_req_create_state *state; req = tevent_req_create(tctx, &state, struct tevent_req_create_state); torture_assert_not_null(tctx, req, "tevent_req_create failed\n"); torture_assert_int_equal(tctx, state->val, 0, "state not initialized\n"); TALLOC_FREE(req); return true; } struct profile1_state { uint8_t dummy; }; static bool test_tevent_req_profile1(struct torture_context *tctx, const void *test_data) { struct tevent_req *req; struct profile1_state *state; const struct tevent_req_profile *p1; struct tevent_req_profile *p2; struct timeval start, stop; bool ok; int cmp; req = tevent_req_create(tctx, &state, struct profile1_state); torture_assert_not_null(tctx, req, "tevent_req_create failed\n"); p1 = tevent_req_get_profile(req); torture_assert(tctx, p1 == NULL, "profile not initialized to NULL\n"); ok = tevent_req_set_profile(req); torture_assert(tctx, ok, "set_profile failed\n"); tevent_req_done(req); p2 = tevent_req_move_profile(req, tctx); torture_assert_not_null(tctx, p2, "get_profile failed\n"); /* Demonstrate sure "p2" outlives req */ TALLOC_FREE(req); tevent_req_profile_get_start(p2, NULL, &start); tevent_req_profile_get_stop(p2, NULL, &stop); cmp = tevent_timeval_compare(&start, &stop); torture_assert(tctx, cmp <= 0, "stop before start\n"); TALLOC_FREE(p2); return true; } struct profile2_state { uint8_t dummy; }; static void profile2_done(struct tevent_req *subreq); static struct tevent_req *profile2_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev) { struct tevent_req *req, *subreq; struct profile2_state *state; bool ok; req = tevent_req_create(mem_ctx, &state, struct profile2_state); if (req == NULL) { return NULL; } ok = tevent_req_set_profile(req); if (!ok) { return tevent_req_post(req, ev); } subreq = tevent_wakeup_send( state, ev, tevent_timeval_current_ofs(0, 1)); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } tevent_req_set_callback(subreq, profile2_done, req); return req; } static void profile2_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); bool ok; ok = tevent_wakeup_recv(subreq); if (!ok) { tevent_req_oom(req); return; } tevent_req_done(req); } static int profile2_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct tevent_req_profile **profile) { int err; if (tevent_req_is_unix_error(req, &err)) { return err; } *profile = tevent_req_move_profile(req, mem_ctx); return 0; } static bool test_tevent_req_profile2(struct torture_context *tctx, const void *test_data) { struct tevent_context *ev; struct tevent_req *req; struct tevent_req_profile *p1 = NULL; struct tevent_req_profile *p2 = NULL; const char *str1, *str2; struct timeval tv1, tv2; pid_t pid1, pid2; enum tevent_req_state state1, state2; uint64_t err1, err2; char *printstring; ssize_t pack_len; int err; bool ok; ev = samba_tevent_context_init(tctx); torture_assert_not_null(tctx, ev, "samba_tevent_context_init failed\n"); req = profile2_send(tctx, ev); torture_assert_not_null(tctx, req, "profile2_send failed\n"); ok = tevent_req_poll_unix(req, ev, &err); torture_assert(tctx, ok, "tevent_req_poll_unix failed\n"); err = profile2_recv(req, tctx, &p1); torture_assert_int_equal(tctx, err, 0, "profile2_recv failed\n"); TALLOC_FREE(req); TALLOC_FREE(ev); printstring = tevent_req_profile_string(tctx, p1, 0, UINT_MAX); torture_assert_not_null( tctx, printstring, "tevent_req_profile_string failed\n"); printf("%s\n", printstring); pack_len = tevent_req_profile_pack(p1, NULL, 0); torture_assert(tctx, pack_len>0, "profile_pack failed\n"); { uint8_t buf[pack_len]; ssize_t unpack_len; tevent_req_profile_pack(p1, buf, sizeof(buf)); dump_data(10, buf, sizeof(buf)); unpack_len = tevent_req_profile_unpack( buf, pack_len, tctx, &p2); torture_assert_int_equal(tctx, pack_len, unpack_len, "profile_unpack failed\n"); } printstring = tevent_req_profile_string(tctx, p2, 0, UINT_MAX); torture_assert_not_null( tctx, printstring, "tevent_req_profile_string failed\n"); printf("%s\n", printstring); tevent_req_profile_get_name(p1, &str1); tevent_req_profile_get_name(p2, &str2); torture_assert_str_equal(tctx, str1, str2, "names differ\n"); tevent_req_profile_get_start(p1, &str1, &tv1); tevent_req_profile_get_start(p2, &str2, &tv2); torture_assert_str_equal(tctx, str1, str2, "start strings differ\n"); torture_assert(tctx, tevent_timeval_compare(&tv1, &tv2) == 0, "start times differ\n"); tevent_req_profile_get_stop(p1, &str1, &tv1); tevent_req_profile_get_stop(p2, &str2, &tv2); torture_assert_str_equal(tctx, str1, str2, "stop strings differ\n"); torture_assert(tctx, tevent_timeval_compare(&tv1, &tv2) == 0, "stop times differ\n"); tevent_req_profile_get_status(p1, &pid1, &state1, &err1); tevent_req_profile_get_status(p2, &pid2, &state2, &err2); torture_assert_int_equal(tctx, pid1, pid2, "pids differ\n"); torture_assert_int_equal(tctx, state1, state2, "states differ\n"); torture_assert_int_equal(tctx, err1, err2, "user errors differ\n"); str1 = tevent_req_profile_string(p1, p1, 0, UINT_MAX); torture_assert_not_null(tctx, str1, "profile_string failed\n"); str2 = tevent_req_profile_string(p2, p2, 0, UINT_MAX); torture_assert_not_null(tctx, str2, "profile_string failed\n"); torture_assert_str_equal(tctx, str1, str2, "result strings differ\n"); TALLOC_FREE(p1); TALLOC_FREE(p2); return true; } struct torture_suite *torture_local_tevent_req(TALLOC_CTX *mem_ctx) { struct torture_suite *suite; suite = torture_suite_create(mem_ctx, "tevent_req"); torture_suite_add_simple_tcase_const( suite, "create", test_tevent_req_create, NULL); torture_suite_add_simple_tcase_const( suite, "profile1", test_tevent_req_profile1, NULL); torture_suite_add_simple_tcase_const( suite, "profile2", test_tevent_req_profile2, NULL); return suite; } ldb-2.0.8/lib/tevent/testsuite.c0000660000000000000000000012750013573675413016511 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. testing of the events subsystem Copyright (C) Stefan Metzmacher 2006-2009 Copyright (C) Jeremy Allison 2013 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "includes.h" #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "system/filesys.h" #include "system/select.h" #include "system/network.h" #include "torture/torture.h" #include "torture/local/proto.h" #ifdef HAVE_PTHREAD #include "system/threads.h" #include #endif static int fde_count; static void do_read(int fd, void *buf, size_t count) { ssize_t ret; do { ret = read(fd, buf, count); } while (ret == -1 && errno == EINTR); } static void fde_handler_read(struct tevent_context *ev_ctx, struct tevent_fd *f, uint16_t flags, void *private_data) { int *fd = (int *)private_data; char c; #ifdef SA_SIGINFO kill(getpid(), SIGUSR1); #endif kill(getpid(), SIGALRM); do_read(fd[0], &c, 1); fde_count++; } static void do_write(int fd, void *buf, size_t count) { ssize_t ret; do { ret = write(fd, buf, count); } while (ret == -1 && errno == EINTR); } static void fde_handler_write(struct tevent_context *ev_ctx, struct tevent_fd *f, uint16_t flags, void *private_data) { int *fd = (int *)private_data; char c = 0; do_write(fd[1], &c, 1); } /* This will only fire if the fd's returned from pipe() are bi-directional. */ static void fde_handler_read_1(struct tevent_context *ev_ctx, struct tevent_fd *f, uint16_t flags, void *private_data) { int *fd = (int *)private_data; char c; #ifdef SA_SIGINFO kill(getpid(), SIGUSR1); #endif kill(getpid(), SIGALRM); do_read(fd[1], &c, 1); fde_count++; } /* This will only fire if the fd's returned from pipe() are bi-directional. */ static void fde_handler_write_1(struct tevent_context *ev_ctx, struct tevent_fd *f, uint16_t flags, void *private_data) { int *fd = (int *)private_data; char c = 0; do_write(fd[0], &c, 1); } static void finished_handler(struct tevent_context *ev_ctx, struct tevent_timer *te, struct timeval tval, void *private_data) { int *finished = (int *)private_data; (*finished) = 1; } static void count_handler(struct tevent_context *ev_ctx, struct tevent_signal *te, int signum, int count, void *info, void *private_data) { int *countp = (int *)private_data; (*countp) += count; } static bool test_event_context(struct torture_context *test, const void *test_data) { struct tevent_context *ev_ctx; int fd[2] = { -1, -1 }; const char *backend = (const char *)test_data; int alarm_count=0, info_count=0; struct tevent_fd *fde_read; struct tevent_fd *fde_read_1; struct tevent_fd *fde_write; struct tevent_fd *fde_write_1; #ifdef SA_RESTART struct tevent_signal *se1 = NULL; #endif #ifdef SA_RESETHAND struct tevent_signal *se2 = NULL; #endif #ifdef SA_SIGINFO struct tevent_signal *se3 = NULL; #endif int finished=0; struct timeval t; int ret; ev_ctx = tevent_context_init_byname(test, backend); if (ev_ctx == NULL) { torture_comment(test, "event backend '%s' not supported\n", backend); return true; } torture_comment(test, "backend '%s' - %s\n", backend, __FUNCTION__); /* reset globals */ fde_count = 0; /* create a pipe */ ret = pipe(fd); torture_assert_int_equal(test, ret, 0, "pipe failed"); fde_read = tevent_add_fd(ev_ctx, ev_ctx, fd[0], TEVENT_FD_READ, fde_handler_read, fd); fde_write_1 = tevent_add_fd(ev_ctx, ev_ctx, fd[0], TEVENT_FD_WRITE, fde_handler_write_1, fd); fde_write = tevent_add_fd(ev_ctx, ev_ctx, fd[1], TEVENT_FD_WRITE, fde_handler_write, fd); fde_read_1 = tevent_add_fd(ev_ctx, ev_ctx, fd[1], TEVENT_FD_READ, fde_handler_read_1, fd); tevent_fd_set_auto_close(fde_read); tevent_fd_set_auto_close(fde_write); tevent_add_timer(ev_ctx, ev_ctx, timeval_current_ofs(2,0), finished_handler, &finished); #ifdef SA_RESTART se1 = tevent_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count); torture_assert(test, se1 != NULL, "failed to setup se1"); #endif #ifdef SA_RESETHAND se2 = tevent_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count); torture_assert(test, se2 != NULL, "failed to setup se2"); #endif #ifdef SA_SIGINFO se3 = tevent_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count); torture_assert(test, se3 != NULL, "failed to setup se3"); #endif t = timeval_current(); while (!finished) { errno = 0; if (tevent_loop_once(ev_ctx) == -1) { TALLOC_FREE(ev_ctx); torture_fail(test, talloc_asprintf(test, "Failed event loop %s\n", strerror(errno))); return false; } } talloc_free(fde_read_1); talloc_free(fde_write_1); talloc_free(fde_read); talloc_free(fde_write); while (alarm_count < fde_count+1) { if (tevent_loop_once(ev_ctx) == -1) { break; } } torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t)); #ifdef SA_RESTART talloc_free(se1); #endif torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch"); #ifdef SA_RESETHAND /* * we do not call talloc_free(se2) * because it is already gone, * after triggering the event handler. */ #endif #ifdef SA_SIGINFO talloc_free(se3); torture_assert_int_equal(test, info_count, fde_count, "info count mismatch"); #endif talloc_free(ev_ctx); return true; } struct test_event_fd1_state { struct torture_context *tctx; const char *backend; struct tevent_context *ev; int sock[2]; struct tevent_timer *te; struct tevent_fd *fde0; struct tevent_fd *fde1; bool got_write; bool got_read; bool drain; bool drain_done; unsigned loop_count; bool finished; const char *error; }; static void test_event_fd1_fde_handler(struct tevent_context *ev_ctx, struct tevent_fd *fde, uint16_t flags, void *private_data) { struct test_event_fd1_state *state = (struct test_event_fd1_state *)private_data; if (state->drain_done) { state->finished = true; state->error = __location__; return; } if (state->drain) { ssize_t ret; uint8_t c = 0; if (!(flags & TEVENT_FD_READ)) { state->finished = true; state->error = __location__; return; } ret = read(state->sock[0], &c, 1); if (ret == 1) { return; } /* * end of test... */ tevent_fd_set_flags(fde, 0); state->drain_done = true; return; } if (!state->got_write) { uint8_t c = 0; if (flags != TEVENT_FD_WRITE) { state->finished = true; state->error = __location__; return; } state->got_write = true; /* * we write to the other socket... */ do_write(state->sock[1], &c, 1); TEVENT_FD_NOT_WRITEABLE(fde); TEVENT_FD_READABLE(fde); return; } if (!state->got_read) { if (flags != TEVENT_FD_READ) { state->finished = true; state->error = __location__; return; } state->got_read = true; TEVENT_FD_NOT_READABLE(fde); return; } state->finished = true; state->error = __location__; return; } static void test_event_fd1_finished(struct tevent_context *ev_ctx, struct tevent_timer *te, struct timeval tval, void *private_data) { struct test_event_fd1_state *state = (struct test_event_fd1_state *)private_data; if (state->drain_done) { state->finished = true; return; } if (!state->got_write) { state->finished = true; state->error = __location__; return; } if (!state->got_read) { state->finished = true; state->error = __location__; return; } state->loop_count++; if (state->loop_count > 3) { state->finished = true; state->error = __location__; return; } state->got_write = false; state->got_read = false; tevent_fd_set_flags(state->fde0, TEVENT_FD_WRITE); if (state->loop_count > 2) { state->drain = true; TALLOC_FREE(state->fde1); TEVENT_FD_READABLE(state->fde0); } state->te = tevent_add_timer(state->ev, state->ev, timeval_current_ofs(0,2000), test_event_fd1_finished, state); } 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; state.backend = (const char *)test_data; state.ev = tevent_context_init_byname(tctx, state.backend); if (state.ev == NULL) { torture_skip(tctx, talloc_asprintf(tctx, "event backend '%s' not supported\n", state.backend)); return true; } tevent_set_debug_stderr(state.ev); torture_comment(tctx, "backend '%s' - %s\n", state.backend, __FUNCTION__); /* * This tests the following: * * It monitors the state of state.sock[0] * with tevent_fd, but we never read/write on state.sock[0] * while state.sock[1] * is only used to write a few bytes. * * We have a loop: * - we wait only for TEVENT_FD_WRITE on state.sock[0] * - we write 1 byte to state.sock[1] * - we wait only for TEVENT_FD_READ on state.sock[0] * - we disable events on state.sock[0] * - the timer event restarts the loop * Then we close state.sock[1] * We have a loop: * - we wait for TEVENT_FD_READ/WRITE on state.sock[0] * - we try to read 1 byte * - if the read gets an error of returns 0 * we disable the event handler * - the timer finishes the test */ state.sock[0] = -1; state.sock[1] = -1; ret = socketpair(AF_UNIX, SOCK_STREAM, 0, state.sock); torture_assert(tctx, ret == 0, "socketpair() failed"); state.te = tevent_add_timer(state.ev, state.ev, timeval_current_ofs(0,1000), test_event_fd1_finished, &state); state.fde0 = tevent_add_fd(state.ev, state.ev, state.sock[0], TEVENT_FD_WRITE, test_event_fd1_fde_handler, &state); /* state.fde1 is only used to auto close */ state.fde1 = tevent_add_fd(state.ev, state.ev, state.sock[1], 0, test_event_fd1_fde_handler, &state); tevent_fd_set_auto_close(state.fde0); tevent_fd_set_auto_close(state.fde1); while (!state.finished) { errno = 0; if (tevent_loop_once(state.ev) == -1) { talloc_free(state.ev); torture_fail(tctx, talloc_asprintf(tctx, "Failed event loop %s\n", strerror(errno))); } } talloc_free(state.ev); torture_assert(tctx, state.error == NULL, talloc_asprintf(tctx, "%s", state.error)); return true; } struct test_event_fd2_state { struct torture_context *tctx; const char *backend; struct tevent_context *ev; struct tevent_timer *te; struct test_event_fd2_sock { struct test_event_fd2_state *state; int fd; struct tevent_fd *fde; size_t num_written; size_t num_read; bool got_full; } sock0, sock1; bool finished; const char *error; }; static void test_event_fd2_sock_handler(struct tevent_context *ev_ctx, struct tevent_fd *fde, uint16_t flags, void *private_data) { struct test_event_fd2_sock *cur_sock = (struct test_event_fd2_sock *)private_data; struct test_event_fd2_state *state = cur_sock->state; struct test_event_fd2_sock *oth_sock = NULL; uint8_t v = 0, c; ssize_t ret; if (cur_sock == &state->sock0) { oth_sock = &state->sock1; } else { oth_sock = &state->sock0; } if (oth_sock->num_written == 1) { if (flags != (TEVENT_FD_READ | TEVENT_FD_WRITE)) { state->finished = true; state->error = __location__; return; } } if (cur_sock->num_read == oth_sock->num_written) { state->finished = true; state->error = __location__; return; } if (!(flags & TEVENT_FD_READ)) { state->finished = true; state->error = __location__; return; } if (oth_sock->num_read >= PIPE_BUF) { /* * On Linux we become writable once we've read * one byte. On Solaris we only become writable * again once we've read 4096 bytes. PIPE_BUF * is probably a safe bet to test against. * * There should be room to write a byte again */ if (!(flags & TEVENT_FD_WRITE)) { state->finished = true; state->error = __location__; return; } } if ((flags & TEVENT_FD_WRITE) && !cur_sock->got_full) { v = (uint8_t)cur_sock->num_written; ret = write(cur_sock->fd, &v, 1); if (ret != 1) { state->finished = true; state->error = __location__; return; } cur_sock->num_written++; if (cur_sock->num_written > 0x80000000) { state->finished = true; state->error = __location__; return; } return; } if (!cur_sock->got_full) { cur_sock->got_full = true; if (!oth_sock->got_full) { /* * cur_sock is full, * lets wait for oth_sock * to be filled */ tevent_fd_set_flags(cur_sock->fde, 0); return; } /* * oth_sock waited for cur_sock, * lets restart it */ tevent_fd_set_flags(oth_sock->fde, TEVENT_FD_READ|TEVENT_FD_WRITE); } ret = read(cur_sock->fd, &v, 1); if (ret != 1) { state->finished = true; state->error = __location__; return; } c = (uint8_t)cur_sock->num_read; if (c != v) { state->finished = true; state->error = __location__; return; } cur_sock->num_read++; if (cur_sock->num_read < oth_sock->num_written) { /* there is more to read */ return; } /* * we read everything, we need to remove TEVENT_FD_WRITE * to avoid spinning */ TEVENT_FD_NOT_WRITEABLE(cur_sock->fde); if (oth_sock->num_read == cur_sock->num_written) { /* * both directions are finished */ state->finished = true; } return; } static void test_event_fd2_finished(struct tevent_context *ev_ctx, struct tevent_timer *te, struct timeval tval, void *private_data) { struct test_event_fd2_state *state = (struct test_event_fd2_state *)private_data; /* * this should never be triggered */ state->finished = true; state->error = __location__; } static bool test_event_fd2(struct torture_context *tctx, const void *test_data) { struct test_event_fd2_state state; int sock[2]; uint8_t c = 0; ZERO_STRUCT(state); state.tctx = tctx; state.backend = (const char *)test_data; state.ev = tevent_context_init_byname(tctx, state.backend); if (state.ev == NULL) { torture_skip(tctx, talloc_asprintf(tctx, "event backend '%s' not supported\n", state.backend)); return true; } tevent_set_debug_stderr(state.ev); torture_comment(tctx, "backend '%s' - %s\n", state.backend, __FUNCTION__); /* * This tests the following * * - We write 1 byte to each socket * - We wait for TEVENT_FD_READ/WRITE on both sockets * - When we get TEVENT_FD_WRITE we write 1 byte * until both socket buffers are full, which * means both sockets only get TEVENT_FD_READ. * - Then we read 1 byte until we have consumed * all bytes the other end has written. */ sock[0] = -1; sock[1] = -1; socketpair(AF_UNIX, SOCK_STREAM, 0, sock); /* * the timer should never expire */ state.te = tevent_add_timer(state.ev, state.ev, timeval_current_ofs(600, 0), test_event_fd2_finished, &state); state.sock0.state = &state; state.sock0.fd = sock[0]; state.sock0.fde = tevent_add_fd(state.ev, state.ev, state.sock0.fd, TEVENT_FD_READ | TEVENT_FD_WRITE, test_event_fd2_sock_handler, &state.sock0); state.sock1.state = &state; state.sock1.fd = sock[1]; state.sock1.fde = tevent_add_fd(state.ev, state.ev, state.sock1.fd, TEVENT_FD_READ | TEVENT_FD_WRITE, test_event_fd2_sock_handler, &state.sock1); tevent_fd_set_auto_close(state.sock0.fde); tevent_fd_set_auto_close(state.sock1.fde); do_write(state.sock0.fd, &c, 1); state.sock0.num_written++; do_write(state.sock1.fd, &c, 1); state.sock1.num_written++; while (!state.finished) { errno = 0; if (tevent_loop_once(state.ev) == -1) { talloc_free(state.ev); torture_fail(tctx, talloc_asprintf(tctx, "Failed event loop %s\n", strerror(errno))); } } talloc_free(state.ev); torture_assert(tctx, state.error == NULL, talloc_asprintf(tctx, "%s", state.error)); return true; } struct test_wrapper_state { struct torture_context *tctx; int num_events; int num_wrap_handlers; }; static bool test_wrapper_before_use(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; return true; } static void test_wrapper_after_use(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_before_fd_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_fd *fde, uint16_t flags, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_after_fd_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_fd *fde, uint16_t flags, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_before_timer_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_timer *te, struct timeval requested_time, struct timeval trigger_time, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_after_timer_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_timer *te, struct timeval requested_time, struct timeval trigger_time, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_before_immediate_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_immediate *im, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_after_immediate_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_immediate *im, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_before_signal_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_signal *se, int signum, int count, void *siginfo, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static void test_wrapper_after_signal_handler(struct tevent_context *wrap_ev, void *private_data, struct tevent_context *main_ev, struct tevent_signal *se, int signum, int count, void *siginfo, const char *handler_name, const char *location) { struct test_wrapper_state *state = talloc_get_type_abort(private_data, struct test_wrapper_state); torture_comment(state->tctx, "%s\n", __func__); state->num_wrap_handlers++; } static const struct tevent_wrapper_ops test_wrapper_ops = { .name = "test_wrapper", .before_use = test_wrapper_before_use, .after_use = test_wrapper_after_use, .before_fd_handler = test_wrapper_before_fd_handler, .after_fd_handler = test_wrapper_after_fd_handler, .before_timer_handler = test_wrapper_before_timer_handler, .after_timer_handler = test_wrapper_after_timer_handler, .before_immediate_handler = test_wrapper_before_immediate_handler, .after_immediate_handler = test_wrapper_after_immediate_handler, .before_signal_handler = test_wrapper_before_signal_handler, .after_signal_handler = test_wrapper_after_signal_handler, }; static void test_wrapper_timer_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct test_wrapper_state *state = (struct test_wrapper_state *)private_data; torture_comment(state->tctx, "timer handler\n"); state->num_events++; talloc_free(te); return; } static void test_wrapper_fd_handler(struct tevent_context *ev, struct tevent_fd *fde, unsigned short fd_flags, void *private_data) { struct test_wrapper_state *state = (struct test_wrapper_state *)private_data; torture_comment(state->tctx, "fd handler\n"); state->num_events++; talloc_free(fde); return; } static void test_wrapper_immediate_handler(struct tevent_context *ev, struct tevent_immediate *im, void *private_data) { struct test_wrapper_state *state = (struct test_wrapper_state *)private_data; state->num_events++; talloc_free(im); torture_comment(state->tctx, "immediate handler\n"); return; } static void test_wrapper_signal_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct test_wrapper_state *state = (struct test_wrapper_state *)private_data; torture_comment(state->tctx, "signal handler\n"); state->num_events++; talloc_free(se); return; } static bool test_wrapper(struct torture_context *tctx, const void *test_data) { struct test_wrapper_state *state = NULL; int sock[2] = { -1, -1}; uint8_t c = 0; const int num_events = 4; const char *backend = (const char *)test_data; struct tevent_context *ev = NULL; struct tevent_context *wrap_ev = NULL; struct tevent_fd *fde = NULL; struct tevent_timer *te = NULL; struct tevent_signal *se = NULL; struct tevent_immediate *im = NULL; int ret; bool ok = false; bool ret2; ev = tevent_context_init_byname(tctx, backend); if (ev == NULL) { torture_skip(tctx, talloc_asprintf(tctx, "event backend '%s' not supported\n", backend)); return true; } tevent_set_debug_stderr(ev); torture_comment(tctx, "tevent backend '%s'\n", backend); wrap_ev = tevent_context_wrapper_create( ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state); torture_assert_not_null_goto(tctx, wrap_ev, ok, done, "tevent_context_wrapper_create failed\n"); *state = (struct test_wrapper_state) { .tctx = tctx, }; ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n"); te = tevent_add_timer(wrap_ev, wrap_ev, timeval_current_ofs(0, 0), test_wrapper_timer_handler, state); torture_assert_not_null_goto(tctx, te, ok, done, "tevent_add_timer failed\n"); fde = tevent_add_fd(wrap_ev, wrap_ev, sock[1], TEVENT_FD_READ, test_wrapper_fd_handler, state); torture_assert_not_null_goto(tctx, fde, ok, done, "tevent_add_fd failed\n"); im = tevent_create_immediate(wrap_ev); torture_assert_not_null_goto(tctx, im, ok, done, "tevent_create_immediate failed\n"); se = tevent_add_signal(wrap_ev, wrap_ev, SIGUSR1, 0, test_wrapper_signal_handler, state); torture_assert_not_null_goto(tctx, se, ok, done, "tevent_add_signal failed\n"); do_write(sock[0], &c, 1); kill(getpid(), SIGUSR1); tevent_schedule_immediate(im, wrap_ev, test_wrapper_immediate_handler, state); ret2 = tevent_context_push_use(wrap_ev); torture_assert_goto(tctx, ret2, ok, done, "tevent_context_push_use(wrap_ev) failed\n"); ret2 = tevent_context_push_use(ev); torture_assert_goto(tctx, ret2, ok, pop_use, "tevent_context_push_use(ev) failed\n"); tevent_context_pop_use(ev); tevent_context_pop_use(wrap_ev); ret = tevent_loop_wait(ev); torture_assert_int_equal_goto(tctx, ret, 0, ok, done, "tevent_loop_wait failed\n"); torture_comment(tctx, "Num events: %d\n", state->num_events); torture_comment(tctx, "Num wrap handlers: %d\n", state->num_wrap_handlers); torture_assert_int_equal_goto(tctx, state->num_events, num_events, ok, done, "Wrong event count\n"); torture_assert_int_equal_goto(tctx, state->num_wrap_handlers, num_events*2+2, ok, done, "Wrong wrapper count\n"); ok = true; done: TALLOC_FREE(wrap_ev); TALLOC_FREE(ev); if (sock[0] != -1) { close(sock[0]); } if (sock[1] != -1) { close(sock[1]); } return ok; pop_use: tevent_context_pop_use(wrap_ev); goto done; } static void test_free_wrapper_signal_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct torture_context *tctx = talloc_get_type_abort(private_data, struct torture_context); torture_comment(tctx, "signal handler\n"); talloc_free(se); /* * signal handlers have highest priority in tevent, so this signal * handler will always be started before the other handlers * below. Freeing the (wrapper) event context here tests that the * wrapper implementation correclty handles the wrapper ev going away * with pending events. */ talloc_free(ev); return; } static void test_free_wrapper_fd_handler(struct tevent_context *ev, struct tevent_fd *fde, unsigned short fd_flags, void *private_data) { /* * This should never be called as * test_free_wrapper_signal_handler() * already destroyed the wrapper tevent_context. */ abort(); } static void test_free_wrapper_immediate_handler(struct tevent_context *ev, struct tevent_immediate *im, void *private_data) { /* * This should never be called as * test_free_wrapper_signal_handler() * already destroyed the wrapper tevent_context. */ abort(); } static void test_free_wrapper_timer_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { /* * This should never be called as * test_free_wrapper_signal_handler() * already destroyed the wrapper tevent_context. */ abort(); } static bool test_free_wrapper(struct torture_context *tctx, const void *test_data) { struct test_wrapper_state *state = NULL; int sock[2] = { -1, -1}; uint8_t c = 0; const char *backend = (const char *)test_data; TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev = NULL; struct tevent_context *wrap_ev = NULL; struct tevent_fd *fde = NULL; struct tevent_timer *te = NULL; struct tevent_signal *se = NULL; struct tevent_immediate *im = NULL; int ret; bool ok = false; ev = tevent_context_init_byname(frame, backend); if (ev == NULL) { torture_skip(tctx, talloc_asprintf(tctx, "event backend '%s' not supported\n", backend)); return true; } tevent_set_debug_stderr(ev); torture_comment(tctx, "tevent backend '%s'\n", backend); wrap_ev = tevent_context_wrapper_create( ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state); torture_assert_not_null_goto(tctx, wrap_ev, ok, done, "tevent_context_wrapper_create failed\n"); *state = (struct test_wrapper_state) { .tctx = tctx, }; ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n"); fde = tevent_add_fd(wrap_ev, frame, sock[1], TEVENT_FD_READ, test_free_wrapper_fd_handler, NULL); torture_assert_not_null_goto(tctx, fde, ok, done, "tevent_add_fd failed\n"); te = tevent_add_timer(wrap_ev, frame, timeval_current_ofs(0, 0), test_free_wrapper_timer_handler, NULL); torture_assert_not_null_goto(tctx, te, ok, done, "tevent_add_timer failed\n"); im = tevent_create_immediate(frame); torture_assert_not_null_goto(tctx, im, ok, done, "tevent_create_immediate failed\n"); se = tevent_add_signal(wrap_ev, frame, SIGUSR1, 0, test_free_wrapper_signal_handler, tctx); torture_assert_not_null_goto(tctx, se, ok, done, "tevent_add_signal failed\n"); do_write(sock[0], &c, 1); kill(getpid(), SIGUSR1); tevent_schedule_immediate(im, wrap_ev, test_free_wrapper_immediate_handler, NULL); ret = tevent_loop_wait(ev); torture_assert_goto(tctx, ret == 0, ok, done, "tevent_loop_wait failed\n"); ok = true; done: TALLOC_FREE(frame); if (sock[0] != -1) { close(sock[0]); } if (sock[1] != -1) { close(sock[1]); } return ok; } #ifdef HAVE_PTHREAD static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER; static bool do_shutdown = false; static void test_event_threaded_lock(void) { int ret; ret = pthread_mutex_lock(&threaded_mutex); assert(ret == 0); } static void test_event_threaded_unlock(void) { int ret; ret = pthread_mutex_unlock(&threaded_mutex); assert(ret == 0); } static void test_event_threaded_trace(enum tevent_trace_point point, void *private_data) { switch (point) { case TEVENT_TRACE_BEFORE_WAIT: test_event_threaded_unlock(); break; case TEVENT_TRACE_AFTER_WAIT: test_event_threaded_lock(); break; case TEVENT_TRACE_BEFORE_LOOP_ONCE: case TEVENT_TRACE_AFTER_LOOP_ONCE: break; } } static void test_event_threaded_timer(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { return; } static void *test_event_poll_thread(void *private_data) { struct tevent_context *ev = (struct tevent_context *)private_data; test_event_threaded_lock(); while (true) { int ret; ret = tevent_loop_once(ev); assert(ret == 0); if (do_shutdown) { test_event_threaded_unlock(); return NULL; } } } static void test_event_threaded_read_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { int *pfd = (int *)private_data; char c; ssize_t nread; if ((flags & TEVENT_FD_READ) == 0) { return; } do { nread = read(*pfd, &c, 1); } while ((nread == -1) && (errno == EINTR)); assert(nread == 1); } static bool test_event_context_threaded(struct torture_context *test, const void *test_data) { struct tevent_context *ev; struct tevent_timer *te; struct tevent_fd *fde; pthread_t poll_thread; int fds[2]; int ret; char c = 0; ev = tevent_context_init_byname(test, "poll_mt"); torture_assert(test, ev != NULL, "poll_mt not supported"); tevent_set_trace_callback(ev, test_event_threaded_trace, NULL); te = tevent_add_timer(ev, ev, timeval_current_ofs(5, 0), test_event_threaded_timer, NULL); torture_assert(test, te != NULL, "Could not add timer"); ret = pthread_create(&poll_thread, NULL, test_event_poll_thread, ev); torture_assert(test, ret == 0, "Could not create poll thread"); ret = pipe(fds); torture_assert(test, ret == 0, "Could not create pipe"); poll(NULL, 0, 100); test_event_threaded_lock(); fde = tevent_add_fd(ev, ev, fds[0], TEVENT_FD_READ, test_event_threaded_read_handler, &fds[0]); torture_assert(test, fde != NULL, "Could not add fd event"); test_event_threaded_unlock(); poll(NULL, 0, 100); do_write(fds[1], &c, 1); poll(NULL, 0, 100); test_event_threaded_lock(); do_shutdown = true; test_event_threaded_unlock(); do_write(fds[1], &c, 1); ret = pthread_join(poll_thread, NULL); torture_assert(test, ret == 0, "pthread_join failed"); return true; } #define NUM_TEVENT_THREADS 100 /* Ugly, but needed for torture_comment... */ static struct torture_context *thread_test_ctx; static pthread_t thread_map[NUM_TEVENT_THREADS]; static unsigned thread_counter; /* Called in master thread context */ static void callback_nowait(struct tevent_context *ev, struct tevent_immediate *im, void *private_ptr) { pthread_t *thread_id_ptr = talloc_get_type_abort(private_ptr, pthread_t); unsigned i; for (i = 0; i < NUM_TEVENT_THREADS; i++) { if (pthread_equal(*thread_id_ptr, thread_map[i])) { break; } } torture_comment(thread_test_ctx, "Callback %u from thread %u\n", thread_counter, i); thread_counter++; } /* Blast the master tevent_context with a callback, no waiting. */ static void *thread_fn_nowait(void *private_ptr) { struct tevent_thread_proxy *master_tp = talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); struct tevent_immediate *im; pthread_t *thread_id_ptr; im = tevent_create_immediate(NULL); if (im == NULL) { return NULL; } thread_id_ptr = talloc(NULL, pthread_t); if (thread_id_ptr == NULL) { return NULL; } *thread_id_ptr = pthread_self(); tevent_thread_proxy_schedule(master_tp, &im, callback_nowait, &thread_id_ptr); return NULL; } static void timeout_fn(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *p) { thread_counter = NUM_TEVENT_THREADS * 10; } static bool test_multi_tevent_threaded(struct torture_context *test, const void *test_data) { unsigned i; struct tevent_context *master_ev; struct tevent_thread_proxy *tp; talloc_disable_null_tracking(); /* Ugly global stuff. */ thread_test_ctx = test; thread_counter = 0; master_ev = tevent_context_init(NULL); if (master_ev == NULL) { return false; } tevent_set_debug_stderr(master_ev); tp = tevent_thread_proxy_create(master_ev); if (tp == NULL) { torture_fail(test, talloc_asprintf(test, "tevent_thread_proxy_create failed\n")); talloc_free(master_ev); return false; } for (i = 0; i < NUM_TEVENT_THREADS; i++) { int ret = pthread_create(&thread_map[i], NULL, thread_fn_nowait, tp); if (ret != 0) { torture_fail(test, talloc_asprintf(test, "Failed to create thread %i, %d\n", i, ret)); return false; } } /* Ensure we don't wait more than 10 seconds. */ tevent_add_timer(master_ev, master_ev, timeval_current_ofs(10,0), timeout_fn, NULL); while (thread_counter < NUM_TEVENT_THREADS) { int ret = tevent_loop_once(master_ev); torture_assert(test, ret == 0, "tevent_loop_once failed"); } torture_assert(test, thread_counter == NUM_TEVENT_THREADS, "thread_counter fail\n"); talloc_free(master_ev); return true; } struct reply_state { struct tevent_thread_proxy *reply_tp; pthread_t thread_id; int *p_finished; }; static void thread_timeout_fn(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *p) { int *p_finished = (int *)p; *p_finished = 2; } /* Called in child-thread context */ static void thread_callback(struct tevent_context *ev, struct tevent_immediate *im, void *private_ptr) { struct reply_state *rsp = talloc_get_type_abort(private_ptr, struct reply_state); talloc_steal(ev, rsp); *rsp->p_finished = 1; } /* Called in master thread context */ static void master_callback(struct tevent_context *ev, struct tevent_immediate *im, void *private_ptr) { struct reply_state *rsp = talloc_get_type_abort(private_ptr, struct reply_state); unsigned i; talloc_steal(ev, rsp); for (i = 0; i < NUM_TEVENT_THREADS; i++) { if (pthread_equal(rsp->thread_id, thread_map[i])) { break; } } torture_comment(thread_test_ctx, "Callback %u from thread %u\n", thread_counter, i); /* Now reply to the thread ! */ tevent_thread_proxy_schedule(rsp->reply_tp, &im, thread_callback, &rsp); thread_counter++; } static void *thread_fn_1(void *private_ptr) { struct tevent_thread_proxy *master_tp = talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); struct tevent_thread_proxy *tp; struct tevent_immediate *im; struct tevent_context *ev; struct reply_state *rsp; int finished = 0; int ret; ev = tevent_context_init(NULL); if (ev == NULL) { return NULL; } tp = tevent_thread_proxy_create(ev); if (tp == NULL) { talloc_free(ev); return NULL; } im = tevent_create_immediate(ev); if (im == NULL) { talloc_free(ev); return NULL; } rsp = talloc(ev, struct reply_state); if (rsp == NULL) { talloc_free(ev); return NULL; } rsp->thread_id = pthread_self(); rsp->reply_tp = tp; rsp->p_finished = &finished; /* Introduce a little randomness into the mix.. */ usleep(random() % 7000); tevent_thread_proxy_schedule(master_tp, &im, master_callback, &rsp); /* Ensure we don't wait more than 10 seconds. */ tevent_add_timer(ev, ev, timeval_current_ofs(10,0), thread_timeout_fn, &finished); while (finished == 0) { ret = tevent_loop_once(ev); assert(ret == 0); } if (finished > 1) { /* Timeout ! */ abort(); } /* * NB. We should talloc_free(ev) here, but if we do * we currently get hit by helgrind Fix #323432 * "When calling pthread_cond_destroy or pthread_mutex_destroy * with initializers as argument Helgrind (incorrectly) reports errors." * * http://valgrind.10908.n7.nabble.com/Helgrind-3-9-0-false-positive- * with-pthread-mutex-destroy-td47757.html * * Helgrind doesn't understand that the request/reply * messages provide synchronization between the lock/unlock * in tevent_thread_proxy_schedule(), and the pthread_destroy() * when the struct tevent_thread_proxy object is talloc_free'd. * * As a work-around for now return ev for the parent thread to free. */ return ev; } static bool test_multi_tevent_threaded_1(struct torture_context *test, const void *test_data) { unsigned i; struct tevent_context *master_ev; struct tevent_thread_proxy *master_tp; int ret; talloc_disable_null_tracking(); /* Ugly global stuff. */ thread_test_ctx = test; thread_counter = 0; master_ev = tevent_context_init(NULL); if (master_ev == NULL) { return false; } tevent_set_debug_stderr(master_ev); master_tp = tevent_thread_proxy_create(master_ev); if (master_tp == NULL) { torture_fail(test, talloc_asprintf(test, "tevent_thread_proxy_create failed\n")); talloc_free(master_ev); return false; } for (i = 0; i < NUM_TEVENT_THREADS; i++) { ret = pthread_create(&thread_map[i], NULL, thread_fn_1, master_tp); if (ret != 0) { torture_fail(test, talloc_asprintf(test, "Failed to create thread %i, %d\n", i, ret)); return false; } } while (thread_counter < NUM_TEVENT_THREADS) { ret = tevent_loop_once(master_ev); torture_assert(test, ret == 0, "tevent_loop_once failed"); } /* Wait for all the threads to finish - join 'em. */ for (i = 0; i < NUM_TEVENT_THREADS; i++) { void *retval; ret = pthread_join(thread_map[i], &retval); torture_assert(test, ret == 0, "pthread_join failed"); /* Free the child thread event context. */ talloc_free(retval); } talloc_free(master_ev); return true; } struct threaded_test_2 { struct tevent_threaded_context *tctx; struct tevent_immediate *im; pthread_t thread_id; }; static void master_callback_2(struct tevent_context *ev, struct tevent_immediate *im, void *private_data); static void *thread_fn_2(void *private_data) { struct threaded_test_2 *state = private_data; state->thread_id = pthread_self(); usleep(random() % 7000); tevent_threaded_schedule_immediate( state->tctx, state->im, master_callback_2, state); return NULL; } static void master_callback_2(struct tevent_context *ev, struct tevent_immediate *im, void *private_data) { struct threaded_test_2 *state = private_data; int i; for (i = 0; i < NUM_TEVENT_THREADS; i++) { if (pthread_equal(state->thread_id, thread_map[i])) { break; } } torture_comment(thread_test_ctx, "Callback_2 %u from thread %u\n", thread_counter, i); thread_counter++; } static bool test_multi_tevent_threaded_2(struct torture_context *test, const void *test_data) { unsigned i; struct tevent_context *ev; struct tevent_threaded_context *tctx; int ret; thread_test_ctx = test; thread_counter = 0; ev = tevent_context_init(test); torture_assert(test, ev != NULL, "tevent_context_init failed"); /* * tevent_re_initialise used to have a bug where it did not * re-initialise the thread support after taking it * down. Exercise that code path. */ ret = tevent_re_initialise(ev); torture_assert(test, ret == 0, "tevent_re_initialise failed"); tctx = tevent_threaded_context_create(ev, ev); torture_assert(test, tctx != NULL, "tevent_threaded_context_create failed"); for (i=0; itctx = tctx; state->im = tevent_create_immediate(state); torture_assert(test, state->im != NULL, "tevent_create_immediate failed"); ret = pthread_create(&thread_map[i], NULL, thread_fn_2, state); torture_assert(test, ret == 0, "pthread_create failed"); } while (thread_counter < NUM_TEVENT_THREADS) { ret = tevent_loop_once(ev); torture_assert(test, ret == 0, "tevent_loop_once failed"); } /* Wait for all the threads to finish - join 'em. */ for (i = 0; i < NUM_TEVENT_THREADS; i++) { void *retval; ret = pthread_join(thread_map[i], &retval); torture_assert(test, ret == 0, "pthread_join failed"); /* Free the child thread event context. */ } talloc_free(tctx); talloc_free(ev); return true; } #endif struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "event"); const char **list = tevent_backend_list(suite); int i; for (i=0;list && list[i];i++) { struct torture_suite *backend_suite; backend_suite = torture_suite_create(mem_ctx, list[i]); torture_suite_add_simple_tcase_const(backend_suite, "context", test_event_context, (const void *)list[i]); torture_suite_add_simple_tcase_const(backend_suite, "fd1", test_event_fd1, (const void *)list[i]); torture_suite_add_simple_tcase_const(backend_suite, "fd2", test_event_fd2, (const void *)list[i]); torture_suite_add_simple_tcase_const(backend_suite, "wrapper", test_wrapper, (const void *)list[i]); torture_suite_add_simple_tcase_const(backend_suite, "free_wrapper", test_free_wrapper, (const void *)list[i]); torture_suite_add_suite(suite, backend_suite); } #ifdef HAVE_PTHREAD torture_suite_add_simple_tcase_const(suite, "threaded_poll_mt", test_event_context_threaded, NULL); torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded", test_multi_tevent_threaded, NULL); torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded_1", test_multi_tevent_threaded_1, NULL); torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded_2", test_multi_tevent_threaded_2, NULL); #endif return suite; } ldb-2.0.8/lib/tevent/tevent.c0000660000000000000000000005550213444661620015757 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. main select loop and event handling Copyright (C) Andrew Tridgell 2003 Copyright (C) Stefan Metzmacher 2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ /* PLEASE READ THIS BEFORE MODIFYING! This module is a general abstraction for the main select loop and event handling. Do not ever put any localised hacks in here, instead register one of the possible event types and implement that event somewhere else. There are 2 types of event handling that are handled in this module: 1) a file descriptor becoming readable or writeable. This is mostly used for network sockets, but can be used for any type of file descriptor. You may only register one handler for each file descriptor/io combination or you will get unpredictable results (this means that you can have a handler for read events, and a separate handler for write events, but not two handlers that are both handling read events) 2) a timed event. You can register an event that happens at a specific time. You can register as many of these as you like. They are single shot - add a new timed event in the event handler to get another event. To setup a set of events you first need to create a event_context structure using the function tevent_context_init(); This returns a 'struct tevent_context' that you use in all subsequent calls. After that you can add/remove events that you are interested in using tevent_add_*() and talloc_free() Finally, you call tevent_loop_wait_once() to block waiting for one of the events to occor or tevent_loop_wait() which will loop forever. */ #include "replace.h" #include "system/filesys.h" #ifdef HAVE_PTHREAD #include "system/threads.h" #endif #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" #ifdef HAVE_EVENTFD #include #endif struct tevent_ops_list { struct tevent_ops_list *next, *prev; const char *name; const struct tevent_ops *ops; }; /* list of registered event backends */ static struct tevent_ops_list *tevent_backends = NULL; static char *tevent_default_backend = NULL; /* register an events backend */ bool tevent_register_backend(const char *name, const struct tevent_ops *ops) { struct tevent_ops_list *e; for (e = tevent_backends; e != NULL; e = e->next) { if (0 == strcmp(e->name, name)) { /* already registered, skip it */ return true; } } e = talloc(NULL, struct tevent_ops_list); if (e == NULL) return false; e->name = name; e->ops = ops; DLIST_ADD(tevent_backends, e); return true; } /* set the default event backend */ void tevent_set_default_backend(const char *backend) { talloc_free(tevent_default_backend); tevent_default_backend = talloc_strdup(NULL, backend); } /* initialise backends if not already done */ static void tevent_backend_init(void) { static bool done; if (done) { return; } done = true; tevent_poll_init(); tevent_poll_mt_init(); #if defined(HAVE_EPOLL) tevent_epoll_init(); #elif defined(HAVE_SOLARIS_PORTS) tevent_port_init(); #endif tevent_standard_init(); } _PRIVATE_ const struct tevent_ops *tevent_find_ops_byname(const char *name) { struct tevent_ops_list *e; tevent_backend_init(); if (name == NULL) { name = tevent_default_backend; } if (name == NULL) { name = "standard"; } for (e = tevent_backends; e != NULL; e = e->next) { if (0 == strcmp(e->name, name)) { return e->ops; } } return NULL; } /* list available backends */ const char **tevent_backend_list(TALLOC_CTX *mem_ctx) { const char **list = NULL; struct tevent_ops_list *e; tevent_backend_init(); for (e=tevent_backends;e;e=e->next) { list = ev_str_list_add(list, e->name); } talloc_steal(mem_ctx, list); return list; } static void tevent_common_wakeup_fini(struct tevent_context *ev); #ifdef HAVE_PTHREAD static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER; static struct tevent_context *tevent_contexts = NULL; static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT; static void tevent_atfork_prepare(void) { struct tevent_context *ev; int ret; ret = pthread_mutex_lock(&tevent_contexts_mutex); if (ret != 0) { abort(); } for (ev = tevent_contexts; ev != NULL; ev = ev->next) { struct tevent_threaded_context *tctx; for (tctx = ev->threaded_contexts; tctx != NULL; tctx = tctx->next) { ret = pthread_mutex_lock(&tctx->event_ctx_mutex); if (ret != 0) { tevent_abort(ev, "pthread_mutex_lock failed"); } } ret = pthread_mutex_lock(&ev->scheduled_mutex); if (ret != 0) { tevent_abort(ev, "pthread_mutex_lock failed"); } } } static void tevent_atfork_parent(void) { struct tevent_context *ev; int ret; for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; ev = DLIST_PREV(ev)) { struct tevent_threaded_context *tctx; ret = pthread_mutex_unlock(&ev->scheduled_mutex); if (ret != 0) { tevent_abort(ev, "pthread_mutex_unlock failed"); } for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; tctx = DLIST_PREV(tctx)) { ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { tevent_abort( ev, "pthread_mutex_unlock failed"); } } } ret = pthread_mutex_unlock(&tevent_contexts_mutex); if (ret != 0) { abort(); } } static void tevent_atfork_child(void) { struct tevent_context *ev; int ret; for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; ev = DLIST_PREV(ev)) { struct tevent_threaded_context *tctx; for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; tctx = DLIST_PREV(tctx)) { tctx->event_ctx = NULL; ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { tevent_abort( ev, "pthread_mutex_unlock failed"); } } ev->threaded_contexts = NULL; ret = pthread_mutex_unlock(&ev->scheduled_mutex); if (ret != 0) { tevent_abort(ev, "pthread_mutex_unlock failed"); } } ret = pthread_mutex_unlock(&tevent_contexts_mutex); if (ret != 0) { abort(); } } static void tevent_prep_atfork(void) { int ret; ret = pthread_atfork(tevent_atfork_prepare, tevent_atfork_parent, tevent_atfork_child); if (ret != 0) { abort(); } } #endif int tevent_common_context_destructor(struct tevent_context *ev) { struct tevent_fd *fd, *fn; struct tevent_timer *te, *tn; struct tevent_immediate *ie, *in; struct tevent_signal *se, *sn; struct tevent_wrapper_glue *gl, *gn; #ifdef HAVE_PTHREAD int ret; #endif if (ev->wrapper.glue != NULL) { tevent_abort(ev, "tevent_common_context_destructor() active on wrapper"); } #ifdef HAVE_PTHREAD ret = pthread_mutex_lock(&tevent_contexts_mutex); if (ret != 0) { abort(); } DLIST_REMOVE(tevent_contexts, ev); ret = pthread_mutex_unlock(&tevent_contexts_mutex); if (ret != 0) { abort(); } while (ev->threaded_contexts != NULL) { struct tevent_threaded_context *tctx = ev->threaded_contexts; ret = pthread_mutex_lock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } /* * Indicate to the thread that the tevent_context is * gone. The counterpart of this is in * _tevent_threaded_schedule_immediate, there we read * this under the threaded_context's mutex. */ tctx->event_ctx = NULL; ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } DLIST_REMOVE(ev->threaded_contexts, tctx); } ret = pthread_mutex_destroy(&ev->scheduled_mutex); if (ret != 0) { abort(); } #endif for (gl = ev->wrapper.list; gl; gl = gn) { gn = gl->next; gl->main_ev = NULL; DLIST_REMOVE(ev->wrapper.list, gl); } tevent_common_wakeup_fini(ev); for (fd = ev->fd_events; fd; fd = fn) { fn = fd->next; fd->wrapper = NULL; fd->event_ctx = NULL; DLIST_REMOVE(ev->fd_events, fd); } ev->last_zero_timer = NULL; for (te = ev->timer_events; te; te = tn) { tn = te->next; te->wrapper = NULL; te->event_ctx = NULL; DLIST_REMOVE(ev->timer_events, te); } for (ie = ev->immediate_events; ie; ie = in) { in = ie->next; ie->wrapper = NULL; ie->event_ctx = NULL; ie->cancel_fn = NULL; DLIST_REMOVE(ev->immediate_events, ie); } for (se = ev->signal_events; se; se = sn) { sn = se->next; se->wrapper = NULL; se->event_ctx = NULL; DLIST_REMOVE(ev->signal_events, se); /* * This is important, Otherwise signals * are handled twice in child. eg, SIGHUP. * one added in parent, and another one in * the child. -- BoYang */ tevent_cleanup_pending_signal_handlers(se); } /* removing nesting hook or we get an abort when nesting is * not allowed. -- SSS * Note that we need to leave the allowed flag at its current * value, otherwise the use in tevent_re_initialise() will * leave the event context with allowed forced to false, which * will break users that expect nesting to be allowed */ ev->nesting.level = 0; ev->nesting.hook_fn = NULL; ev->nesting.hook_private = NULL; return 0; } static int tevent_common_context_constructor(struct tevent_context *ev) { int ret; #ifdef HAVE_PTHREAD ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork); if (ret != 0) { return ret; } ret = pthread_mutex_init(&ev->scheduled_mutex, NULL); if (ret != 0) { return ret; } ret = pthread_mutex_lock(&tevent_contexts_mutex); if (ret != 0) { pthread_mutex_destroy(&ev->scheduled_mutex); return ret; } DLIST_ADD(tevent_contexts, ev); ret = pthread_mutex_unlock(&tevent_contexts_mutex); if (ret != 0) { abort(); } #endif talloc_set_destructor(ev, tevent_common_context_destructor); return 0; } void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason) { void *parent_ptr = talloc_parent(ptr); size_t parent_blocks = talloc_total_blocks(parent_ptr); if (parent_ptr != NULL && parent_blocks == 0) { /* * This is an implicit talloc free, as we still have a parent * but it's already being destroyed. Note that * talloc_total_blocks(ptr) also just returns 0 if a * talloc_free(ptr) is still in progress of freeing all * children. */ return; } tevent_abort(NULL, reason); } /* create a event_context structure for a specific implemementation. This must be the first events call, and all subsequent calls pass this event_context as the first element. Event handlers also receive this as their first argument. This function is for allowing third-party-applications to hook in gluecode to their own event loop code, so that they can make async usage of our client libs NOTE: use tevent_context_init() inside of samba! */ struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx, const struct tevent_ops *ops, void *additional_data) { struct tevent_context *ev; int ret; ev = talloc_zero(mem_ctx, struct tevent_context); if (!ev) return NULL; ret = tevent_common_context_constructor(ev); if (ret != 0) { talloc_free(ev); return NULL; } ev->ops = ops; ev->additional_data = additional_data; ret = ev->ops->context_init(ev); if (ret != 0) { talloc_free(ev); return NULL; } return ev; } /* create a event_context structure. This must be the first events call, and all subsequent calls pass this event_context as the first element. Event handlers also receive this as their first argument. */ struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name) { const struct tevent_ops *ops; ops = tevent_find_ops_byname(name); if (ops == NULL) { return NULL; } return tevent_context_init_ops(mem_ctx, ops, NULL); } /* create a event_context structure. This must be the first events call, and all subsequent calls pass this event_context as the first element. Event handlers also receive this as their first argument. */ struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx) { return tevent_context_init_byname(mem_ctx, NULL); } /* add a fd based event return NULL on failure (memory allocation error) */ struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location) { return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data, handler_name, location); } /* set a close function on the fd event */ void tevent_fd_set_close_fn(struct tevent_fd *fde, tevent_fd_close_fn_t close_fn) { if (!fde) return; if (!fde->event_ctx) return; fde->event_ctx->ops->set_fd_close_fn(fde, close_fn); } static void tevent_fd_auto_close_fn(struct tevent_context *ev, struct tevent_fd *fde, int fd, void *private_data) { close(fd); } void tevent_fd_set_auto_close(struct tevent_fd *fde) { tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn); } /* return the fd event flags */ uint16_t tevent_fd_get_flags(struct tevent_fd *fde) { if (!fde) return 0; if (!fde->event_ctx) return 0; return fde->event_ctx->ops->get_fd_flags(fde); } /* set the fd event flags */ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags) { if (!fde) return; if (!fde->event_ctx) return; fde->event_ctx->ops->set_fd_flags(fde, flags); } bool tevent_signal_support(struct tevent_context *ev) { if (ev->ops->add_signal) { return true; } return false; } static void (*tevent_abort_fn)(const char *reason); void tevent_set_abort_fn(void (*abort_fn)(const char *reason)) { tevent_abort_fn = abort_fn; } void tevent_abort(struct tevent_context *ev, const char *reason) { if (ev != NULL) { tevent_debug(ev, TEVENT_DEBUG_FATAL, "abort: %s\n", reason); } if (!tevent_abort_fn) { abort(); } tevent_abort_fn(reason); } /* add a timer event return NULL on failure */ struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location) { return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data, handler_name, location); } /* allocate an immediate event return NULL on failure (memory allocation error) */ struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx, const char *location) { struct tevent_immediate *im; im = talloc(mem_ctx, struct tevent_immediate); if (im == NULL) return NULL; *im = (struct tevent_immediate) { .create_location = location }; return im; } /* schedule an immediate event */ void _tevent_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ev, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location) { ev->ops->schedule_immediate(im, ev, handler, private_data, handler_name, location); } /* add a signal event sa_flags are flags to sigaction(2) return NULL on failure */ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data, const char *handler_name, const char *location) { return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, handler_name, location); } void tevent_loop_allow_nesting(struct tevent_context *ev) { if (ev->wrapper.glue != NULL) { tevent_abort(ev, "tevent_loop_allow_nesting() on wrapper"); return; } if (ev->wrapper.list != NULL) { tevent_abort(ev, "tevent_loop_allow_nesting() with wrapper"); return; } ev->nesting.allowed = true; } void tevent_loop_set_nesting_hook(struct tevent_context *ev, tevent_nesting_hook hook, void *private_data) { if (ev->nesting.hook_fn && (ev->nesting.hook_fn != hook || ev->nesting.hook_private != private_data)) { /* the way the nesting hook code is currently written we cannot support two different nesting hooks at the same time. */ tevent_abort(ev, "tevent: Violation of nesting hook rules\n"); } ev->nesting.hook_fn = hook; ev->nesting.hook_private = private_data; } static void tevent_abort_nesting(struct tevent_context *ev, const char *location) { const char *reason; reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s", location); if (!reason) { reason = "tevent_loop_once() nesting"; } tevent_abort(ev, reason); } /* do a single event loop using the events defined in ev */ int _tevent_loop_once(struct tevent_context *ev, const char *location) { int ret; void *nesting_stack_ptr = NULL; ev->nesting.level++; if (ev->nesting.level > 1) { if (!ev->nesting.allowed) { tevent_abort_nesting(ev, location); errno = ELOOP; return -1; } } if (ev->nesting.level > 0) { if (ev->nesting.hook_fn) { int ret2; ret2 = ev->nesting.hook_fn(ev, ev->nesting.hook_private, ev->nesting.level, true, (void *)&nesting_stack_ptr, location); if (ret2 != 0) { ret = ret2; goto done; } } } tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE); ret = ev->ops->loop_once(ev, location); tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE); if (ev->nesting.level > 0) { if (ev->nesting.hook_fn) { int ret2; ret2 = ev->nesting.hook_fn(ev, ev->nesting.hook_private, ev->nesting.level, false, (void *)&nesting_stack_ptr, location); if (ret2 != 0) { ret = ret2; goto done; } } } done: ev->nesting.level--; return ret; } /* this is a performance optimization for the samba4 nested event loop problems */ int _tevent_loop_until(struct tevent_context *ev, bool (*finished)(void *private_data), void *private_data, const char *location) { int ret = 0; void *nesting_stack_ptr = NULL; ev->nesting.level++; if (ev->nesting.level > 1) { if (!ev->nesting.allowed) { tevent_abort_nesting(ev, location); errno = ELOOP; return -1; } } if (ev->nesting.level > 0) { if (ev->nesting.hook_fn) { int ret2; ret2 = ev->nesting.hook_fn(ev, ev->nesting.hook_private, ev->nesting.level, true, (void *)&nesting_stack_ptr, location); if (ret2 != 0) { ret = ret2; goto done; } } } while (!finished(private_data)) { tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE); ret = ev->ops->loop_once(ev, location); tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE); if (ret != 0) { break; } } if (ev->nesting.level > 0) { if (ev->nesting.hook_fn) { int ret2; ret2 = ev->nesting.hook_fn(ev, ev->nesting.hook_private, ev->nesting.level, false, (void *)&nesting_stack_ptr, location); if (ret2 != 0) { ret = ret2; goto done; } } } done: ev->nesting.level--; return ret; } bool tevent_common_have_events(struct tevent_context *ev) { if (ev->fd_events != NULL) { if (ev->fd_events != ev->wakeup_fde) { return true; } if (ev->fd_events->next != NULL) { return true; } /* * At this point we just have the wakeup pipe event as * the only fd_event. That one does not count as a * regular event, so look at the other event types. */ } return ((ev->timer_events != NULL) || (ev->immediate_events != NULL) || (ev->signal_events != NULL)); } /* return on failure or (with 0) if all fd events are removed */ int tevent_common_loop_wait(struct tevent_context *ev, const char *location) { /* * loop as long as we have events pending */ while (tevent_common_have_events(ev)) { int ret; ret = _tevent_loop_once(ev, location); if (ret != 0) { tevent_debug(ev, TEVENT_DEBUG_FATAL, "_tevent_loop_once() failed: %d - %s\n", ret, strerror(errno)); return ret; } } tevent_debug(ev, TEVENT_DEBUG_WARNING, "tevent_common_loop_wait() out of events\n"); return 0; } /* return on failure or (with 0) if all fd events are removed */ int _tevent_loop_wait(struct tevent_context *ev, const char *location) { return ev->ops->loop_wait(ev, location); } /* re-initialise a tevent context. This leaves you with the same event context, but all events are wiped and the structure is re-initialised. This is most useful after a fork() zero is returned on success, non-zero on failure */ int tevent_re_initialise(struct tevent_context *ev) { tevent_common_context_destructor(ev); tevent_common_context_constructor(ev); return ev->ops->context_init(ev); } static void wakeup_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *_private) { ssize_t ret; do { /* * This is the boilerplate for eventfd, but it works * for pipes too. And as we don't care about the data * we read, we're fine. */ uint64_t val; ret = read(fde->fd, &val, sizeof(val)); } while (ret == -1 && errno == EINTR); } /* * Initialize the wakeup pipe and pipe fde */ int tevent_common_wakeup_init(struct tevent_context *ev) { int ret, read_fd; if (ev->wakeup_fde != NULL) { return 0; } #ifdef HAVE_EVENTFD ret = eventfd(0, EFD_NONBLOCK); if (ret == -1) { return errno; } read_fd = ev->wakeup_fd = ret; #else { int pipe_fds[2]; ret = pipe(pipe_fds); if (ret == -1) { return errno; } ev->wakeup_fd = pipe_fds[1]; ev->wakeup_read_fd = pipe_fds[0]; ev_set_blocking(ev->wakeup_fd, false); ev_set_blocking(ev->wakeup_read_fd, false); read_fd = ev->wakeup_read_fd; } #endif ev->wakeup_fde = tevent_add_fd(ev, ev, read_fd, TEVENT_FD_READ, wakeup_pipe_handler, NULL); if (ev->wakeup_fde == NULL) { close(ev->wakeup_fd); #ifndef HAVE_EVENTFD close(ev->wakeup_read_fd); #endif return ENOMEM; } return 0; } int tevent_common_wakeup_fd(int fd) { ssize_t ret; do { #ifdef HAVE_EVENTFD uint64_t val = 1; ret = write(fd, &val, sizeof(val)); #else char c = '\0'; ret = write(fd, &c, 1); #endif } while ((ret == -1) && (errno == EINTR)); return 0; } int tevent_common_wakeup(struct tevent_context *ev) { if (ev->wakeup_fde == NULL) { return ENOTCONN; } return tevent_common_wakeup_fd(ev->wakeup_fd); } static void tevent_common_wakeup_fini(struct tevent_context *ev) { if (ev->wakeup_fde == NULL) { return; } TALLOC_FREE(ev->wakeup_fde); close(ev->wakeup_fd); #ifndef HAVE_EVENTFD close(ev->wakeup_read_fd); #endif } ldb-2.0.8/lib/tevent/tevent.h0000660000000000000000000023167313573675413016001 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. generalised event loop handling Copyright (C) Andrew Tridgell 2005 Copyright (C) Stefan Metzmacher 2005-2009 Copyright (C) Volker Lendecke 2008 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #ifndef __TEVENT_H__ #define __TEVENT_H__ #include #include #include #include struct tevent_context; struct tevent_ops; struct tevent_fd; struct tevent_timer; struct tevent_immediate; struct tevent_signal; struct tevent_thread_proxy; struct tevent_threaded_context; /** * @defgroup tevent The tevent API * * The tevent low-level API * * This API provides the public interface to manage events in the tevent * mainloop. Functions are provided for managing low-level events such * as timer events, fd events and signal handling. * * @{ */ /* event handler types */ /** * Called when a file descriptor monitored by tevent has * data to be read or written on it. */ typedef void (*tevent_fd_handler_t)(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data); /** * Called when tevent is ceasing the monitoring of a file descriptor. */ typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev, struct tevent_fd *fde, int fd, void *private_data); /** * Called when a tevent timer has fired. */ typedef void (*tevent_timer_handler_t)(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data); /** * Called when a tevent immediate event is invoked. */ typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx, struct tevent_immediate *im, void *private_data); /** * Called after tevent detects the specified signal. */ typedef void (*tevent_signal_handler_t)(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data); /** * @brief Create a event_context structure. * * This must be the first events call, and all subsequent calls pass this * event_context as the first element. Event handlers also receive this as * their first argument. * * @param[in] mem_ctx The memory context to use. * * @return An allocated tevent context, NULL on error. * * @see tevent_context_init() */ struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx); /** * @brief Create a event_context structure and select a specific backend. * * This must be the first events call, and all subsequent calls pass this * event_context as the first element. Event handlers also receive this as * their first argument. * * @param[in] mem_ctx The memory context to use. * * @param[in] name The name of the backend to use. * * @return An allocated tevent context, NULL on error. */ struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); /** * @brief Create a custom event context * * @param[in] mem_ctx The memory context to use. * @param[in] ops The function pointer table of the backend. * @param[in] additional_data The additional/private data to this instance * * @return An allocated tevent context, NULL on error. * */ struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx, const struct tevent_ops *ops, void *additional_data); /** * @brief List available backends. * * @param[in] mem_ctx The memory context to use. * * @return A string vector with a terminating NULL element, NULL * on error. */ const char **tevent_backend_list(TALLOC_CTX *mem_ctx); /** * @brief Set the default tevent backend. * * @param[in] backend The name of the backend to set. */ void tevent_set_default_backend(const char *backend); #ifdef DOXYGEN /** * @brief Add a file descriptor based event. * * @param[in] ev The event context to work on. * * @param[in] mem_ctx The talloc memory context to use. * * @param[in] fd The file descriptor to base the event on. * * @param[in] flags #TEVENT_FD_READ or #TEVENT_FD_WRITE * * @param[in] handler The callback handler for the event. * * @param[in] private_data The private data passed to the callback handler. * * @return The file descriptor based event, NULL on error. * * @note To cancel the monitoring of a file descriptor, call talloc_free() * on the object returned by this function. * * @note The caller should avoid closing the file descriptor before * calling talloc_free()! Otherwise the behaviour is undefined which * might result in crashes. See https://bugzilla.samba.org/show_bug.cgi?id=11141 * for an example. */ struct tevent_fd *tevent_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data); #else struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location); #define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \ #handler, __location__) #endif #ifdef DOXYGEN /** * @brief Add a timed event * * @param[in] ev The event context to work on. * * @param[in] mem_ctx The talloc memory context to use. * * @param[in] next_event Timeval specifying the absolute time to fire this * event. This is not an offset. * * @param[in] handler The callback handler for the event. * * @param[in] private_data The private data passed to the callback handler. * * @return The newly-created timer event, or NULL on error. * * @note To cancel a timer event before it fires, call talloc_free() on the * event returned from this function. This event is automatically * talloc_free()-ed after its event handler files, if it hasn't been freed yet. * * @note Unlike some mainloops, tevent timers are one-time events. To set up * a recurring event, it is necessary to call tevent_add_timer() again during * the handler processing. * * @note Due to the internal mainloop processing, a timer set to run * immediately will do so after any other pending timers fire, but before * any further file descriptor or signal handling events fire. Callers should * not rely on this behavior! */ struct tevent_timer *tevent_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data); #else struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location); #define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \ _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \ #handler, __location__) #endif /** * @brief Set the time a tevent_timer fires * * @param[in] te The timer event to reset * * @param[in] next_event Timeval specifying the absolute time to fire this * event. This is not an offset. */ void tevent_update_timer(struct tevent_timer *te, struct timeval next_event); #ifdef DOXYGEN /** * Initialize an immediate event object * * This object can be used to trigger an event to occur immediately after * returning from the current event (before any other event occurs) * * @param[in] mem_ctx The talloc memory context to use as the parent * * @return An empty tevent_immediate object. Use tevent_schedule_immediate * to populate and use it. * * @note Available as of tevent 0.9.8 */ struct tevent_immediate *tevent_create_immediate(TALLOC_CTX *mem_ctx); #else struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx, const char *location); #define tevent_create_immediate(mem_ctx) \ _tevent_create_immediate(mem_ctx, __location__) #endif #ifdef DOXYGEN /** * Schedule an event for immediate execution. This event will occur * immediately after returning from the current event (before any other * event occurs) * * @param[in] im The tevent_immediate object to populate and use * @param[in] ctx The tevent_context to run this event * @param[in] handler The event handler to run when this event fires * @param[in] private_data Data to pass to the event handler */ void tevent_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ctx, tevent_immediate_handler_t handler, void *private_data); #else void _tevent_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ctx, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location); #define tevent_schedule_immediate(im, ctx, handler, private_data) \ _tevent_schedule_immediate(im, ctx, handler, private_data, \ #handler, __location__); #endif #ifdef DOXYGEN /** * @brief Add a tevent signal handler * * tevent_add_signal() creates a new event for handling a signal the next * time through the mainloop. It implements a very simple traditional signal * handler whose only purpose is to add the handler event into the mainloop. * * @param[in] ev The event context to work on. * * @param[in] mem_ctx The talloc memory context to use. * * @param[in] signum The signal to trap * * @param[in] handler The callback handler for the signal. * * @param[in] sa_flags sigaction flags for this signal handler. * * @param[in] private_data The private data passed to the callback handler. * * @return The newly-created signal handler event, or NULL on error. * * @note To cancel a signal handler, call talloc_free() on the event returned * from this function. * * @see tevent_num_signals, tevent_sa_info_queue_count */ struct tevent_signal *tevent_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data); #else struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data, const char *handler_name, const char *location); #define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \ #handler, __location__) #endif /** * @brief the number of supported signals * * This returns value of the configure time TEVENT_NUM_SIGNALS constant. * * The 'signum' argument of tevent_add_signal() must be less than * TEVENT_NUM_SIGNALS. * * @see tevent_add_signal */ size_t tevent_num_signals(void); /** * @brief the number of pending realtime signals * * This returns value of TEVENT_SA_INFO_QUEUE_COUNT. * * The tevent internals remember the last TEVENT_SA_INFO_QUEUE_COUNT * siginfo_t structures for SA_SIGINFO signals. If the system generates * more some signals get lost. * * @see tevent_add_signal */ size_t tevent_sa_info_queue_count(void); #ifdef DOXYGEN /** * @brief Pass a single time through the mainloop * * This will process any appropriate signal, immediate, fd and timer events * * @param[in] ev The event context to process * * @return Zero on success, nonzero if an internal error occurred */ int tevent_loop_once(struct tevent_context *ev); #else int _tevent_loop_once(struct tevent_context *ev, const char *location); #define tevent_loop_once(ev) \ _tevent_loop_once(ev, __location__) #endif #ifdef DOXYGEN /** * @brief Run the mainloop * * The mainloop will run until there are no events remaining to be processed * * @param[in] ev The event context to process * * @return Zero if all events have been processed. Nonzero if an internal * error occurred. */ int tevent_loop_wait(struct tevent_context *ev); #else int _tevent_loop_wait(struct tevent_context *ev, const char *location); #define tevent_loop_wait(ev) \ _tevent_loop_wait(ev, __location__) #endif /** * Assign a function to run when a tevent_fd is freed * * This function is a destructor for the tevent_fd. It does not automatically * close the file descriptor. If this is the desired behavior, then it must be * performed by the close_fn. * * @param[in] fde File descriptor event on which to set the destructor * @param[in] close_fn Destructor to execute when fde is freed * * @note That the close_fn() on tevent_fd is *NOT* wrapped on contexts * created by tevent_context_wrapper_create()! * * @see tevent_fd_set_close_fn * @see tevent_context_wrapper_create */ void tevent_fd_set_close_fn(struct tevent_fd *fde, tevent_fd_close_fn_t close_fn); /** * Automatically close the file descriptor when the tevent_fd is freed * * This function calls close(fd) internally. * * @param[in] fde File descriptor event to auto-close * * @see tevent_fd_set_close_fn */ void tevent_fd_set_auto_close(struct tevent_fd *fde); /** * Return the flags set on this file descriptor event * * @param[in] fde File descriptor event to query * * @return The flags set on the event. See #TEVENT_FD_READ and * #TEVENT_FD_WRITE */ uint16_t tevent_fd_get_flags(struct tevent_fd *fde); /** * Set flags on a file descriptor event * * @param[in] fde File descriptor event to set * @param[in] flags Flags to set on the event. See #TEVENT_FD_READ and * #TEVENT_FD_WRITE */ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags); /** * Query whether tevent supports signal handling * * @param[in] ev An initialized tevent context * * @return True if this platform and tevent context support signal handling */ bool tevent_signal_support(struct tevent_context *ev); void tevent_set_abort_fn(void (*abort_fn)(const char *reason)); /* bits for file descriptor event flags */ /** * Monitor a file descriptor for data to be read */ #define TEVENT_FD_READ 1 /** * Monitor a file descriptor for writeability */ #define TEVENT_FD_WRITE 2 /** * Convenience function for declaring a tevent_fd writable */ #define TEVENT_FD_WRITEABLE(fde) \ tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE) /** * Convenience function for declaring a tevent_fd readable */ #define TEVENT_FD_READABLE(fde) \ tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ) /** * Convenience function for declaring a tevent_fd non-writable */ #define TEVENT_FD_NOT_WRITEABLE(fde) \ tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE) /** * Convenience function for declaring a tevent_fd non-readable */ #define TEVENT_FD_NOT_READABLE(fde) \ tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ) /** * Debug level of tevent */ enum tevent_debug_level { TEVENT_DEBUG_FATAL, TEVENT_DEBUG_ERROR, TEVENT_DEBUG_WARNING, TEVENT_DEBUG_TRACE }; /** * @brief The tevent debug callbac. * * @param[in] context The memory context to use. * * @param[in] level The debug level. * * @param[in] fmt The format string. * * @param[in] ap The arguments for the format string. */ typedef void (*tevent_debug_fn)(void *context, enum tevent_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); /** * Set destination for tevent debug messages * * @param[in] ev Event context to debug * @param[in] debug Function to handle output printing * @param[in] context The context to pass to the debug function. * * @return Always returns 0 as of version 0.9.8 * * @note Default is to emit no debug messages */ int tevent_set_debug(struct tevent_context *ev, tevent_debug_fn debug, void *context); /** * Designate stderr for debug message output * * @param[in] ev Event context to debug * * @note This function will only output TEVENT_DEBUG_FATAL, TEVENT_DEBUG_ERROR * and TEVENT_DEBUG_WARNING messages. For TEVENT_DEBUG_TRACE, please define a * function for tevent_set_debug() */ int tevent_set_debug_stderr(struct tevent_context *ev); enum tevent_trace_point { /** * Corresponds to a trace point just before waiting */ TEVENT_TRACE_BEFORE_WAIT, /** * Corresponds to a trace point just after waiting */ TEVENT_TRACE_AFTER_WAIT, #define TEVENT_HAS_LOOP_ONCE_TRACE_POINTS 1 /** * Corresponds to a trace point just before calling * the loop_once() backend function. */ TEVENT_TRACE_BEFORE_LOOP_ONCE, /** * Corresponds to a trace point right after the * loop_once() backend function has returned. */ TEVENT_TRACE_AFTER_LOOP_ONCE, }; typedef void (*tevent_trace_callback_t)(enum tevent_trace_point, void *private_data); /** * Register a callback to be called at certain trace points * * @param[in] ev Event context * @param[in] cb Trace callback * @param[in] private_data Data to be passed to callback * * @note The callback will be called at trace points defined by * tevent_trace_point. Call with NULL to reset. */ void tevent_set_trace_callback(struct tevent_context *ev, tevent_trace_callback_t cb, void *private_data); /** * Retrieve the current trace callback * * @param[in] ev Event context * @param[out] cb Registered trace callback * @param[out] private_data Registered data to be passed to callback * * @note This can be used to allow one component that wants to * register a callback to respect the callback that another component * has already registered. */ void tevent_get_trace_callback(struct tevent_context *ev, tevent_trace_callback_t *cb, void *private_data); /** * @} */ /** * @defgroup tevent_request The tevent request functions. * @ingroup tevent * * A tevent_req represents an asynchronous computation. * * The tevent_req group of API calls is the recommended way of * programming async computations within tevent. In particular the * file descriptor (tevent_add_fd) and timer (tevent_add_timed) events * are considered too low-level to be used in larger computations. To * read and write from and to sockets, Samba provides two calls on top * of tevent_add_fd: tstream_read_packet_send/recv and tstream_writev_send/recv. * These requests are much easier to compose than the low-level event * handlers called from tevent_add_fd. * * A lot of the simplicity tevent_req has brought to the notoriously * hairy async programming came via a set of conventions that every * async computation programmed should follow. One central piece of * these conventions is the naming of routines and variables. * * Every async computation needs a name (sensibly called "computation" * down from here). From this name quite a few naming conventions are * derived. * * Every computation that requires local state needs a * @code * struct computation_state { * int local_var; * }; * @endcode * Even if no local variables are required, such a state struct should * be created containing a dummy variable. Quite a few helper * functions and macros (for example tevent_req_create()) assume such * a state struct. * * An async computation is started by a computation_send * function. When it is finished, its result can be received by a * computation_recv function. For an example how to set up an async * computation, see the code example in the documentation for * tevent_req_create() and tevent_req_post(). The prototypes for _send * and _recv functions should follow some conventions: * * @code * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, * struct tevent_req *ev, * ... further args); * int computation_recv(struct tevent_req *req, ... further output args); * @endcode * * The "int" result of computation_recv() depends on the result the * sync version of the function would have, "int" is just an example * here. * * Another important piece of the conventions is that the program flow * is interrupted as little as possible. Because a blocking * sub-computation requires that the flow needs to continue in a * separate function that is the logical sequel of some computation, * it should lexically follow sending off the blocking * sub-computation. Setting the callback function via * tevent_req_set_callback() requires referencing a function lexically * below the call to tevent_req_set_callback(), forward declarations * are required. A lot of the async computations thus begin with a * sequence of declarations such as * * @code * static void computation_step1_done(struct tevent_req *subreq); * static void computation_step2_done(struct tevent_req *subreq); * static void computation_step3_done(struct tevent_req *subreq); * @endcode * * It really helps readability a lot to do these forward declarations, * because the lexically sequential program flow makes the async * computations almost as clear to read as a normal, sync program * flow. * * It is up to the user of the async computation to talloc_free it * after it has finished. If an async computation should be aborted, * the tevent_req structure can be talloc_free'ed. After it has * finished, it should talloc_free'ed by the API user. * * tevent_req variable naming conventions: * * The name of the variable pointing to the tevent_req structure * returned by a _send() function SHOULD be named differently between * implementation and caller. * * From the point of view of the implementation (of the _send() and * _recv() functions) the variable returned by tevent_req_create() is * always called @em req. * * While the caller of the _send() function should use @em subreq to * hold the result. * * @see tevent_req_create() * @see tevent_req_fn() * * @{ */ /** * An async request moves from TEVENT_REQ_INIT to * TEVENT_REQ_IN_PROGRESS. All other states are valid after a request * has finished. */ enum tevent_req_state { /** * We are creating the request */ TEVENT_REQ_INIT, /** * We are waiting the request to complete */ TEVENT_REQ_IN_PROGRESS, /** * The request is finished successfully */ TEVENT_REQ_DONE, /** * A user error has occurred. The user error has been * indicated by tevent_req_error(), it can be retrieved via * tevent_req_is_error(). */ TEVENT_REQ_USER_ERROR, /** * Request timed out after the timeout set by tevent_req_set_endtime. */ TEVENT_REQ_TIMED_OUT, /** * An internal allocation has failed, or tevent_req_nomem has * been given a NULL pointer as the first argument. */ TEVENT_REQ_NO_MEMORY, /** * The request has been received by the caller. No further * action is valid. */ TEVENT_REQ_RECEIVED }; /** * @brief An async request */ struct tevent_req; /** * @brief A tevent request callback function. * * @param[in] subreq The tevent async request which executed this callback. */ typedef void (*tevent_req_fn)(struct tevent_req *subreq); /** * @brief Set an async request callback. * * See the documentation of tevent_req_post() for an example how this * is supposed to be used. * * @param[in] req The async request to set the callback. * * @param[in] fn The callback function to set. * * @param[in] pvt A pointer to private data to pass to the async request * callback. */ void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt); #ifdef DOXYGEN /** * @brief Get the private data cast to the given type for a callback from * a tevent request structure. * * @code * static void computation_done(struct tevent_req *subreq) { * struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); * struct computation_state *state = tevent_req_data(req, struct computation_state); * .... more things, eventually maybe call tevent_req_done(req); * } * @endcode * * @param[in] req The structure to get the callback data from. * * @param[in] type The type of the private callback data to get. * * @return The type casted private data set NULL if not set. */ void *tevent_req_callback_data(struct tevent_req *req, #type); #else void *_tevent_req_callback_data(struct tevent_req *req); #define tevent_req_callback_data(_req, _type) \ talloc_get_type_abort(_tevent_req_callback_data(_req), _type) #endif #ifdef DOXYGEN /** * @brief Get the private data for a callback from a tevent request structure. * * @param[in] req The structure to get the callback data from. * * @return The private data or NULL if not set. */ void *tevent_req_callback_data_void(struct tevent_req *req); #else #define tevent_req_callback_data_void(_req) \ _tevent_req_callback_data(_req) #endif #ifdef DOXYGEN /** * @brief Get the private data from a tevent request structure. * * When the tevent_req has been created by tevent_req_create, the * result of tevent_req_data() is the state variable created by * tevent_req_create() as a child of the req. * * @param[in] req The structure to get the private data from. * * @param[in] type The type of the private data * * @return The private data or NULL if not set. */ void *tevent_req_data(struct tevent_req *req, #type); #else void *_tevent_req_data(struct tevent_req *req); #define tevent_req_data(_req, _type) \ talloc_get_type_abort(_tevent_req_data(_req), _type) #endif /** * @brief The print function which can be set for a tevent async request. * * @param[in] req The tevent async request. * * @param[in] ctx A talloc memory context which can be uses to allocate * memory. * * @return An allocated string buffer to print. * * Example: * @code * static char *my_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) * { * struct my_data *data = tevent_req_data(req, struct my_data); * char *result; * * result = tevent_req_default_print(mem_ctx, req); * if (result == NULL) { * return NULL; * } * * return talloc_asprintf_append_buffer(result, "foo=%d, bar=%d", * data->foo, data->bar); * } * @endcode */ typedef char *(*tevent_req_print_fn)(struct tevent_req *req, TALLOC_CTX *ctx); /** * @brief This function sets a print function for the given request. * * This function can be used to setup a print function for the given request. * This will be triggered if the tevent_req_print() function was * called on the given request. * * @param[in] req The request to use. * * @param[in] fn A pointer to the print function * * @note This function should only be used for debugging. */ void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn); /** * @brief The default print function for creating debug messages. * * The function should not be used by users of the async API, * but custom print function can use it and append custom text * to the string. * * @param[in] req The request to be printed. * * @param[in] mem_ctx The memory context for the result. * * @return Text representation of request. * */ char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); /** * @brief Print an tevent_req structure in debug messages. * * This function should be used by callers of the async API. * * @param[in] mem_ctx The memory context for the result. * * @param[in] req The request to be printed. * * @return Text representation of request. */ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); /** * @brief A typedef for a cancel function for a tevent request. * * @param[in] req The tevent request calling this function. * * @return True if the request could be canceled, false if not. */ typedef bool (*tevent_req_cancel_fn)(struct tevent_req *req); /** * @brief This function sets a cancel function for the given tevent request. * * This function can be used to setup a cancel function for the given request. * This will be triggered if the tevent_req_cancel() function was * called on the given request. * * @param[in] req The request to use. * * @param[in] fn A pointer to the cancel function. */ void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn); #ifdef DOXYGEN /** * @brief Try to cancel the given tevent request. * * This function can be used to cancel the given request. * * It is only possible to cancel a request when the implementation * has registered a cancel function via the tevent_req_set_cancel_fn(). * * @param[in] req The request to use. * * @return This function returns true if the request is * cancelable, otherwise false is returned. * * @note Even if the function returns true, the caller need to wait * for the function to complete normally. * Only the _recv() function of the given request indicates * if the request was really canceled. */ bool tevent_req_cancel(struct tevent_req *req); #else bool _tevent_req_cancel(struct tevent_req *req, const char *location); #define tevent_req_cancel(req) \ _tevent_req_cancel(req, __location__) #endif /** * @brief A typedef for a cleanup function for a tevent request. * * @param[in] req The tevent request calling this function. * * @param[in] req_state The current tevent_req_state. * */ typedef void (*tevent_req_cleanup_fn)(struct tevent_req *req, enum tevent_req_state req_state); /** * @brief This function sets a cleanup function for the given tevent request. * * This function can be used to setup a cleanup function for the given request. * This will be triggered when the tevent_req_done() or tevent_req_error() * function was called, before notifying the callers callback function, * and also before scheduling the deferred trigger. * * This might be useful if more than one tevent_req belong together * and need to finish both requests at the same time. * * The cleanup function is able to call tevent_req_done() or tevent_req_error() * recursively, the cleanup function is only triggered the first time. * * The cleanup function is also called by tevent_req_received() * (possibly triggered from tevent_req_destructor()) before destroying * the private data of the tevent_req. * * @param[in] req The request to use. * * @param[in] fn A pointer to the cancel function. */ void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn); #ifdef DOXYGEN /** * @brief Create an async tevent request. * * The new async request will be initialized in state TEVENT_REQ_IN_PROGRESS. * * @code * struct tevent_req *req; * struct computation_state *state; * req = tevent_req_create(mem_ctx, &state, struct computation_state); * @endcode * * Tevent_req_create() allocates and zeros the state variable as a talloc * child of its result. The state variable should be used as the talloc * parent for all temporary variables that are allocated during the async * computation. This way, when the user of the async computation frees * the request, the state as a talloc child will be free'd along with * all the temporary variables hanging off the state. * * @param[in] mem_ctx The memory context for the result. * @param[in] pstate Pointer to the private request state. * @param[in] type The name of the request. * * @return A new async request. NULL on error. */ struct tevent_req *tevent_req_create(TALLOC_CTX *mem_ctx, void **pstate, #type); #else struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, void *pstate, size_t state_size, const char *type, const char *location); #define tevent_req_create(_mem_ctx, _pstate, _type) \ _tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \ #_type, __location__) #endif /** * @brief Set a timeout for an async request. On failure, "req" is already * set to state TEVENT_REQ_NO_MEMORY. * * @param[in] req The request to set the timeout for. * * @param[in] ev The event context to use for the timer. * * @param[in] endtime The endtime of the request. * * @return True if succeeded, false if not. */ bool tevent_req_set_endtime(struct tevent_req *req, struct tevent_context *ev, struct timeval endtime); /** * @brief Reset the timer set by tevent_req_set_endtime. * * @param[in] req The request to reset the timeout for */ void tevent_req_reset_endtime(struct tevent_req *req); #ifdef DOXYGEN /** * @brief Call the notify callback of the given tevent request manually. * * @param[in] req The tevent request to call the notify function from. * * @see tevent_req_set_callback() */ void tevent_req_notify_callback(struct tevent_req *req); #else void _tevent_req_notify_callback(struct tevent_req *req, const char *location); #define tevent_req_notify_callback(req) \ _tevent_req_notify_callback(req, __location__) #endif #ifdef DOXYGEN /** * @brief An async request has successfully finished. * * This function is to be used by implementors of async requests. When a * request is successfully finished, this function calls the user's completion * function. * * @param[in] req The finished request. */ void tevent_req_done(struct tevent_req *req); #else void _tevent_req_done(struct tevent_req *req, const char *location); #define tevent_req_done(req) \ _tevent_req_done(req, __location__) #endif #ifdef DOXYGEN /** * @brief An async request has seen an error. * * This function is to be used by implementors of async requests. When a * request can not successfully completed, the implementation should call this * function with the appropriate status code. * * If error is 0 the function returns false and does nothing more. * * @param[in] req The request with an error. * * @param[in] error The error code. * * @return On success true is returned, false if error is 0. * * @code * int error = first_function(); * if (tevent_req_error(req, error)) { * return; * } * * error = second_function(); * if (tevent_req_error(req, error)) { * return; * } * * tevent_req_done(req); * return; * @endcode */ bool tevent_req_error(struct tevent_req *req, uint64_t error); #else bool _tevent_req_error(struct tevent_req *req, uint64_t error, const char *location); #define tevent_req_error(req, error) \ _tevent_req_error(req, error, __location__) #endif #ifdef DOXYGEN /** * @brief Helper function for nomem check. * * Convenience helper to easily check alloc failure within a callback * implementing the next step of an async request. * * @param[in] p The pointer to be checked. * * @param[in] req The request being processed. * * @code * p = talloc(mem_ctx, bla); * if (tevent_req_nomem(p, req)) { * return; * } * @endcode */ bool tevent_req_nomem(const void *p, struct tevent_req *req); #else bool _tevent_req_nomem(const void *p, struct tevent_req *req, const char *location); #define tevent_req_nomem(p, req) \ _tevent_req_nomem(p, req, __location__) #endif #ifdef DOXYGEN /** * @brief Indicate out of memory to a request * * @param[in] req The request being processed. */ void tevent_req_oom(struct tevent_req *req); #else void _tevent_req_oom(struct tevent_req *req, const char *location); #define tevent_req_oom(req) \ _tevent_req_oom(req, __location__) #endif /** * @brief Finish a request before the caller had a chance to set the callback. * * An implementation of an async request might find that it can either finish * the request without waiting for an external event, or it can not even start * the engine. To present the illusion of a callback to the user of the API, * the implementation can call this helper function which triggers an * immediate event. This way the caller can use the same calling * conventions, independent of whether the request was actually deferred. * * @code * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, * struct tevent_context *ev) * { * struct tevent_req *req, *subreq; * struct computation_state *state; * req = tevent_req_create(mem_ctx, &state, struct computation_state); * if (req == NULL) { * return NULL; * } * subreq = subcomputation_send(state, ev); * if (tevent_req_nomem(subreq, req)) { * return tevent_req_post(req, ev); * } * tevent_req_set_callback(subreq, computation_done, req); * return req; * } * @endcode * * @param[in] req The finished request. * * @param[in] ev The tevent_context for the immediate event. * * @return The given request will be returned. */ struct tevent_req *tevent_req_post(struct tevent_req *req, struct tevent_context *ev); /** * @brief Finish multiple requests within one function * * Normally tevent_req_notify_callback() and all wrappers * (e.g. tevent_req_done() and tevent_req_error()) * need to be the last thing an event handler should call. * This is because the callback is likely to destroy the * context of the current function. * * If a function wants to notify more than one caller, * it is dangerous if it just triggers multiple callbacks * in a row. With tevent_req_defer_callback() it is possible * to set an event context that will be used to defer the callback * via an immediate event (similar to tevent_req_post()). * * @code * struct complete_state { * struct tevent_context *ev; * * struct tevent_req **reqs; * }; * * void complete(struct complete_state *state) * { * size_t i, c = talloc_array_length(state->reqs); * * for (i=0; i < c; i++) { * tevent_req_defer_callback(state->reqs[i], state->ev); * tevent_req_done(state->reqs[i]); * } * } * @endcode * * @param[in] req The finished request. * * @param[in] ev The tevent_context for the immediate event. * * @return The given request will be returned. */ void tevent_req_defer_callback(struct tevent_req *req, struct tevent_context *ev); /** * @brief Check if the given request is still in progress. * * It is typically used by sync wrapper functions. * * @param[in] req The request to poll. * * @return The boolean form of "is in progress". */ bool tevent_req_is_in_progress(struct tevent_req *req); /** * @brief Actively poll for the given request to finish. * * This function is typically used by sync wrapper functions. * * @param[in] req The request to poll. * * @param[in] ev The tevent_context to be used. * * @return On success true is returned. If a critical error has * happened in the tevent loop layer false is returned. * This is not the return value of the given request! * * @note This should only be used if the given tevent context was created by the * caller, to avoid event loop nesting. * * @code * req = tstream_writev_queue_send(mem_ctx, * ev_ctx, * tstream, * send_queue, * iov, 2); * ok = tevent_req_poll(req, tctx->ev); * rc = tstream_writev_queue_recv(req, &sys_errno); * TALLOC_FREE(req); * @endcode */ bool tevent_req_poll(struct tevent_req *req, struct tevent_context *ev); /** * @brief Get the tevent request state and the actual error set by * tevent_req_error. * * @code * int computation_recv(struct tevent_req *req, uint64_t *perr) * { * enum tevent_req_state state; * uint64_t err; * if (tevent_req_is_error(req, &state, &err)) { * *perr = err; * return -1; * } * return 0; * } * @endcode * * @param[in] req The tevent request to get the error from. * * @param[out] state A pointer to store the tevent request error state. * * @param[out] error A pointer to store the error set by tevent_req_error(). * * @return True if the function could set error and state, false * otherwise. * * @see tevent_req_error() */ bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error); /** * @brief Use as the last action of a _recv() function. * * This function destroys the attached private data. * * @param[in] req The finished request. */ void tevent_req_received(struct tevent_req *req); /** * @brief Mark a tevent_req for profiling * * This will turn on profiling for this tevent_req an all subreqs that * are directly started as helper requests off this * tevent_req. subreqs are chained by walking up the talloc_parent * hierarchy at a subreq's tevent_req_create. This means to get the * profiling chain right the subreq that needs to be profiled as part * of this tevent_req's profile must be a talloc child of the requests * state variable. * * @param[in] req The request to do tracing for * * @return False if the profile could not be activated */ bool tevent_req_set_profile(struct tevent_req *req); struct tevent_req_profile; /** * @brief Get the a request's profile for inspection * * @param[in] req The request to get the profile from * * @return The request's profile */ const struct tevent_req_profile *tevent_req_get_profile( struct tevent_req *req); /** * @brief Move the profile out of a request * * This function detaches the request's profile from the request, so * that the profile can outlive the request in a _recv function. * * @param[in] req The request to move the profile out of * @param[in] mem_ctx The new talloc context for the profile * * @return The moved profile */ struct tevent_req_profile *tevent_req_move_profile(struct tevent_req *req, TALLOC_CTX *mem_ctx); /** * @brief Get a profile description * * @param[in] profile The profile to be queried * @param[in] req_name The name of the request (state's name) * * "req_name" after this call is still in talloc-posession of "profile" */ void tevent_req_profile_get_name(const struct tevent_req_profile *profile, const char **req_name); /** * @brief Get a profile's start event data * * @param[in] profile The profile to be queried * @param[in] start_location The location where this event started * @param[in] start_time The time this event started * * "start_location" after this call is still in talloc-posession of "profile" */ void tevent_req_profile_get_start(const struct tevent_req_profile *profile, const char **start_location, struct timeval *start_time); /** * @brief Get a profile's stop event data * * @param[in] profile The profile to be queried * @param[in] stop_location The location where this event stopped * @param[in] stop_time The time this event stopped * * "stop_location" after this call is still in talloc-posession of "profile" */ void tevent_req_profile_get_stop(const struct tevent_req_profile *profile, const char **stop_location, struct timeval *stop_time); /** * @brief Get a profile's result data * * @param[in] pid The process where this profile was taken * @param[in] state The status the profile's tevent_req finished with * @param[in] user_error The user error of the profile's tevent_req */ void tevent_req_profile_get_status(const struct tevent_req_profile *profile, pid_t *pid, enum tevent_req_state *state, uint64_t *user_error); /** * @brief Retrieve the first subreq's profile from a profile * * @param[in] profile The profile to query * * @return The first tevent subreq's profile */ const struct tevent_req_profile *tevent_req_profile_get_subprofiles( const struct tevent_req_profile *profile); /** * @brief Walk the chain of subreqs * * @param[in] profile The subreq's profile to walk * * @return The next subprofile in the list */ const struct tevent_req_profile *tevent_req_profile_next( const struct tevent_req_profile *profile); /** * @brief Create a fresh tevent_req_profile * * @param[in] mem_ctx The talloc context to hang the fresh struct off * * @return The fresh struct */ struct tevent_req_profile *tevent_req_profile_create(TALLOC_CTX *mem_ctx); /** * @brief Set a profile's name * * @param[in] profile The profile to set the name for * @param[in] name The new name for the profile * * @return True if the internal talloc_strdup succeeded */ bool tevent_req_profile_set_name(struct tevent_req_profile *profile, const char *name); /** * @brief Set a profile's start event * * @param[in] profile The profile to set the start data for * @param[in] start_location The new start location * @param[in] start_time The new start time * * @return True if the internal talloc_strdup succeeded */ bool tevent_req_profile_set_start(struct tevent_req_profile *profile, const char *start_location, struct timeval start_time); /** * @brief Set a profile's stop event * * @param[in] profile The profile to set the stop data for * @param[in] stop_location The new stop location * @param[in] stop_time The new stop time * * @return True if the internal talloc_strdup succeeded */ bool tevent_req_profile_set_stop(struct tevent_req_profile *profile, const char *stop_location, struct timeval stop_time); /** * @brief Set a profile's exit status * * @param[in] profile The profile to set the exit status for * @param[in] pid The process where this profile was taken * @param[in] state The status the profile's tevent_req finished with * @param[in] user_error The user error of the profile's tevent_req */ void tevent_req_profile_set_status(struct tevent_req_profile *profile, pid_t pid, enum tevent_req_state state, uint64_t user_error); /** * @brief Add a subprofile to a profile * * @param[in] parent_profile The profile to be modified * @param[in] sub_profile The subreqs profile profile to be added * * "subreq" is talloc_move'ed into "parent_profile", so the talloc * ownership of "sub_profile" changes */ void tevent_req_profile_append_sub(struct tevent_req_profile *parent_profile, struct tevent_req_profile **sub_profile); /** * @brief Create a tevent subrequest at a given time. * * The idea is that always the same syntax for tevent requests. * * @param[in] mem_ctx The talloc memory context to use. * * @param[in] ev The event handle to setup the request. * * @param[in] wakeup_time The time to wakeup and execute the request. * * @return The new subrequest, NULL on error. * * Example: * @code * static void my_callback_wakeup_done(tevent_req *subreq) * { * struct tevent_req *req = tevent_req_callback_data(subreq, * struct tevent_req); * bool ok; * * ok = tevent_wakeup_recv(subreq); * TALLOC_FREE(subreq); * if (!ok) { * tevent_req_error(req, -1); * return; * } * ... * } * @endcode * * @code * subreq = tevent_wakeup_send(mem_ctx, ev, wakeup_time); * if (tevent_req_nomem(subreq, req)) { * return false; * } * tevent_set_callback(subreq, my_callback_wakeup_done, req); * @endcode * * @see tevent_wakeup_recv() */ struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct timeval wakeup_time); /** * @brief Check if the wakeup has been correctly executed. * * This function needs to be called in the callback function set after calling * tevent_wakeup_send(). * * @param[in] req The tevent request to check. * * @return True on success, false otherwise. * * @see tevent_wakeup_recv() */ bool tevent_wakeup_recv(struct tevent_req *req); /* @} */ /** * @defgroup tevent_helpers The tevent helper functions * @ingroup tevent * * @todo description * * @{ */ /** * @brief Compare two timeval values. * * @param[in] tv1 The first timeval value to compare. * * @param[in] tv2 The second timeval value to compare. * * @return 0 if they are equal. * 1 if the first time is greater than the second. * -1 if the first time is smaller than the second. */ int tevent_timeval_compare(const struct timeval *tv1, const struct timeval *tv2); /** * @brief Get a zero timeval value. * * @return A zero timeval value. */ struct timeval tevent_timeval_zero(void); /** * @brief Get a timeval value for the current time. * * @return A timeval value with the current time. */ struct timeval tevent_timeval_current(void); /** * @brief Get a timeval structure with the given values. * * @param[in] secs The seconds to set. * * @param[in] usecs The microseconds to set. * * @return A timeval structure with the given values. */ struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs); /** * @brief Get the difference between two timeval values. * * @param[in] tv1 The first timeval. * * @param[in] tv2 The second timeval. * * @return A timeval structure with the difference between the * first and the second value. */ struct timeval tevent_timeval_until(const struct timeval *tv1, const struct timeval *tv2); /** * @brief Check if a given timeval structure is zero. * * @param[in] tv The timeval to check if it is zero. * * @return True if it is zero, false otherwise. */ bool tevent_timeval_is_zero(const struct timeval *tv); /** * @brief Add the given amount of time to a timeval structure. * * @param[in] tv The timeval structure to add the time. * * @param[in] secs The seconds to add to the timeval. * * @param[in] usecs The microseconds to add to the timeval. * * @return The timeval structure with the new time. */ struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, uint32_t usecs); /** * @brief Get a timeval in the future with a specified offset from now. * * @param[in] secs The seconds of the offset from now. * * @param[in] usecs The microseconds of the offset from now. * * @return A timeval with the given offset in the future. */ struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs); /* @} */ /** * @defgroup tevent_queue The tevent queue functions * @ingroup tevent * * A tevent_queue is used to queue up async requests that must be * serialized. For example writing buffers into a socket must be * serialized. Writing a large lump of data into a socket can require * multiple write(2) or send(2) system calls. If more than one async * request is outstanding to write large buffers into a socket, every * request must individually be completed before the next one begins, * even if multiple syscalls are required. * * Take a look at @ref tevent_queue_tutorial for more details. * @{ */ struct tevent_queue; struct tevent_queue_entry; #ifdef DOXYGEN /** * @brief Create and start a tevent queue. * * @param[in] mem_ctx The talloc memory context to allocate the queue. * * @param[in] name The name to use to identify the queue. * * @return An allocated tevent queue on success, NULL on error. * * @see tevent_queue_start() * @see tevent_queue_stop() */ struct tevent_queue *tevent_queue_create(TALLOC_CTX *mem_ctx, const char *name); #else struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, const char *name, const char *location); #define tevent_queue_create(_mem_ctx, _name) \ _tevent_queue_create((_mem_ctx), (_name), __location__) #endif /** * @brief A callback trigger function run by the queue. * * @param[in] req The tevent request the trigger function is executed on. * * @param[in] private_data The private data pointer specified by * tevent_queue_add(). * * @see tevent_queue_add() * @see tevent_queue_add_entry() * @see tevent_queue_add_optimize_empty() */ typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req, void *private_data); /** * @brief Add a tevent request to the queue. * * @param[in] queue The queue to add the request. * * @param[in] ev The event handle to use for the request. * * @param[in] req The tevent request to add to the queue. * * @param[in] trigger The function triggered by the queue when the request * is called. Since tevent 0.9.14 it's possible to * pass NULL, in order to just add a "blocker" to the * queue. * * @param[in] private_data The private data passed to the trigger function. * * @return True if the request has been successfully added, false * otherwise. */ bool tevent_queue_add(struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data); /** * @brief Add a tevent request to the queue. * * The request can be removed from the queue by calling talloc_free() * (or a similar function) on the returned queue entry. This * is the only difference to tevent_queue_add(). * * @param[in] queue The queue to add the request. * * @param[in] ev The event handle to use for the request. * * @param[in] req The tevent request to add to the queue. * * @param[in] trigger The function triggered by the queue when the request * is called. Since tevent 0.9.14 it's possible to * pass NULL, in order to just add a "blocker" to the * queue. * * @param[in] private_data The private data passed to the trigger function. * * @return a pointer to the tevent_queue_entry if the request * has been successfully added, NULL otherwise. * * @see tevent_queue_add() * @see tevent_queue_add_optimize_empty() */ struct tevent_queue_entry *tevent_queue_add_entry( struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data); /** * @brief Add a tevent request to the queue using a possible optimization. * * This tries to optimize for the empty queue case and may calls * the trigger function directly. This is the only difference compared * to tevent_queue_add_entry(). * * The caller needs to be prepared that the trigger function has * already called tevent_req_notify_callback(), tevent_req_error(), * tevent_req_done() or a similar function. * * The trigger function has no chance to see the returned * queue_entry in the optimized case. * * The request can be removed from the queue by calling talloc_free() * (or a similar function) on the returned queue entry. * * @param[in] queue The queue to add the request. * * @param[in] ev The event handle to use for the request. * * @param[in] req The tevent request to add to the queue. * * @param[in] trigger The function triggered by the queue when the request * is called. Since tevent 0.9.14 it's possible to * pass NULL, in order to just add a "blocker" to the * queue. * * @param[in] private_data The private data passed to the trigger function. * * @return a pointer to the tevent_queue_entry if the request * has been successfully added, NULL otherwise. * * @see tevent_queue_add() * @see tevent_queue_add_entry() */ struct tevent_queue_entry *tevent_queue_add_optimize_empty( struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data); /** * @brief Untrigger an already triggered queue entry. * * If a trigger function detects that it needs to remain * in the queue, it needs to call tevent_queue_stop() * followed by tevent_queue_entry_untrigger(). * * @note In order to call tevent_queue_entry_untrigger() * the queue must be already stopped and the given queue_entry * must be the first one in the queue! Otherwise it calls abort(). * * @note You can't use this together with tevent_queue_add_optimize_empty() * because the trigger function don't have access to the quene entry * in the case of an empty queue. * * @param[in] queue_entry The queue entry to rearm. * * @see tevent_queue_add_entry() * @see tevent_queue_stop() */ void tevent_queue_entry_untrigger(struct tevent_queue_entry *entry); /** * @brief Start a tevent queue. * * The queue is started by default. * * @param[in] queue The queue to start. */ void tevent_queue_start(struct tevent_queue *queue); /** * @brief Stop a tevent queue. * * The queue is started by default. * * @param[in] queue The queue to stop. */ void tevent_queue_stop(struct tevent_queue *queue); /** * @brief Get the length of the queue. * * @param[in] queue The queue to get the length from. * * @return The number of elements. */ size_t tevent_queue_length(struct tevent_queue *queue); /** * @brief Is the tevent queue running. * * The queue is started by default. * * @param[in] queue The queue. * * @return Whether the queue is running or not.. */ bool tevent_queue_running(struct tevent_queue *queue); /** * @brief Create a tevent subrequest that waits in a tevent_queue * * The idea is that always the same syntax for tevent requests. * * @param[in] mem_ctx The talloc memory context to use. * * @param[in] ev The event handle to setup the request. * * @param[in] queue The queue to wait in. * * @return The new subrequest, NULL on error. * * @see tevent_queue_wait_recv() */ struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct tevent_queue *queue); /** * @brief Check if we no longer need to wait in the queue. * * This function needs to be called in the callback function set after calling * tevent_queue_wait_send(). * * @param[in] req The tevent request to check. * * @return True on success, false otherwise. * * @see tevent_queue_wait_send() */ bool tevent_queue_wait_recv(struct tevent_req *req); typedef int (*tevent_nesting_hook)(struct tevent_context *ev, void *private_data, uint32_t level, bool begin, void *stack_ptr, const char *location); /** * @brief Create a tevent_thread_proxy for message passing between threads. * * The tevent_context must have been allocated on the NULL * talloc context, and talloc_disable_null_tracking() must * have been called. * * @param[in] dest_ev_ctx The tevent_context to receive events. * * @return An allocated tevent_thread_proxy, NULL on error. * If tevent was compiled without PTHREAD support * NULL is always returned and errno set to ENOSYS. * * @see tevent_thread_proxy_schedule() */ struct tevent_thread_proxy *tevent_thread_proxy_create( struct tevent_context *dest_ev_ctx); /** * @brief Schedule an immediate event on an event context from another thread. * * Causes dest_ev_ctx, being run by another thread, to receive an * immediate event calling the handler with the *pp_private parameter. * * *pp_im must be a pointer to an immediate event talloced on a context owned * by the calling thread, or the NULL context. Ownership will * be transferred to the tevent_thread_proxy and *pp_im will be returned as NULL. * * *pp_private_data must be a talloced area of memory with no destructors. * Ownership of this memory will be transferred to the tevent library and * *pp_private_data will be set to NULL on successful completion of * the call. Set pp_private to NULL if no parameter transfer * needed (a pure callback). This is an asynchronous request, caller * does not wait for callback to be completed before returning. * * @param[in] tp The tevent_thread_proxy to use. * * @param[in] pp_im Pointer to immediate event pointer. * * @param[in] handler The function that will be called. * * @param[in] pp_private_data The talloced memory to transfer. * * @see tevent_thread_proxy_create() */ void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, struct tevent_immediate **pp_im, tevent_immediate_handler_t handler, void *pp_private_data); /* * @brief Create a context for threaded activation of immediates * * A tevent_treaded_context provides a link into an event * context. Using tevent_threaded_schedule_immediate, it is possible * to activate an immediate event from within a thread. * * It is the duty of the caller of tevent_threaded_context_create() to * keep the event context around longer than any * tevent_threaded_context. tevent will abort if ev is talloc_free'ed * with an active tevent_threaded_context. * * If tevent is build without pthread support, this always returns * NULL with errno=ENOSYS. * * @param[in] mem_ctx The talloc memory context to use. * @param[in] ev The event context to link this to. * @return The threaded context, or NULL with errno set. * * @see tevent_threaded_schedule_immediate() * * @note Available as of tevent 0.9.30 */ struct tevent_threaded_context *tevent_threaded_context_create( TALLOC_CTX *mem_ctx, struct tevent_context *ev); #ifdef DOXYGEN /* * @brief Activate an immediate from a thread * * Activate an immediate from within a thread. * * This routine does not watch out for talloc hierarchies. This means * that it is highly recommended to create the tevent_immediate in the * thread owning tctx, allocate a threaded job description for the * thread, hand over both pointers to a helper thread and not touch it * in the main thread at all anymore. * * tevent_threaded_schedule_immediate is intended as a job completion * indicator for simple threaded helpers. * * Please be aware that tevent_threaded_schedule_immediate is very * picky about its arguments: An immediate may not already be * activated and the handler must exist. With * tevent_threaded_schedule_immediate memory ownership is transferred * to the main thread holding the tevent context behind tctx, the * helper thread can't access it anymore. * * @param[in] tctx The threaded context to go through * @param[in] im The immediate event to activate * @param[in] handler The immediate handler to call in the main thread * @param[in] private_data Pointer for the immediate handler * * @see tevent_threaded_context_create() * * @note Available as of tevent 0.9.30 */ void tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, struct tevent_immediate *im, tevent_immediate_handler_t handler, void *private_data); #else void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, struct tevent_immediate *im, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location); #define tevent_threaded_schedule_immediate(tctx, im, handler, private_data) \ _tevent_threaded_schedule_immediate(tctx, im, handler, private_data, \ #handler, __location__); #endif #ifdef TEVENT_DEPRECATED #ifndef _DEPRECATED_ #ifdef HAVE___ATTRIBUTE__ #define _DEPRECATED_ __attribute__ ((deprecated)) #else #define _DEPRECATED_ #endif #endif void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_; void tevent_loop_set_nesting_hook(struct tevent_context *ev, tevent_nesting_hook hook, void *private_data) _DEPRECATED_; int _tevent_loop_until(struct tevent_context *ev, bool (*finished)(void *private_data), void *private_data, const char *location) _DEPRECATED_; #define tevent_loop_until(ev, finished, private_data) \ _tevent_loop_until(ev, finished, private_data, __location__) #endif int tevent_re_initialise(struct tevent_context *ev); /* @} */ /** * @defgroup tevent_ops The tevent operation functions * @ingroup tevent * * The following structure and registration functions are exclusively * needed for people writing and pluggin a different event engine. * There is nothing useful for normal tevent user in here. * @{ */ struct tevent_ops { /* context init */ int (*context_init)(struct tevent_context *ev); /* fd_event functions */ struct tevent_fd *(*add_fd)(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location); void (*set_fd_close_fn)(struct tevent_fd *fde, tevent_fd_close_fn_t close_fn); uint16_t (*get_fd_flags)(struct tevent_fd *fde); void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags); /* timed_event functions */ struct tevent_timer *(*add_timer)(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location); /* immediate event functions */ void (*schedule_immediate)(struct tevent_immediate *im, struct tevent_context *ev, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location); /* signal functions */ struct tevent_signal *(*add_signal)(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data, const char *handler_name, const char *location); /* loop functions */ int (*loop_once)(struct tevent_context *ev, const char *location); int (*loop_wait)(struct tevent_context *ev, const char *location); }; bool tevent_register_backend(const char *name, const struct tevent_ops *ops); /* @} */ #ifdef TEVENT_DEPRECATED /** * @defgroup tevent_wrapper_ops The tevent wrapper operation functions * @ingroup tevent * * The following structure and registration functions are exclusively * needed for people writing wrapper functions for event handlers * e.g. wrappers can be used for debugging/profiling or impersonation. * * There is nothing useful for normal tevent user in here. * * @note That the close_fn() on tevent_fd is *NOT* wrapped! * * @see tevent_context_wrapper_create * @see tevent_fd_set_auto_close * @{ */ struct tevent_wrapper_ops { const char *name; bool (*before_use)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, const char *location); void (*after_use)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, const char *location); void (*before_fd_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_fd *fde, uint16_t flags, const char *handler_name, const char *location); void (*after_fd_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_fd *fde, uint16_t flags, const char *handler_name, const char *location); void (*before_timer_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_timer *te, struct timeval requested_time, struct timeval trigger_time, const char *handler_name, const char *location); void (*after_timer_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_timer *te, struct timeval requested_time, struct timeval trigger_time, const char *handler_name, const char *location); void (*before_immediate_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_immediate *im, const char *handler_name, const char *location); void (*after_immediate_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_immediate *im, const char *handler_name, const char *location); void (*before_signal_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_signal *se, int signum, int count, void *siginfo, const char *handler_name, const char *location); void (*after_signal_handler)(struct tevent_context *wrap_ev, void *private_state, struct tevent_context *main_ev, struct tevent_signal *se, int signum, int count, void *siginfo, const char *handler_name, const char *location); }; #ifdef DOXYGEN /** * @brief Create a wrapper tevent_context. * * @param[in] main_ev The main event context to work on. * * @param[in] mem_ctx The talloc memory context to use. * * @param[in] ops The tevent_wrapper_ops function table. * * @param[out] private_state The private state use by the wrapper functions. * * @param[in] private_type The talloc type of the private_state. * * @return The wrapper event context, NULL on error. * * @note Available as of tevent 0.9.37 * @note Deprecated as of tevent 0.9.38 */ struct tevent_context *tevent_context_wrapper_create(struct tevent_context *main_ev, TALLOC_CTX *mem_ctx, const struct tevent_wrapper_ops *ops, void **private_state, const char *private_type); #else struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev, TALLOC_CTX *mem_ctx, const struct tevent_wrapper_ops *ops, void *pstate, size_t psize, const char *type, const char *location) _DEPRECATED_; #define tevent_context_wrapper_create(main_ev, mem_ctx, ops, state, type) \ _tevent_context_wrapper_create(main_ev, mem_ctx, ops, \ state, sizeof(type), #type, __location__) #endif /** * @brief Check if the event context is a wrapper event context. * * @param[in] ev The event context to work on. * * @return Is a wrapper (true), otherwise (false). * * @see tevent_context_wrapper_create() * * @note Available as of tevent 0.9.37 * @note Deprecated as of tevent 0.9.38 */ bool tevent_context_is_wrapper(struct tevent_context *ev) _DEPRECATED_; #ifdef DOXYGEN /** * @brief Prepare the environment of a (wrapper) event context. * * A caller might call this before passing a wrapper event context * to a tevent_req based *_send() function. * * The wrapper event context might do something like impersonation. * * tevent_context_push_use() must always be used in combination * with tevent_context_pop_use(). * * There is a global stack of currently active/busy wrapper event contexts. * Each wrapper can only appear once on that global stack! * The stack size is limited to 32 elements, which should be enough * for all useful scenarios. * * In addition to an explicit tevent_context_push_use() also * the invocation of an immediate, timer or fd handler implicitly * pushes the wrapper on the stack. * * Therefore there are some strict constraints for the usage of * tevent_context_push_use(): * - It must not be called from within an event handler * that already acts on the wrapper. * - tevent_context_pop_use() must be called before * leaving the code block that called tevent_context_push_use(). * - The caller is responsible ensure the correct stack ordering * - Any violation of these constraints results in calling * the abort handler of the given tevent context. * * Calling tevent_context_push_use() on a raw event context * still consumes an element on the stack, but it's otherwise * a no-op. * * If tevent_context_push_use() returns false, it means * that the wrapper's before_use() hook returned this failure, * in that case you must not call tevent_context_pop_use() as * the wrapper is not pushed onto the stack. * * @param[in] ev The event context to work on. * * @return Success (true) or failure (false). * * @note This is only needed if wrapper event contexts are in use. * * @see tevent_context_pop_use * * @note Available as of tevent 0.9.37 * @note Deprecated as of tevent 0.9.38 */ bool tevent_context_push_use(struct tevent_context *ev); #else bool _tevent_context_push_use(struct tevent_context *ev, const char *location) _DEPRECATED_; #define tevent_context_push_use(ev) \ _tevent_context_push_use(ev, __location__) #endif #ifdef DOXYGEN /** * @brief Release the environment of a (wrapper) event context. * * The wrapper event context might undo something like impersonation. * * This must be called after a succesful tevent_context_push_use(). * Any ordering violation results in calling * the abort handler of the given tevent context. * * This basically calls the wrapper's after_use() hook. * * @param[in] ev The event context to work on. * * @note This is only needed if wrapper event contexts are in use. * * @see tevent_context_push_use * * @note Available as of tevent 0.9.37 * @note Deprecated as of tevent 0.9.38 */ void tevent_context_pop_use(struct tevent_context *ev); #else void _tevent_context_pop_use(struct tevent_context *ev, const char *location) _DEPRECATED_; #define tevent_context_pop_use(ev) \ _tevent_context_pop_use(ev, __location__) #endif /** * @brief Check is the two context pointers belong to the same low level loop * * With the introduction of wrapper contexts it's not trivial * to check if two context pointers belong to the same low level * event loop. Some code may need to know this in order * to make some caching decisions. * * @param[in] ev1 The first event context. * @param[in] ev2 The second event context. * * @return true if both contexts belong to the same (still existing) context * loop, false otherwise. * * @see tevent_context_wrapper_create * * @note Available as of tevent 0.9.37 * @note Deprecated as of tevent 0.9.38 */ bool tevent_context_same_loop(struct tevent_context *ev1, struct tevent_context *ev2) _DEPRECATED_; /* @} */ #endif /* TEVENT_DEPRECATED */ /** * @defgroup tevent_compat The tevent compatibility functions * @ingroup tevent * * The following definitions are usueful only for compatibility with the * implementation originally developed within the samba4 code and will be * soon removed. Please NEVER use in new code. * * @todo Ignore it? * * @{ */ #ifdef TEVENT_COMPAT_DEFINES #define event_context tevent_context #define event_ops tevent_ops #define fd_event tevent_fd #define timed_event tevent_timer #define signal_event tevent_signal #define event_fd_handler_t tevent_fd_handler_t #define event_timed_handler_t tevent_timer_handler_t #define event_signal_handler_t tevent_signal_handler_t #define event_context_init(mem_ctx) \ tevent_context_init(mem_ctx) #define event_context_init_byname(mem_ctx, name) \ tevent_context_init_byname(mem_ctx, name) #define event_backend_list(mem_ctx) \ tevent_backend_list(mem_ctx) #define event_set_default_backend(backend) \ tevent_set_default_backend(backend) #define event_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) #define event_add_timed(ev, mem_ctx, next_event, handler, private_data) \ tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) #define event_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) #define event_loop_once(ev) \ tevent_loop_once(ev) #define event_loop_wait(ev) \ tevent_loop_wait(ev) #define event_get_fd_flags(fde) \ tevent_fd_get_flags(fde) #define event_set_fd_flags(fde, flags) \ tevent_fd_set_flags(fde, flags) #define EVENT_FD_READ TEVENT_FD_READ #define EVENT_FD_WRITE TEVENT_FD_WRITE #define EVENT_FD_WRITEABLE(fde) \ TEVENT_FD_WRITEABLE(fde) #define EVENT_FD_READABLE(fde) \ TEVENT_FD_READABLE(fde) #define EVENT_FD_NOT_WRITEABLE(fde) \ TEVENT_FD_NOT_WRITEABLE(fde) #define EVENT_FD_NOT_READABLE(fde) \ TEVENT_FD_NOT_READABLE(fde) #define ev_debug_level tevent_debug_level #define EV_DEBUG_FATAL TEVENT_DEBUG_FATAL #define EV_DEBUG_ERROR TEVENT_DEBUG_ERROR #define EV_DEBUG_WARNING TEVENT_DEBUG_WARNING #define EV_DEBUG_TRACE TEVENT_DEBUG_TRACE #define ev_set_debug(ev, debug, context) \ tevent_set_debug(ev, debug, context) #define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev) #endif /* TEVENT_COMPAT_DEFINES */ /* @} */ #endif /* __TEVENT_H__ */ ldb-2.0.8/lib/tevent/tevent.pc.in0000660000000000000000000000040712406075657016544 0ustar rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: tevent Description: An event system library Version: @PACKAGE_VERSION@ Requires: talloc Libs: @LIB_RPATH@ -L${libdir} -ltevent Cflags: -I${includedir} URL: http://samba.org/ ldb-2.0.8/lib/tevent/tevent.py0000660000000000000000000000174413573675413016174 0ustar rootroot00000000000000# # Python integration for tevent # # Copyright (C) Jelmer Vernooij 2011 # # ** NOTE! The following LGPL license applies to the tevent # ** 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 . from _tevent import ( __version__, backend_list, Context, Signal, ) ldb-2.0.8/lib/tevent/tevent_debug.c0000660000000000000000000000722413444661620017123 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Copyright (C) Andrew Tridgell 2005 Copyright (C) Jelmer Vernooij 2005 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "tevent.h" #include "tevent_internal.h" /******************************************************************** * Debug wrapper functions, modeled (with lot's of code copied as is) * after the ev debug wrapper functions ********************************************************************/ /* this allows the user to choose their own debug function */ int tevent_set_debug(struct tevent_context *ev, void (*debug)(void *context, enum tevent_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0), void *context) { if (ev->wrapper.glue != NULL) { ev = tevent_wrapper_main_ev(ev); tevent_abort(ev, "tevent_set_debug() on wrapper"); errno = EINVAL; return -1; } ev->debug_ops.debug = debug; ev->debug_ops.context = context; return 0; } /* debug function for ev_set_debug_stderr */ static void tevent_debug_stderr(void *private_data, enum tevent_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); static void tevent_debug_stderr(void *private_data, enum tevent_debug_level level, const char *fmt, va_list ap) { if (level <= TEVENT_DEBUG_WARNING) { vfprintf(stderr, fmt, ap); } } /* convenience function to setup debug messages on stderr messages of level TEVENT_DEBUG_WARNING and higher are printed */ int tevent_set_debug_stderr(struct tevent_context *ev) { return tevent_set_debug(ev, tevent_debug_stderr, ev); } /* * log a message * * The default debug action is to ignore debugging messages. * This is the most appropriate action for a library. * Applications using the library must decide where to * redirect debugging messages */ void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level, const char *fmt, ...) { va_list ap; if (!ev) { return; } if (ev->wrapper.glue != NULL) { ev = tevent_wrapper_main_ev(ev); } if (ev->debug_ops.debug == NULL) { return; } va_start(ap, fmt); ev->debug_ops.debug(ev->debug_ops.context, level, fmt, ap); va_end(ap); } void tevent_set_trace_callback(struct tevent_context *ev, tevent_trace_callback_t cb, void *private_data) { if (ev->wrapper.glue != NULL) { ev = tevent_wrapper_main_ev(ev); tevent_abort(ev, "tevent_set_trace_callback() on wrapper"); return; } ev->tracing.callback = cb; ev->tracing.private_data = private_data; } void tevent_get_trace_callback(struct tevent_context *ev, tevent_trace_callback_t *cb, void *private_data) { *cb = ev->tracing.callback; *(void**)private_data = ev->tracing.private_data; } void tevent_trace_point_callback(struct tevent_context *ev, enum tevent_trace_point tp) { if (ev->tracing.callback != NULL) { ev->tracing.callback(tp, ev->tracing.private_data); } } ldb-2.0.8/lib/tevent/tevent_epoll.c0000660000000000000000000006216313444661620017153 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. main select loop and event handling - epoll implementation Copyright (C) Andrew Tridgell 2003-2005 Copyright (C) Stefan Metzmacher 2005-2013 Copyright (C) Jeremy Allison 2013 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/select.h" #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" struct epoll_event_context { /* a pointer back to the generic event_context */ struct tevent_context *ev; /* when using epoll this is the handle from epoll_create */ int epoll_fd; pid_t pid; bool panic_force_replay; bool *panic_state; bool (*panic_fallback)(struct tevent_context *ev, bool replay); }; #define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0) #define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) #define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) #define EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX (1<<3) #ifdef TEST_PANIC_FALLBACK static int epoll_create_panic_fallback(struct epoll_event_context *epoll_ev, int size) { if (epoll_ev->panic_fallback == NULL) { return epoll_create(size); } /* 50% of the time, fail... */ if ((random() % 2) == 0) { errno = EINVAL; return -1; } return epoll_create(size); } static int epoll_ctl_panic_fallback(struct epoll_event_context *epoll_ev, int epfd, int op, int fd, struct epoll_event *event) { if (epoll_ev->panic_fallback == NULL) { return epoll_ctl(epfd, op, fd, event); } /* 50% of the time, fail... */ if ((random() % 2) == 0) { errno = EINVAL; return -1; } return epoll_ctl(epfd, op, fd, event); } static int epoll_wait_panic_fallback(struct epoll_event_context *epoll_ev, int epfd, struct epoll_event *events, int maxevents, int timeout) { if (epoll_ev->panic_fallback == NULL) { return epoll_wait(epfd, events, maxevents, timeout); } /* 50% of the time, fail... */ if ((random() % 2) == 0) { errno = EINVAL; return -1; } return epoll_wait(epfd, events, maxevents, timeout); } #define epoll_create(_size) \ epoll_create_panic_fallback(epoll_ev, _size) #define epoll_ctl(_epfd, _op, _fd, _event) \ epoll_ctl_panic_fallback(epoll_ev,_epfd, _op, _fd, _event) #define epoll_wait(_epfd, _events, _maxevents, _timeout) \ epoll_wait_panic_fallback(epoll_ev, _epfd, _events, _maxevents, _timeout) #endif /* called to set the panic fallback function. */ _PRIVATE_ void tevent_epoll_set_panic_fallback(struct tevent_context *ev, bool (*panic_fallback)(struct tevent_context *ev, bool replay)) { struct epoll_event_context *epoll_ev = talloc_get_type_abort(ev->additional_data, struct epoll_event_context); epoll_ev->panic_fallback = panic_fallback; } /* called when a epoll call fails */ static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason, bool replay) { struct tevent_context *ev = epoll_ev->ev; bool (*panic_fallback)(struct tevent_context *ev, bool replay); panic_fallback = epoll_ev->panic_fallback; if (epoll_ev->panic_state != NULL) { *epoll_ev->panic_state = true; } if (epoll_ev->panic_force_replay) { replay = true; } TALLOC_FREE(ev->additional_data); if (panic_fallback == NULL) { tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s (%s) replay[%u] - calling abort()\n", reason, strerror(errno), (unsigned)replay); abort(); } tevent_debug(ev, TEVENT_DEBUG_ERROR, "%s (%s) replay[%u] - calling panic_fallback\n", reason, strerror(errno), (unsigned)replay); if (!panic_fallback(ev, replay)) { /* Fallback failed. */ tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s (%s) replay[%u] - calling abort()\n", reason, strerror(errno), (unsigned)replay); abort(); } } /* map from TEVENT_FD_* to EPOLLIN/EPOLLOUT */ static uint32_t epoll_map_flags(uint16_t flags) { uint32_t ret = 0; if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP); if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP); return ret; } /* free the epoll fd */ static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev) { close(epoll_ev->epoll_fd); epoll_ev->epoll_fd = -1; return 0; } /* init the epoll fd */ static int epoll_init_ctx(struct epoll_event_context *epoll_ev) { epoll_ev->epoll_fd = epoll_create(64); if (epoll_ev->epoll_fd == -1) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, "Failed to create epoll handle.\n"); return -1; } if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); } epoll_ev->pid = getpid(); talloc_set_destructor(epoll_ev, epoll_ctx_destructor); return 0; } static void epoll_update_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde); /* reopen the epoll handle when our pid changes see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an demonstration of why this is needed */ static void epoll_check_reopen(struct epoll_event_context *epoll_ev) { struct tevent_fd *fde; bool *caller_panic_state = epoll_ev->panic_state; bool panic_triggered = false; if (epoll_ev->pid == getpid()) { return; } close(epoll_ev->epoll_fd); epoll_ev->epoll_fd = epoll_create(64); if (epoll_ev->epoll_fd == -1) { epoll_panic(epoll_ev, "epoll_create() failed", false); return; } if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); } epoll_ev->pid = getpid(); epoll_ev->panic_state = &panic_triggered; for (fde=epoll_ev->ev->fd_events;fde;fde=fde->next) { fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; epoll_update_event(epoll_ev, fde); if (panic_triggered) { if (caller_panic_state != NULL) { *caller_panic_state = true; } return; } } epoll_ev->panic_state = NULL; } /* epoll cannot add the same file descriptor twice, once with read, once with write which is allowed by the tevent backend. Multiplex the existing fde, flag it as such so we can search for the correct fde on event triggering. */ static int epoll_add_multiplex_fd(struct epoll_event_context *epoll_ev, struct tevent_fd *add_fde) { struct epoll_event event; struct tevent_fd *mpx_fde; int ret; /* Find the existing fde that caused the EEXIST error. */ for (mpx_fde = epoll_ev->ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) { if (mpx_fde->fd != add_fde->fd) { continue; } if (mpx_fde == add_fde) { continue; } break; } if (mpx_fde == NULL) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, "can't find multiplex fde for fd[%d]", add_fde->fd); return -1; } if (mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { /* Logic error. Can't have more than 2 multiplexed fde's. */ tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, "multiplex fde for fd[%d] is already multiplexed\n", mpx_fde->fd); return -1; } /* * The multiplex fde must have the same fd, and also * already have an epoll event attached. */ if (!(mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) { /* Logic error. Can't have more than 2 multiplexed fde's. */ tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, "multiplex fde for fd[%d] has no event\n", mpx_fde->fd); return -1; } /* Modify the mpx_fde to add in the new flags. */ ZERO_STRUCT(event); event.events = epoll_map_flags(mpx_fde->flags); event.events |= epoll_map_flags(add_fde->flags); event.data.ptr = mpx_fde; ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, mpx_fde->fd, &event); if (ret != 0 && errno == EBADF) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, "EPOLL_CTL_MOD EBADF for " "add_fde[%p] mpx_fde[%p] fd[%d] - disabling\n", add_fde, mpx_fde, add_fde->fd); DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); mpx_fde->wrapper = NULL; mpx_fde->event_ctx = NULL; DLIST_REMOVE(epoll_ev->ev->fd_events, add_fde); add_fde->wrapper = NULL; add_fde->event_ctx = NULL; return 0; } else if (ret != 0) { return ret; } /* * Make each fde->additional_data pointers point at each other * so we can look them up from each other. They are now paired. */ mpx_fde->additional_data = (struct tevent_fd *)add_fde; add_fde->additional_data = (struct tevent_fd *)mpx_fde; /* Now flag both fde's as being multiplexed. */ mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; add_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; /* we need to keep the GOT_ERROR flag */ if (mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR) { add_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; } return 0; } /* add the epoll event to the given fd_event */ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) { struct epoll_event event; int ret; struct tevent_fd *mpx_fde = NULL; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * This is a multiplexed fde, we need to include both * flags in the modified event. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; } ZERO_STRUCT(event); event.events = epoll_map_flags(fde->flags); if (mpx_fde != NULL) { event.events |= epoll_map_flags(mpx_fde->flags); } event.data.ptr = fde; ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event); if (ret != 0 && errno == EBADF) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, "EPOLL_CTL_ADD EBADF for " "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", fde, mpx_fde, fde->fd); DLIST_REMOVE(epoll_ev->ev->fd_events, fde); fde->wrapper = NULL; fde->event_ctx = NULL; if (mpx_fde != NULL) { DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); mpx_fde->wrapper = NULL; mpx_fde->event_ctx = NULL; } return; } else if (ret != 0 && errno == EEXIST && mpx_fde == NULL) { ret = epoll_add_multiplex_fd(epoll_ev, fde); if (ret != 0) { epoll_panic(epoll_ev, "epoll_add_multiplex_fd failed", false); return; } } else if (ret != 0) { epoll_panic(epoll_ev, "EPOLL_CTL_ADD failed", false); return; } fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; /* only if we want to read we want to tell the event handler about errors */ if (fde->flags & TEVENT_FD_READ) { fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; } if (mpx_fde == NULL) { return; } mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; /* only if we want to read we want to tell the event handler about errors */ if (mpx_fde->flags & TEVENT_FD_READ) { mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; } } /* delete the epoll event for given fd_event */ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) { struct epoll_event event; int ret; struct tevent_fd *mpx_fde = NULL; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * This is a multiplexed fde, we need to modify both events. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; } ZERO_STRUCT(event); ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event); if (ret != 0 && errno == ENOENT) { /* * This can happen after a epoll_check_reopen * within epoll_event_fd_destructor. */ tevent_debug(epoll_ev->ev, TEVENT_DEBUG_TRACE, "EPOLL_CTL_DEL ignoring ENOENT for fd[%d]\n", fde->fd); return; } else if (ret != 0 && errno == EBADF) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, "EPOLL_CTL_DEL EBADF for " "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", fde, mpx_fde, fde->fd); DLIST_REMOVE(epoll_ev->ev->fd_events, fde); fde->wrapper = NULL; fde->event_ctx = NULL; if (mpx_fde != NULL) { DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); mpx_fde->wrapper = NULL; mpx_fde->event_ctx = NULL; } return; } else if (ret != 0) { epoll_panic(epoll_ev, "EPOLL_CTL_DEL failed", false); return; } } /* change the epoll event to the given fd_event */ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) { struct tevent_fd *mpx_fde = NULL; struct epoll_event event; int ret; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * This is a multiplexed fde, we need to include both * flags in the modified event. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; } ZERO_STRUCT(event); event.events = epoll_map_flags(fde->flags); if (mpx_fde != NULL) { event.events |= epoll_map_flags(mpx_fde->flags); } event.data.ptr = fde; ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event); if (ret != 0 && errno == EBADF) { tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, "EPOLL_CTL_MOD EBADF for " "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", fde, mpx_fde, fde->fd); DLIST_REMOVE(epoll_ev->ev->fd_events, fde); fde->wrapper = NULL; fde->event_ctx = NULL; if (mpx_fde != NULL) { DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); mpx_fde->wrapper = NULL; mpx_fde->event_ctx = NULL; } return; } else if (ret != 0) { epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed", false); return; } fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; /* only if we want to read we want to tell the event handler about errors */ if (fde->flags & TEVENT_FD_READ) { fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; } if (mpx_fde == NULL) { return; } mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; /* only if we want to read we want to tell the event handler about errors */ if (mpx_fde->flags & TEVENT_FD_READ) { mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; } } static void epoll_update_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) { bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR); bool want_read = (fde->flags & TEVENT_FD_READ); bool want_write= (fde->flags & TEVENT_FD_WRITE); struct tevent_fd *mpx_fde = NULL; if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * work out what the multiplexed fde wants. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); if (mpx_fde->flags & TEVENT_FD_READ) { want_read = true; } if (mpx_fde->flags & TEVENT_FD_WRITE) { want_write = true; } } /* there's already an event */ if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) { if (want_read || (want_write && !got_error)) { epoll_mod_event(epoll_ev, fde); return; } /* * if we want to match the select behavior, we need to remove the epoll_event * when the caller isn't interested in events. * * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them */ epoll_del_event(epoll_ev, fde); return; } /* there's no epoll_event attached to the fde */ if (want_read || (want_write && !got_error)) { epoll_add_event(epoll_ev, fde); return; } } /* Cope with epoll returning EPOLLHUP|EPOLLERR on an event. Return true if there's nothing else to do, false if this event needs further handling. */ static bool epoll_handle_hup_or_err(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) { if (fde == NULL) { /* Nothing to do if no event. */ return true; } fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; /* * if we only wait for TEVENT_FD_WRITE, we should not tell the * event handler about it, and remove the epoll_event, * as we only report errors when waiting for read events, * to match the select() behavior */ if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { /* * Do the same as the poll backend and * remove the writeable flag. */ fde->flags &= ~TEVENT_FD_WRITE; return true; } /* This has TEVENT_FD_READ set, we're not finished. */ return false; } /* event loop handling using epoll */ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp) { int ret, i; #define MAXEVENTS 1 struct epoll_event events[MAXEVENTS]; int timeout = -1; int wait_errno; if (tvalp) { /* it's better to trigger timed events a bit later than too early */ timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000); } if (epoll_ev->ev->signal_events && tevent_common_check_signal(epoll_ev->ev)) { return 0; } tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout); wait_errno = errno; tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_AFTER_WAIT); if (ret == -1 && wait_errno == EINTR && epoll_ev->ev->signal_events) { if (tevent_common_check_signal(epoll_ev->ev)) { return 0; } } if (ret == -1 && wait_errno != EINTR) { epoll_panic(epoll_ev, "epoll_wait() failed", true); return -1; } if (ret == 0 && tvalp) { /* we don't care about a possible delay here */ tevent_common_loop_timer_delay(epoll_ev->ev); return 0; } for (i=0;iadditional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * Save off the multiplexed event in case we need * to use it to call the handler function. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); } if (events[i].events & (EPOLLHUP|EPOLLERR)) { bool handled_fde = epoll_handle_hup_or_err(epoll_ev, fde); bool handled_mpx = epoll_handle_hup_or_err(epoll_ev, mpx_fde); if (handled_fde && handled_mpx) { epoll_update_event(epoll_ev, fde); continue; } if (!handled_mpx) { /* * If the mpx event was the one that needs * further handling, it's the TEVENT_FD_READ * event so switch over and call that handler. */ fde = mpx_fde; mpx_fde = NULL; } flags |= TEVENT_FD_READ; } if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ; if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE; if (flags & TEVENT_FD_WRITE) { if (fde->flags & TEVENT_FD_WRITE) { mpx_fde = NULL; } if (mpx_fde && mpx_fde->flags & TEVENT_FD_WRITE) { fde = mpx_fde; mpx_fde = NULL; } } if (mpx_fde) { /* Ensure we got the right fde. */ if ((flags & fde->flags) == 0) { fde = mpx_fde; mpx_fde = NULL; } } /* * make sure we only pass the flags * the handler is expecting. */ flags &= fde->flags; if (flags) { return tevent_common_invoke_fd_handler(fde, flags, NULL); } } return 0; } /* create a epoll_event_context structure. */ static int epoll_event_context_init(struct tevent_context *ev) { int ret; struct epoll_event_context *epoll_ev; /* * We might be called during tevent_re_initialise() * which means we need to free our old additional_data. */ TALLOC_FREE(ev->additional_data); epoll_ev = talloc_zero(ev, struct epoll_event_context); if (!epoll_ev) return -1; epoll_ev->ev = ev; epoll_ev->epoll_fd = -1; ret = epoll_init_ctx(epoll_ev); if (ret != 0) { talloc_free(epoll_ev); return ret; } ev->additional_data = epoll_ev; return 0; } /* destroy an fd_event */ static int epoll_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; struct epoll_event_context *epoll_ev = NULL; bool panic_triggered = false; struct tevent_fd *mpx_fde = NULL; int flags = fde->flags; if (ev == NULL) { return tevent_common_fd_destructor(fde); } epoll_ev = talloc_get_type_abort(ev->additional_data, struct epoll_event_context); /* * we must remove the event from the list * otherwise a panic fallback handler may * reuse invalid memory */ DLIST_REMOVE(ev->fd_events, fde); if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; fde->additional_data = NULL; mpx_fde->additional_data = NULL; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; } epoll_ev->panic_state = &panic_triggered; epoll_check_reopen(epoll_ev); if (panic_triggered) { return tevent_common_fd_destructor(fde); } if (mpx_fde != NULL) { epoll_update_event(epoll_ev, mpx_fde); if (panic_triggered) { return tevent_common_fd_destructor(fde); } } fde->flags = 0; epoll_update_event(epoll_ev, fde); fde->flags = flags; if (panic_triggered) { return tevent_common_fd_destructor(fde); } epoll_ev->panic_state = NULL; return tevent_common_fd_destructor(fde); } /* add a fd based event return NULL on failure (memory allocation error) */ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct epoll_event_context *epoll_ev = talloc_get_type_abort(ev->additional_data, struct epoll_event_context); struct tevent_fd *fde; bool panic_triggered = false; fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, handler, private_data, handler_name, location); if (!fde) return NULL; talloc_set_destructor(fde, epoll_event_fd_destructor); epoll_ev->panic_state = &panic_triggered; epoll_check_reopen(epoll_ev); if (panic_triggered) { return fde; } epoll_ev->panic_state = NULL; epoll_update_event(epoll_ev, fde); return fde; } /* set the fd event flags */ static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) { struct tevent_context *ev; struct epoll_event_context *epoll_ev; bool panic_triggered = false; if (fde->flags == flags) return; ev = fde->event_ctx; epoll_ev = talloc_get_type_abort(ev->additional_data, struct epoll_event_context); fde->flags = flags; epoll_ev->panic_state = &panic_triggered; epoll_check_reopen(epoll_ev); if (panic_triggered) { return; } epoll_ev->panic_state = NULL; epoll_update_event(epoll_ev, fde); } /* do a single event loop using the events defined in ev */ static int epoll_event_loop_once(struct tevent_context *ev, const char *location) { struct epoll_event_context *epoll_ev = talloc_get_type_abort(ev->additional_data, struct epoll_event_context); struct timeval tval; bool panic_triggered = false; if (ev->signal_events && tevent_common_check_signal(ev)) { return 0; } if (ev->threaded_contexts != NULL) { tevent_common_threaded_activate_immediate(ev); } if (ev->immediate_events && tevent_common_loop_immediate(ev)) { return 0; } tval = tevent_common_loop_timer_delay(ev); if (tevent_timeval_is_zero(&tval)) { return 0; } epoll_ev->panic_state = &panic_triggered; epoll_ev->panic_force_replay = true; epoll_check_reopen(epoll_ev); if (panic_triggered) { errno = EINVAL; return -1; } epoll_ev->panic_force_replay = false; epoll_ev->panic_state = NULL; return epoll_event_loop(epoll_ev, &tval); } static const struct tevent_ops epoll_event_ops = { .context_init = epoll_event_context_init, .add_fd = epoll_event_add_fd, .set_fd_close_fn = tevent_common_fd_set_close_fn, .get_fd_flags = tevent_common_fd_get_flags, .set_fd_flags = epoll_event_set_fd_flags, .add_timer = tevent_common_add_timer_v2, .schedule_immediate = tevent_common_schedule_immediate, .add_signal = tevent_common_add_signal, .loop_once = epoll_event_loop_once, .loop_wait = tevent_common_loop_wait, }; _PRIVATE_ bool tevent_epoll_init(void) { return tevent_register_backend("epoll", &epoll_event_ops); } ldb-2.0.8/lib/tevent/tevent_fd.c0000660000000000000000000000742313573675413016437 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. common events code for fd events Copyright (C) Stefan Metzmacher 2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" int tevent_common_fd_destructor(struct tevent_fd *fde) { if (fde->destroyed) { tevent_common_check_double_free(fde, "tevent_fd double free"); goto done; } fde->destroyed = true; if (fde->event_ctx) { DLIST_REMOVE(fde->event_ctx->fd_events, fde); } if (fde->close_fn) { fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data); fde->fd = -1; fde->close_fn = NULL; } fde->event_ctx = NULL; done: if (fde->busy) { return -1; } fde->wrapper = NULL; return 0; } struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct tevent_fd *fde; /* tevent will crash later on select() if we save * a negative file descriptor. Better to fail here * so that consumers will be able to debug it */ if (fd < 0) return NULL; fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); if (!fde) return NULL; *fde = (struct tevent_fd) { .event_ctx = ev, .fd = fd, .flags = flags, .handler = handler, .private_data = private_data, .handler_name = handler_name, .location = location, }; DLIST_ADD(ev->fd_events, fde); talloc_set_destructor(fde, tevent_common_fd_destructor); return fde; } uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde) { return fde->flags; } void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags) { if (fde->flags == flags) return; fde->flags = flags; } void tevent_common_fd_set_close_fn(struct tevent_fd *fde, tevent_fd_close_fn_t close_fn) { fde->close_fn = close_fn; } int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, bool *removed) { struct tevent_context *handler_ev = fde->event_ctx; if (removed != NULL) { *removed = false; } if (fde->event_ctx == NULL) { return 0; } fde->busy = true; if (fde->wrapper != NULL) { handler_ev = fde->wrapper->wrap_ev; tevent_wrapper_push_use_internal(handler_ev, fde->wrapper); fde->wrapper->ops->before_fd_handler( fde->wrapper->wrap_ev, fde->wrapper->private_state, fde->wrapper->main_ev, fde, flags, fde->handler_name, fde->location); } fde->handler(handler_ev, fde, flags, fde->private_data); if (fde->wrapper != NULL) { fde->wrapper->ops->after_fd_handler( fde->wrapper->wrap_ev, fde->wrapper->private_state, fde->wrapper->main_ev, fde, flags, fde->handler_name, fde->location); tevent_wrapper_pop_use_internal(handler_ev, fde->wrapper); } fde->busy = false; if (fde->destroyed) { talloc_set_destructor(fde, NULL); TALLOC_FREE(fde); if (removed != NULL) { *removed = true; } } return 0; } ldb-2.0.8/lib/tevent/tevent_immediate.c0000660000000000000000000001152013573675413017775 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. common events code for immediate events Copyright (C) Stefan Metzmacher 2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" static void tevent_common_immediate_cancel(struct tevent_immediate *im) { const char *create_location = im->create_location; bool busy = im->busy; if (im->destroyed) { tevent_abort(im->event_ctx, "tevent_immediate use after free"); return; } if (!im->event_ctx) { return; } if (im->handler_name != NULL) { tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE, "Cancel immediate event %p \"%s\"\n", im, im->handler_name); } /* let the backend free im->additional_data */ if (im->cancel_fn) { im->cancel_fn(im); } DLIST_REMOVE(im->event_ctx->immediate_events, im); *im = (struct tevent_immediate) { .create_location = create_location, .busy = busy, }; if (!busy) { talloc_set_destructor(im, NULL); } } /* destroy an immediate event */ static int tevent_common_immediate_destructor(struct tevent_immediate *im) { if (im->destroyed) { tevent_common_check_double_free(im, "tevent_immediate double free"); goto done; } tevent_common_immediate_cancel(im); im->destroyed = true; done: if (im->busy) { return -1; } return 0; } /* * schedule an immediate event on */ void tevent_common_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ev, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location) { const char *create_location = im->create_location; bool busy = im->busy; struct tevent_wrapper_glue *glue = im->wrapper; tevent_common_immediate_cancel(im); if (!handler) { return; } *im = (struct tevent_immediate) { .event_ctx = ev, .wrapper = glue, .handler = handler, .private_data = private_data, .handler_name = handler_name, .create_location = create_location, .schedule_location = location, .busy = busy, }; DLIST_ADD_END(ev->immediate_events, im); talloc_set_destructor(im, tevent_common_immediate_destructor); tevent_debug(ev, TEVENT_DEBUG_TRACE, "Schedule immediate event \"%s\": %p\n", handler_name, im); } int tevent_common_invoke_immediate_handler(struct tevent_immediate *im, bool *removed) { struct tevent_context *handler_ev = im->event_ctx; struct tevent_context *ev = im->event_ctx; struct tevent_immediate cur = *im; if (removed != NULL) { *removed = false; } tevent_debug(ev, TEVENT_DEBUG_TRACE, "Run immediate event \"%s\": %p\n", im->handler_name, im); /* * remember the handler and then clear the event * the handler might reschedule the event */ im->busy = true; im->handler_name = NULL; tevent_common_immediate_cancel(im); if (cur.wrapper != NULL) { handler_ev = cur.wrapper->wrap_ev; tevent_wrapper_push_use_internal(handler_ev, cur.wrapper); cur.wrapper->ops->before_immediate_handler( cur.wrapper->wrap_ev, cur.wrapper->private_state, cur.wrapper->main_ev, im, cur.handler_name, cur.schedule_location); } cur.handler(handler_ev, im, cur.private_data); if (cur.wrapper != NULL) { cur.wrapper->ops->after_immediate_handler( cur.wrapper->wrap_ev, cur.wrapper->private_state, cur.wrapper->main_ev, im, cur.handler_name, cur.schedule_location); tevent_wrapper_pop_use_internal(handler_ev, cur.wrapper); } im->busy = false; if (im->destroyed) { talloc_set_destructor(im, NULL); TALLOC_FREE(im); if (removed != NULL) { *removed = true; } } return 0; } /* trigger the first immediate event and return true if no event was triggered return false */ bool tevent_common_loop_immediate(struct tevent_context *ev) { struct tevent_immediate *im = ev->immediate_events; int ret; if (!im) { return false; } ret = tevent_common_invoke_immediate_handler(im, NULL); if (ret != 0) { tevent_abort(ev, "tevent_common_invoke_immediate_handler() failed"); } return true; } ldb-2.0.8/lib/tevent/tevent_internal.h0000660000000000000000000003223613444661620017657 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. generalised event loop handling INTERNAL STRUCTS. THERE ARE NO API GUARANTEES. External users should only ever have to include this header when implementing new tevent backends. Copyright (C) Stefan Metzmacher 2005-2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ struct tevent_req { /** * @brief What to do on completion * * This is used for the user of an async request, fn is called when * the request completes, either successfully or with an error. */ struct { /** * @brief Completion function * Completion function, to be filled by the API user */ tevent_req_fn fn; /** * @brief Private data for the completion function */ void *private_data; } async; /** * @brief Private state pointer for the actual implementation * * The implementation doing the work for the async request needs to * keep around current data like for example a fd event. The user of * an async request should not touch this. */ void *data; /** * @brief A function to overwrite the default print function * * The implementation doing the work may want to implement a * custom function to print the text representation of the async * request. */ tevent_req_print_fn private_print; /** * @brief A function to cancel the request * * The implementation might want to set a function * that is called when the tevent_req_cancel() function * was called. */ tevent_req_cancel_fn private_cancel; /** * @brief A function to cleanup the request * * The implementation might want to set a function * that is called before the tevent_req_done() and tevent_req_error() * trigger the callers callback function. */ struct { tevent_req_cleanup_fn fn; enum tevent_req_state state; } private_cleanup; /** * @brief Internal state of the request * * Callers should only access this via functions and never directly. */ struct { /** * @brief The talloc type of the data pointer * * This is filled by the tevent_req_create() macro. * * This for debugging only. */ const char *private_type; /** * @brief The location where the request was created * * This uses the __location__ macro via the tevent_req_create() * macro. * * This for debugging only. */ const char *create_location; /** * @brief The location where the request was finished * * This uses the __location__ macro via the tevent_req_done(), * tevent_req_error() or tevent_req_nomem() macro. * * This for debugging only. */ const char *finish_location; /** * @brief The location where the request was canceled * * This uses the __location__ macro via the * tevent_req_cancel() macro. * * This for debugging only. */ const char *cancel_location; /** * @brief The external state - will be queried by the caller * * While the async request is being processed, state will remain in * TEVENT_REQ_IN_PROGRESS. A request is finished if * req->state>=TEVENT_REQ_DONE. */ enum tevent_req_state state; /** * @brief status code when finished * * This status can be queried in the async completion function. It * will be set to 0 when everything went fine. */ uint64_t error; /** * @brief the immediate event used by tevent_req_post * */ struct tevent_immediate *trigger; /** * @brief An event context which will be used to * defer the _tevent_req_notify_callback(). */ struct tevent_context *defer_callback_ev; /** * @brief the timer event if tevent_req_set_endtime was used * */ struct tevent_timer *timer; /** * @brief The place where profiling data is kept */ struct tevent_req_profile *profile; } internal; }; struct tevent_req_profile { struct tevent_req_profile *prev, *next; struct tevent_req_profile *parent; const char *req_name; pid_t pid; const char *start_location; struct timeval start_time; const char *stop_location; struct timeval stop_time; enum tevent_req_state state; uint64_t user_error; struct tevent_req_profile *subprofiles; }; struct tevent_fd { struct tevent_fd *prev, *next; struct tevent_context *event_ctx; struct tevent_wrapper_glue *wrapper; bool busy; bool destroyed; int fd; uint16_t flags; /* see TEVENT_FD_* flags */ tevent_fd_handler_t handler; tevent_fd_close_fn_t close_fn; /* this is private for the specific handler */ void *private_data; /* this is for debugging only! */ const char *handler_name; const char *location; /* this is private for the events_ops implementation */ uint64_t additional_flags; void *additional_data; }; struct tevent_timer { struct tevent_timer *prev, *next; struct tevent_context *event_ctx; struct tevent_wrapper_glue *wrapper; bool busy; bool destroyed; struct timeval next_event; tevent_timer_handler_t handler; /* this is private for the specific handler */ void *private_data; /* this is for debugging only! */ const char *handler_name; const char *location; /* this is private for the events_ops implementation */ void *additional_data; }; struct tevent_immediate { struct tevent_immediate *prev, *next; struct tevent_context *event_ctx; struct tevent_wrapper_glue *wrapper; bool busy; bool destroyed; tevent_immediate_handler_t handler; /* this is private for the specific handler */ void *private_data; /* this is for debugging only! */ const char *handler_name; const char *create_location; const char *schedule_location; /* this is private for the events_ops implementation */ void (*cancel_fn)(struct tevent_immediate *im); void *additional_data; }; struct tevent_signal { struct tevent_signal *prev, *next; struct tevent_context *event_ctx; struct tevent_wrapper_glue *wrapper; bool busy; bool destroyed; int signum; int sa_flags; tevent_signal_handler_t handler; /* this is private for the specific handler */ void *private_data; /* this is for debugging only! */ const char *handler_name; const char *location; /* this is private for the events_ops implementation */ void *additional_data; }; struct tevent_threaded_context { struct tevent_threaded_context *next, *prev; #ifdef HAVE_PTHREAD pthread_mutex_t event_ctx_mutex; #endif struct tevent_context *event_ctx; }; struct tevent_debug_ops { void (*debug)(void *context, enum tevent_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); void *context; }; void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); void tevent_abort(struct tevent_context *ev, const char *reason); void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason); struct tevent_context { /* the specific events implementation */ const struct tevent_ops *ops; /* * The following three pointers are queried on every loop_once * in the order in which they appear here. Not measured, but * hopefully putting them at the top together with "ops" * should make tevent a *bit* more cache-friendly than before. */ /* list of signal events - used by common code */ struct tevent_signal *signal_events; /* List of threaded job indicators */ struct tevent_threaded_context *threaded_contexts; /* list of immediate events - used by common code */ struct tevent_immediate *immediate_events; /* list of fd events - used by common code */ struct tevent_fd *fd_events; /* list of timed events - used by common code */ struct tevent_timer *timer_events; /* List of scheduled immediates */ pthread_mutex_t scheduled_mutex; struct tevent_immediate *scheduled_immediates; /* this is private for the events_ops implementation */ void *additional_data; /* pipe hack used with signal handlers */ struct tevent_fd *wakeup_fde; int wakeup_fd; /* fd to write into */ #ifndef HAVE_EVENT_FD int wakeup_read_fd; #endif /* debugging operations */ struct tevent_debug_ops debug_ops; /* info about the nesting status */ struct { bool allowed; uint32_t level; tevent_nesting_hook hook_fn; void *hook_private; } nesting; struct { tevent_trace_callback_t callback; void *private_data; } tracing; struct { /* * This is used on the main event context */ struct tevent_wrapper_glue *list; /* * This is used on the wrapper event context */ struct tevent_wrapper_glue *glue; } wrapper; /* * an optimization pointer into timer_events * used by used by common code via * tevent_common_add_timer_v2() */ struct tevent_timer *last_zero_timer; #ifdef HAVE_PTHREAD struct tevent_context *prev, *next; #endif }; const struct tevent_ops *tevent_find_ops_byname(const char *name); int tevent_common_context_destructor(struct tevent_context *ev); int tevent_common_loop_wait(struct tevent_context *ev, const char *location); int tevent_common_fd_destructor(struct tevent_fd *fde); struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location); void tevent_common_fd_set_close_fn(struct tevent_fd *fde, tevent_fd_close_fn_t close_fn); uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde); void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags); int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, bool *removed); struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location); struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location); struct timeval tevent_common_loop_timer_delay(struct tevent_context *); int tevent_common_invoke_timer_handler(struct tevent_timer *te, struct timeval current_time, bool *removed); void tevent_common_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ev, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location); int tevent_common_invoke_immediate_handler(struct tevent_immediate *im, bool *removed); bool tevent_common_loop_immediate(struct tevent_context *ev); void tevent_common_threaded_activate_immediate(struct tevent_context *ev); bool tevent_common_have_events(struct tevent_context *ev); int tevent_common_wakeup_init(struct tevent_context *ev); int tevent_common_wakeup_fd(int fd); int tevent_common_wakeup(struct tevent_context *ev); struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data, const char *handler_name, const char *location); int tevent_common_check_signal(struct tevent_context *ev); void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se); int tevent_common_invoke_signal_handler(struct tevent_signal *se, int signum, int count, void *siginfo, bool *removed); struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev); struct tevent_wrapper_ops; struct tevent_wrapper_glue { struct tevent_wrapper_glue *prev, *next; struct tevent_context *wrap_ev; struct tevent_context *main_ev; bool busy; bool destroyed; const struct tevent_wrapper_ops *ops; void *private_state; }; void tevent_wrapper_push_use_internal(struct tevent_context *ev, struct tevent_wrapper_glue *wrapper); void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr, struct tevent_wrapper_glue *wrapper); bool tevent_standard_init(void); bool tevent_poll_init(void); bool tevent_poll_event_add_fd_internal(struct tevent_context *ev, struct tevent_fd *fde); bool tevent_poll_mt_init(void); #ifdef HAVE_EPOLL bool tevent_epoll_init(void); void tevent_epoll_set_panic_fallback(struct tevent_context *ev, bool (*panic_fallback)(struct tevent_context *ev, bool replay)); #endif #ifdef HAVE_SOLARIS_PORTS bool tevent_port_init(void); #endif void tevent_trace_point_callback(struct tevent_context *ev, enum tevent_trace_point); ldb-2.0.8/lib/tevent/tevent_liboop.c0000660000000000000000000001576012406075657017333 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. main select loop and event handling wrapper for http://git.lysator.liu.se/liboop/ Copyright (C) Stefan Metzmacher 2005 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "events.h" #include "events_internal.h" #include /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NOTE: this code compiles fine, but is completely *UNTESTED* and is only committed as an example !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ static int oop_event_context_destructor(struct tevent_context *ev) { oop_source_sys *oop_sys = ev->additional_data; oop_sys_delete(oop_sys); return 0; } /* create a oop_event_context structure. */ static int oop_event_context_init(struct tevent_context *ev, void *private_data) { oop_source_sys *oop_sys = private_data; if (!oop_sys) { oop_sys = oop_sys_new(); if (!oop_sys) { return -1; } talloc_set_destructor(ev, oop_event_context_destructor); } ev->additional_data = oop_sys; return 0; } static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr) { struct tevent_fd *fde = ptr; if (fd != fde->fd) return OOP_ERROR; switch(oop_type) { case OOP_READ: fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data); return OOP_CONTINUE; case OOP_WRITE: fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data); return OOP_CONTINUE; case OOP_EXCEPTION: return OOP_ERROR; case OOP_NUM_EVENTS: return OOP_ERROR; } return OOP_ERROR; } /* destroy an fd_event */ static int oop_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; oop_source_sys *oop_sys = ev->additional_data; oop_source *oop = oop_sys_source(oop_sys); if (fde->flags & EVENT_FD_READ) oop->cancel_fd(oop, fde->fd, OOP_READ); if (fde->flags & EVENT_FD_WRITE) oop->cancel_fd(oop, fde->fd, OOP_WRITE); if (fde->flags & EVENT_FD_AUTOCLOSE) { close(fde->fd); fde->fd = -1; } return 0; } /* add a fd based event return NULL on failure (memory allocation error) */ static struct tevent_fd *oop_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, event_fd_handler_t handler, void *private_data) { struct tevent_fd *fde; oop_source_sys *oop_sys = ev->additional_data; oop_source *oop = oop_sys_source(oop_sys); fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); if (!fde) return NULL; fde->event_ctx = ev; fde->fd = fd; fde->flags = flags; fde->handler = handler; fde->private_data = private_data; fde->additional_flags = 0; fde->additional_data = NULL; if (fde->flags & EVENT_FD_READ) oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); if (fde->flags & EVENT_FD_WRITE) oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); talloc_set_destructor(fde, oop_event_fd_destructor); return fde; } /* return the fd event flags */ static uint16_t oop_event_get_fd_flags(struct tevent_fd *fde) { return fde->flags; } /* set the fd event flags */ static void oop_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) { oop_source_sys *oop_sys; oop_source *oop; oop_sys = fde->event_ctx->additional_data; oop = oop_sys_source(oop_sys); if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ))) oop->cancel_fd(oop, fde->fd, OOP_READ); if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ)) oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE))) oop->cancel_fd(oop, fde->fd, OOP_WRITE); if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE)) oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); fde->flags = flags; } static int oop_event_timed_destructor(struct tevent_timer *te); static int oop_event_timed_deny_destructor(struct tevent_timer *te) { return -1; } static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr) { struct tevent_timer *te = ptr; /* deny the handler to free the event */ talloc_set_destructor(te, oop_event_timed_deny_destructor); te->handler(te->event_ctx, te, t, te->private_data); talloc_set_destructor(te, oop_event_timed_destructor); talloc_free(te); return OOP_CONTINUE; } /* destroy a timed event */ static int oop_event_timed_destructor(struct tevent_timer *te) { struct tevent_context *ev = te->event_ctx; oop_source_sys *oop_sys = ev->additional_data; oop_source *oop = oop_sys_source(oop_sys); oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te); return 0; } /* add a timed event return NULL on failure (memory allocation error) */ static struct tevent_timer *oop_event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, event_timed_handler_t handler, void *private_data) { oop_source_sys *oop_sys = ev->additional_data; oop_source *oop = oop_sys_source(oop_sys); struct tevent_timer *te; te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); if (te == NULL) return NULL; te->event_ctx = ev; te->next_event = next_event; te->handler = handler; te->private_data = private_data; te->additional_data = NULL; oop->on_time(oop, te->next_event, oop_event_timed_handler, te); talloc_set_destructor(te, oop_event_timed_destructor); return te; } /* do a single event loop using the events defined in ev */ static int oop_event_loop_once(struct tevent_context *ev) { void *oop_ret; oop_source_sys *oop_sys = ev->additional_data; oop_ret = oop_sys_run_once(oop_sys); if (oop_ret == OOP_CONTINUE) { return 0; } return -1; } /* return on failure or (with 0) if all fd events are removed */ static int oop_event_loop_wait(struct tevent_context *ev) { void *oop_ret; oop_source_sys *oop_sys = ev->additional_data; oop_ret = oop_sys_run(oop_sys); if (oop_ret == OOP_CONTINUE) { return 0; } return -1; } static const struct event_ops event_oop_ops = { .context_init = oop_event_context_init, .add_fd = oop_event_add_fd, .get_fd_flags = oop_event_get_fd_flags, .set_fd_flags = oop_event_set_fd_flags, .add_timer = oop_event_add_timed, .add_signal = common_event_add_signal, .loop_once = oop_event_loop_once, .loop_wait = oop_event_loop_wait, }; const struct event_ops *event_liboop_get_ops(void) { return &event_oop_ops; } ldb-2.0.8/lib/tevent/tevent_poll.c0000660000000000000000000003610613444661620017004 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. main select loop and event handling Copyright (C) Andrew Tridgell 2003-2005 Copyright (C) Stefan Metzmacher 2005-2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/select.h" #include "tevent.h" #include "tevent_util.h" #include "tevent_internal.h" struct poll_event_context { /* a pointer back to the generic event_context */ struct tevent_context *ev; /* * one or more events were deleted or disabled */ bool deleted; /* * These two arrays are maintained together. * * The following is always true: * num_fds <= num_fdes * * new 'fresh' elements are added at the end * of the 'fdes' array and picked up later * to the 'fds' array in poll_event_sync_arrays() * before the poll() syscall. */ struct pollfd *fds; size_t num_fds; struct tevent_fd **fdes; size_t num_fdes; /* * use tevent_common_wakeup(ev) to wake the poll() thread */ bool use_mt_mode; }; /* create a poll_event_context structure. */ static int poll_event_context_init(struct tevent_context *ev) { struct poll_event_context *poll_ev; /* * we might be called during tevent_re_initialise() * which means we need to free our old additional_data * in order to detach old fd events from the * poll_ev->fresh list */ TALLOC_FREE(ev->additional_data); poll_ev = talloc_zero(ev, struct poll_event_context); if (poll_ev == NULL) { return -1; } poll_ev->ev = ev; ev->additional_data = poll_ev; return 0; } static int poll_event_context_init_mt(struct tevent_context *ev) { struct poll_event_context *poll_ev; int ret; ret = poll_event_context_init(ev); if (ret == -1) { return ret; } poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); ret = tevent_common_wakeup_init(ev); if (ret != 0) { return ret; } poll_ev->use_mt_mode = true; return 0; } static void poll_event_wake_pollthread(struct poll_event_context *poll_ev) { if (!poll_ev->use_mt_mode) { return; } tevent_common_wakeup(poll_ev->ev); } /* destroy an fd_event */ static int poll_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; struct poll_event_context *poll_ev; uint64_t del_idx = fde->additional_flags; if (ev == NULL) { goto done; } poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); if (del_idx == UINT64_MAX) { goto done; } poll_ev->fdes[del_idx] = NULL; poll_ev->deleted = true; poll_event_wake_pollthread(poll_ev); done: return tevent_common_fd_destructor(fde); } static void poll_event_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ev, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct poll_event_context *poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); tevent_common_schedule_immediate(im, ev, handler, private_data, handler_name, location); poll_event_wake_pollthread(poll_ev); } /* Private function called by "standard" backend fallback. Note this only allows fallback to "poll" backend, not "poll-mt". */ _PRIVATE_ bool tevent_poll_event_add_fd_internal(struct tevent_context *ev, struct tevent_fd *fde) { struct poll_event_context *poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); uint64_t fde_idx = UINT64_MAX; size_t num_fdes; fde->additional_flags = UINT64_MAX; talloc_set_destructor(fde, poll_event_fd_destructor); if (fde->flags == 0) { /* * Nothing more to do... */ return true; } /* * We need to add it to the end of the 'fdes' array. */ num_fdes = poll_ev->num_fdes + 1; if (num_fdes > talloc_array_length(poll_ev->fdes)) { struct tevent_fd **tmp_fdes = NULL; size_t array_length; array_length = (num_fdes + 15) & ~15; /* round up to 16 */ tmp_fdes = talloc_realloc(poll_ev, poll_ev->fdes, struct tevent_fd *, array_length); if (tmp_fdes == NULL) { return false; } poll_ev->fdes = tmp_fdes; } fde_idx = poll_ev->num_fdes; fde->additional_flags = fde_idx; poll_ev->fdes[fde_idx] = fde; poll_ev->num_fdes++; return true; } /* add a fd based event return NULL on failure (memory allocation error) */ static struct tevent_fd *poll_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct poll_event_context *poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); struct tevent_fd *fde; bool ok; if (fd < 0) { return NULL; } fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, handler, private_data, handler_name, location); if (fde == NULL) { return NULL; } ok = tevent_poll_event_add_fd_internal(ev, fde); if (!ok) { TALLOC_FREE(fde); return NULL; } poll_event_wake_pollthread(poll_ev); /* * poll_event_loop_poll will take care of the rest in * poll_event_setup_fresh */ return fde; } /* set the fd event flags */ static void poll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) { struct tevent_context *ev = fde->event_ctx; struct poll_event_context *poll_ev; uint64_t idx = fde->additional_flags; uint16_t pollflags; if (ev == NULL) { return; } if (fde->flags == flags) { return; } poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); fde->flags = flags; if (idx == UINT64_MAX) { /* * We move it between the fresh and disabled lists. */ tevent_poll_event_add_fd_internal(ev, fde); poll_event_wake_pollthread(poll_ev); return; } if (fde->flags == 0) { /* * We need to remove it from the array * and move it to the disabled list. */ poll_ev->fdes[idx] = NULL; poll_ev->deleted = true; fde->additional_flags = UINT64_MAX; poll_event_wake_pollthread(poll_ev); return; } if (idx >= poll_ev->num_fds) { /* * Not yet added to the * poll_ev->fds array. */ poll_event_wake_pollthread(poll_ev); return; } pollflags = 0; if (flags & TEVENT_FD_READ) { pollflags |= (POLLIN|POLLHUP); } if (flags & TEVENT_FD_WRITE) { pollflags |= (POLLOUT); } poll_ev->fds[idx].events = pollflags; poll_event_wake_pollthread(poll_ev); } static bool poll_event_sync_arrays(struct tevent_context *ev, struct poll_event_context *poll_ev) { size_t i; size_t array_length; if (poll_ev->deleted) { for (i=0; i < poll_ev->num_fds;) { struct tevent_fd *fde = poll_ev->fdes[i]; size_t ci; if (fde != NULL) { i++; continue; } /* * This fde was talloc_free()'ed. Delete it * from the arrays */ poll_ev->num_fds -= 1; ci = poll_ev->num_fds; if (ci > i) { poll_ev->fds[i] = poll_ev->fds[ci]; poll_ev->fdes[i] = poll_ev->fdes[ci]; if (poll_ev->fdes[i] != NULL) { poll_ev->fdes[i]->additional_flags = i; } } poll_ev->fds[ci] = (struct pollfd) { .fd = -1 }; poll_ev->fdes[ci] = NULL; } poll_ev->deleted = false; } if (poll_ev->num_fds == poll_ev->num_fdes) { return true; } /* * Recheck the size of both arrays and make sure * poll_fd->fds array has at least the size of the * in use poll_ev->fdes array. */ if (poll_ev->num_fdes > talloc_array_length(poll_ev->fds)) { struct pollfd *tmp_fds = NULL; /* * Make sure both allocated the same length. */ array_length = talloc_array_length(poll_ev->fdes); tmp_fds = talloc_realloc(poll_ev, poll_ev->fds, struct pollfd, array_length); if (tmp_fds == NULL) { return false; } poll_ev->fds = tmp_fds; } /* * Now setup the new elements. */ for (i = poll_ev->num_fds; i < poll_ev->num_fdes; i++) { struct tevent_fd *fde = poll_ev->fdes[i]; struct pollfd *pfd = &poll_ev->fds[poll_ev->num_fds]; if (fde == NULL) { continue; } if (i > poll_ev->num_fds) { poll_ev->fdes[poll_ev->num_fds] = fde; fde->additional_flags = poll_ev->num_fds; poll_ev->fdes[i] = NULL; } pfd->fd = fde->fd; pfd->events = 0; pfd->revents = 0; if (fde->flags & TEVENT_FD_READ) { pfd->events |= (POLLIN|POLLHUP); } if (fde->flags & TEVENT_FD_WRITE) { pfd->events |= (POLLOUT); } poll_ev->num_fds += 1; } /* Both are in sync again */ poll_ev->num_fdes = poll_ev->num_fds; /* * Check if we should shrink the arrays * But keep at least 16 elements. */ array_length = (poll_ev->num_fds + 15) & ~15; /* round up to 16 */ array_length = MAX(array_length, 16); if (array_length < talloc_array_length(poll_ev->fdes)) { struct tevent_fd **tmp_fdes = NULL; struct pollfd *tmp_fds = NULL; tmp_fdes = talloc_realloc(poll_ev, poll_ev->fdes, struct tevent_fd *, array_length); if (tmp_fdes == NULL) { return false; } poll_ev->fdes = tmp_fdes; tmp_fds = talloc_realloc(poll_ev, poll_ev->fds, struct pollfd, array_length); if (tmp_fds == NULL) { return false; } poll_ev->fds = tmp_fds; } return true; } /* event loop handling using poll() */ static int poll_event_loop_poll(struct tevent_context *ev, struct timeval *tvalp) { struct poll_event_context *poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); int pollrtn; int timeout = -1; int poll_errno; struct tevent_fd *fde = NULL; struct tevent_fd *next = NULL; unsigned i; bool ok; if (ev->signal_events && tevent_common_check_signal(ev)) { return 0; } if (tvalp != NULL) { timeout = tvalp->tv_sec * 1000; timeout += (tvalp->tv_usec + 999) / 1000; } ok = poll_event_sync_arrays(ev, poll_ev); if (!ok) { return -1; } tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); pollrtn = poll(poll_ev->fds, poll_ev->num_fds, timeout); poll_errno = errno; tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_AFTER_WAIT); if (pollrtn == -1 && poll_errno == EINTR && ev->signal_events) { tevent_common_check_signal(ev); return 0; } if (pollrtn == 0 && tvalp) { /* we don't care about a possible delay here */ tevent_common_loop_timer_delay(ev); return 0; } if (pollrtn <= 0) { /* * No fd's ready */ return 0; } /* at least one file descriptor is ready - check which ones and call the handler, being careful to allow the handler to remove itself when called */ for (fde = ev->fd_events; fde; fde = next) { uint64_t idx = fde->additional_flags; struct pollfd *pfd; uint16_t flags = 0; next = fde->next; if (idx == UINT64_MAX) { continue; } pfd = &poll_ev->fds[idx]; if (pfd->revents & POLLNVAL) { /* * the socket is dead! this should never * happen as the socket should have first been * made readable and that should have removed * the event, so this must be a bug. * * We ignore it here to match the epoll * behavior. */ tevent_debug(ev, TEVENT_DEBUG_ERROR, "POLLNVAL on fde[%p] fd[%d] - disabling\n", fde, pfd->fd); poll_ev->fdes[idx] = NULL; poll_ev->deleted = true; DLIST_REMOVE(ev->fd_events, fde); fde->wrapper = NULL; fde->event_ctx = NULL; continue; } if (pfd->revents & (POLLHUP|POLLERR)) { /* If we only wait for TEVENT_FD_WRITE, we should not tell the event handler about it, and remove the writable flag, as we only report errors when waiting for read events to match the select behavior. */ if (!(fde->flags & TEVENT_FD_READ)) { TEVENT_FD_NOT_WRITEABLE(fde); continue; } flags |= TEVENT_FD_READ; } if (pfd->revents & POLLIN) { flags |= TEVENT_FD_READ; } if (pfd->revents & POLLOUT) { flags |= TEVENT_FD_WRITE; } /* * Note that fde->flags could be changed when using * the poll_mt backend together with threads, * that why we need to check pfd->revents and fde->flags */ flags &= fde->flags; if (flags != 0) { DLIST_DEMOTE(ev->fd_events, fde); return tevent_common_invoke_fd_handler(fde, flags, NULL); } } for (i = 0; i < poll_ev->num_fds; i++) { if (poll_ev->fds[i].revents & POLLNVAL) { /* * the socket is dead! this should never * happen as the socket should have first been * made readable and that should have removed * the event, so this must be a bug or * a race in the poll_mt usage. */ fde = poll_ev->fdes[i]; tevent_debug(ev, TEVENT_DEBUG_WARNING, "POLLNVAL on dangling fd[%d] fde[%p] - disabling\n", poll_ev->fds[i].fd, fde); poll_ev->fdes[i] = NULL; poll_ev->deleted = true; if (fde != NULL) { DLIST_REMOVE(ev->fd_events, fde); fde->wrapper = NULL; fde->event_ctx = NULL; } } } return 0; } /* do a single event loop using the events defined in ev */ static int poll_event_loop_once(struct tevent_context *ev, const char *location) { struct timeval tval; if (ev->signal_events && tevent_common_check_signal(ev)) { return 0; } if (ev->threaded_contexts != NULL) { tevent_common_threaded_activate_immediate(ev); } if (ev->immediate_events && tevent_common_loop_immediate(ev)) { return 0; } tval = tevent_common_loop_timer_delay(ev); if (tevent_timeval_is_zero(&tval)) { return 0; } return poll_event_loop_poll(ev, &tval); } static const struct tevent_ops poll_event_ops = { .context_init = poll_event_context_init, .add_fd = poll_event_add_fd, .set_fd_close_fn = tevent_common_fd_set_close_fn, .get_fd_flags = tevent_common_fd_get_flags, .set_fd_flags = poll_event_set_fd_flags, .add_timer = tevent_common_add_timer_v2, .schedule_immediate = tevent_common_schedule_immediate, .add_signal = tevent_common_add_signal, .loop_once = poll_event_loop_once, .loop_wait = tevent_common_loop_wait, }; _PRIVATE_ bool tevent_poll_init(void) { return tevent_register_backend("poll", &poll_event_ops); } static const struct tevent_ops poll_event_mt_ops = { .context_init = poll_event_context_init_mt, .add_fd = poll_event_add_fd, .set_fd_close_fn = tevent_common_fd_set_close_fn, .get_fd_flags = tevent_common_fd_get_flags, .set_fd_flags = poll_event_set_fd_flags, .add_timer = tevent_common_add_timer_v2, .schedule_immediate = poll_event_schedule_immediate, .add_signal = tevent_common_add_signal, .loop_once = poll_event_loop_once, .loop_wait = tevent_common_loop_wait, }; _PRIVATE_ bool tevent_poll_mt_init(void) { return tevent_register_backend("poll_mt", &poll_event_mt_ops); } ldb-2.0.8/lib/tevent/tevent_port.c0000660000000000000000000004766213444661620017033 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Main select loop and event handling - Solaris port implementation. Losely based on the Linux epoll backend. Copyright (C) Jeremy Allison 2013 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/select.h" #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" struct port_associate_vals { struct port_associate_vals *prev, *next; struct port_event_context *port_ev; int events; struct tevent_fd *fde; bool associated_event; }; struct port_event_context { /* a pointer back to the generic event_context */ struct tevent_context *ev; /* This is the handle from port_create */ int port_fd; pid_t pid; /* List of associations. */ struct port_associate_vals *po_vals; }; #define PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION (1<<0) #define PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) #define PORT_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) #define PORT_ADDITIONAL_FD_FLAG_HAS_MPX (1<<3) /* Map from TEVENT_FD_* to POLLIN/POLLOUT */ static int port_map_flags(uint16_t flags) { int ret = 0; if (flags & TEVENT_FD_READ) ret |= (POLLIN | POLLERR | POLLHUP); if (flags & TEVENT_FD_WRITE) ret |= (POLLOUT | POLLERR | POLLHUP); return ret; } /* Free the port fd */ static int port_ctx_destructor(struct port_event_context *port_ev) { close(port_ev->port_fd); port_ev->port_fd = -1; return 0; } /* Init the port fd */ static int port_init_ctx(struct port_event_context *port_ev) { port_ev->port_fd = port_create(); if (port_ev->port_fd == -1) { tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, "Failed to create port handle.\n"); return -1; } if (!ev_set_close_on_exec(port_ev->port_fd)) { tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); } port_ev->pid = getpid(); talloc_set_destructor(port_ev, port_ctx_destructor); return 0; } /* Functions to manage the lower level cache of associated events on the port_fd. */ static int port_associate_vals_destructor(struct port_associate_vals *val) { DLIST_REMOVE(val->port_ev->po_vals, val); memset(val, '\0', sizeof(struct port_associate_vals)); return 0; } /* * TODO: As the port_association is per-fde, it should be possible to store it * directly in fde->additional_data, alongside any multiplexed-fde. That way the * lookup on store and delete would be avoided, and associate_all_events() could * walk the ev->fd_events list. */ static bool store_port_association(struct port_event_context *port_ev, struct tevent_fd *fde, int events) { struct port_associate_vals *val; for (val = port_ev->po_vals; val; val = val->next) { if (val->fde->fd == fde->fd) { /* Association already attached to fd. */ if (val->events != events) { val->events = events; val->associated_event = false; } return true; } } val = talloc_zero(port_ev, struct port_associate_vals); if (val == NULL) { return false; } val->port_ev = port_ev; val->fde = fde; val->events = events; val->associated_event = false; DLIST_ADD(port_ev->po_vals, val); talloc_set_destructor(val, port_associate_vals_destructor); return true; } static void delete_port_association(struct port_event_context *port_ev, struct tevent_fd *fde) { struct port_associate_vals *val; for (val = port_ev->po_vals; val; val = val->next) { if (val->fde == fde) { if (val->associated_event) { (void)port_dissociate(port_ev->port_fd, PORT_SOURCE_FD, fde->fd); } talloc_free(val); return; } } } static int associate_all_events(struct port_event_context *port_ev) { struct port_associate_vals *val; for (val = port_ev->po_vals; val; val = val->next) { int ret; if (val->associated_event) { continue; } ret = port_associate(port_ev->port_fd, PORT_SOURCE_FD, (uintptr_t)val->fde->fd, val->events, (void *)val); if (ret != 0) { return -1; } val->associated_event = true; } return 0; } static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde); /* Reopen the port handle when our pid changes. */ static int port_check_reopen(struct port_event_context *port_ev) { struct tevent_fd *fde; if (port_ev->pid == getpid()) { return 0; } close(port_ev->port_fd); port_ev->port_fd = port_create(); if (port_ev->port_fd == -1) { tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, "port_create() failed"); return -1; } if (!ev_set_close_on_exec(port_ev->port_fd)) { tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); } port_ev->pid = getpid(); for (fde=port_ev->ev->fd_events;fde;fde=fde->next) { fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; if (port_update_event(port_ev, fde) != 0) { return -1; } } return 0; } /* * Solaris ports cannot add the same file descriptor twice, once * with read, once with write which is allowed by the tevent backend. * Multiplex the existing fde, flag it as such so we can search for the * correct fde on event triggering. */ static void port_setup_multiplex_fd(struct port_event_context *port_ev, struct tevent_fd *add_fde, struct tevent_fd *mpx_fde) { /* * Make each fde->additional_data pointers point at each other * so we can look them up from each other. They are now paired. */ mpx_fde->additional_data = add_fde; add_fde->additional_data = mpx_fde; /* Now flag both fde's as being multiplexed. */ mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; /* We need to keep the GOT_ERROR flag. */ if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR) { add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; } } /* Add the port event to the given fd_event, Or modify an existing event. */ static int port_add_event(struct port_event_context *port_ev, struct tevent_fd *fde) { int flags = port_map_flags(fde->flags); struct tevent_fd *mpx_fde = NULL; fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * This is already a multiplexed fde, we need to include both * flags in the modified event. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; flags |= port_map_flags(mpx_fde->flags); } else { /* * Not (yet) a multiplexed event. See if there * is already an event with the same fd. */ for (mpx_fde = port_ev->ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) { if (mpx_fde->fd != fde->fd) { continue; } if (mpx_fde == fde) { continue; } /* Same fd. */ break; } if (mpx_fde) { if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { /* Logic error. Can't have more then 2 multiplexed fde's. */ tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, "multiplex fde for fd[%d] is already multiplexed\n", mpx_fde->fd); return -1; } flags |= port_map_flags(mpx_fde->flags); } } if (!store_port_association(port_ev, fde, flags)) { tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, "store_port_association failed for fd[%d]\n", fde->fd); return -1; } /* Note we have an association now. */ fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; /* Only if we want to read do we tell the event handler about errors. */ if (fde->flags & TEVENT_FD_READ) { fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; } if (mpx_fde == NULL) { return 0; } /* Set up the multiplex pointer. Does no harm if already multiplexed. */ port_setup_multiplex_fd(port_ev, fde, mpx_fde); mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; /* Only if we want to read do we tell the event handler about errors. */ if (mpx_fde->flags & TEVENT_FD_READ) { mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; } return 0; } /* Delete the port association for the given fd_event. */ static void port_del_event(struct port_event_context *port_ev, struct tevent_fd *fde) { struct tevent_fd *mpx_fde = NULL; fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * This is a multiplexed fde, we need to remove * both associations. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; mpx_fde->additional_data = NULL; fde->additional_data = NULL; } delete_port_association(port_ev, fde); } /* Add or remove the port event from the given fd_event */ static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde) { bool got_error = (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR); bool want_read = (fde->flags & TEVENT_FD_READ); bool want_write = (fde->flags & TEVENT_FD_WRITE); struct tevent_fd *mpx_fde = NULL; if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * work out what the multiplexed fde wants. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); if (mpx_fde->flags & TEVENT_FD_READ) { want_read = true; } if (mpx_fde->flags & TEVENT_FD_WRITE) { want_write = true; } } if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION) { /* There's already an association. */ if (want_read || (want_write && !got_error)) { return port_add_event(port_ev, fde); } /* * If we want to match the select behavior, we need to remove the port event * when the caller isn't interested in events. */ port_del_event(port_ev, fde); return 0; } /* There's no port event attached to the fde. */ if (want_read || (want_write && !got_error)) { return port_add_event(port_ev, fde); } return 0; } /* Cope with port_get returning EPOLLHP|EPOLLERR on an association. Return true if there's nothing else to do, false if this event needs further handling. */ static bool port_handle_hup_or_err(struct port_event_context *port_ev, struct tevent_fd *fde) { if (fde == NULL) { return true; } fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; /* * If we only wait for TEVENT_FD_WRITE, we should not tell the * event handler about it, and remove the port association, * as we only report error when waiting for read events, * to match the select() behavior. */ if (!(fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { /* * Do the same as the poll backend and * remove the writable flag. */ fde->flags &= ~TEVENT_FD_WRITE; return true; } /* This has TEVENT_FD_READ set, we're not finished. */ return false; } /* Event loop handling using Solaris ports. */ static int port_event_loop(struct port_event_context *port_ev, struct timeval *tvalp) { int ret; #define MAXEVENTS 1 port_event_t events[MAXEVENTS]; uint_t nget = 1; uint_t max_events = MAXEVENTS; uint_t i; int port_errno; struct timespec ts; struct tevent_context *ev = port_ev->ev; if (tvalp) { ts.tv_sec = tvalp->tv_sec; ts.tv_nsec = tvalp->tv_usec * 1000; } if (port_ev->ev->signal_events && tevent_common_check_signal(ev)) { return 0; } /* * Solaris triggers sending the event to the port * at the time the port association is done. Postpone * associating fd's until just before we get the events, * otherwise we can deadlock. */ if (associate_all_events(port_ev) != 0) { return -1; } tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_WAIT); ret = port_getn(port_ev->port_fd, events, max_events, &nget, &ts); port_errno = errno; tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_WAIT); if (ret == -1 && port_errno == EINTR) { if (ev->signal_events) { tevent_common_check_signal(ev); } /* * If no signal handlers we got an unsolicited * signal wakeup. This can happen with epoll * too. Just return and ignore. */ return 0; } if (ret == -1 && port_errno == ETIME) { /* * If errno is set to ETIME it is possible that we still got an event. * In that case we need to go through the processing loop so that we * reassociate the received event with the port or the association will * be lost so check the value of nget is 0 before returning. */ if (nget == 0) { /* we don't care about a possible delay here */ tevent_common_loop_timer_delay(ev); return 0; } /* * Set the return value to 0 since we do not actually have an error and we * do have events that need to be processed. This keeps us from getting * caught in the generic error test. */ ret = 0; } if (ret == -1) { tevent_debug(ev, TEVENT_DEBUG_ERROR, "port_get failed (%s)\n", strerror(errno)); return -1; } for (i = 0; i < nget; i++) { struct tevent_fd *mpx_fde = NULL; struct tevent_fd *fde = NULL; uint16_t flags = 0; struct port_associate_vals *val = talloc_get_type(events[i].portev_user, struct port_associate_vals); if (val == NULL) { tevent_debug(ev, TEVENT_DEBUG_ERROR, "port_getn() gave bad data"); return -1; } /* Mark this event as needing to be re-associated. */ val->associated_event = false; fde = val->fde; if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { /* * Save off the multiplexed event in case we need * to use it to call the handler function. */ mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); } if (events[i].portev_events & (POLLHUP|POLLERR)) { bool handled_fde = port_handle_hup_or_err(port_ev, fde); bool handled_mpx = port_handle_hup_or_err(port_ev, mpx_fde); if (handled_fde && handled_mpx) { return port_update_event(port_ev, fde); } if (!handled_mpx) { /* * If the mpx event was the one that needs * further handling, it's the TEVENT_FD_READ * event so switch over and call that handler. */ fde = mpx_fde; mpx_fde = NULL; } flags |= TEVENT_FD_READ; } if (events[i].portev_events & POLLIN) { flags |= TEVENT_FD_READ; } if (events[i].portev_events & POLLOUT) { flags |= TEVENT_FD_WRITE; } if (flags & TEVENT_FD_WRITE) { if (fde->flags & TEVENT_FD_WRITE) { mpx_fde = NULL; } if (mpx_fde && (mpx_fde->flags & TEVENT_FD_WRITE)) { fde = mpx_fde; mpx_fde = NULL; } if (mpx_fde) { /* Ensure we got the right fde. */ if ((flags & fde->flags) == 0) { fde = mpx_fde; mpx_fde = NULL; } } } /* * Make sure we only pass the flags * the handler is expecting. */ flags &= fde->flags; if (flags) { return tevent_common_invoke_fd_handler(fde, flags, NULL); } } return 0; } /* create a port_event_context structure. */ static int port_event_context_init(struct tevent_context *ev) { int ret; struct port_event_context *port_ev; /* * We might be called during tevent_re_initialise() * which means we need to free our old additional_data. */ TALLOC_FREE(ev->additional_data); port_ev = talloc_zero(ev, struct port_event_context); if (!port_ev) { return -1; } port_ev->ev = ev; port_ev->port_fd = -1; port_ev->pid = (pid_t)-1; ret = port_init_ctx(port_ev); if (ret != 0) { talloc_free(port_ev); return ret; } ev->additional_data = port_ev; return 0; } /* destroy an fd_event */ static int port_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; struct port_event_context *port_ev = NULL; struct tevent_fd *mpx_fde = NULL; int flags = (int)fde->flags; if (ev == NULL) { return tevent_common_fd_destructor(fde); } port_ev = talloc_get_type_abort(ev->additional_data, struct port_event_context); DLIST_REMOVE(ev->fd_events, fde); if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { mpx_fde = talloc_get_type_abort(fde->additional_data, struct tevent_fd); fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; fde->additional_data = NULL; mpx_fde->additional_data = NULL; fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; } (void)port_check_reopen(port_ev); if (mpx_fde != NULL) { (void)port_update_event(port_ev, mpx_fde); } fde->flags = 0; (void)port_update_event(port_ev, fde); fde->flags = flags; return tevent_common_fd_destructor(fde); } /* add a fd based event return NULL on failure (memory allocation error) */ static struct tevent_fd *port_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct port_event_context *port_ev = talloc_get_type_abort(ev->additional_data, struct port_event_context); struct tevent_fd *fde; fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, handler, private_data, handler_name, location); if (!fde) { return NULL; } talloc_set_destructor(fde, port_event_fd_destructor); if (port_check_reopen(port_ev) != 0) { TALLOC_FREE(fde); return NULL; } if (port_update_event(port_ev, fde) != 0) { TALLOC_FREE(fde); return NULL; } return fde; } /* set the fd event flags */ static void port_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) { struct tevent_context *ev; struct port_event_context *port_ev; if (fde->flags == flags) { return; } ev = fde->event_ctx; port_ev = talloc_get_type_abort(ev->additional_data, struct port_event_context); fde->flags = flags; (void)port_check_reopen(port_ev); (void)port_update_event(port_ev, fde); } /* do a single event loop using the events defined in ev */ static int port_event_loop_once(struct tevent_context *ev, const char *location) { struct port_event_context *port_ev = talloc_get_type(ev->additional_data, struct port_event_context); struct timeval tval; if (ev->signal_events && tevent_common_check_signal(ev)) { return 0; } if (ev->threaded_contexts != NULL) { tevent_common_threaded_activate_immediate(ev); } if (ev->immediate_events && tevent_common_loop_immediate(ev)) { return 0; } tval = tevent_common_loop_timer_delay(ev); if (tevent_timeval_is_zero(&tval)) { return 0; } if (port_check_reopen(port_ev) != 0) { errno = EINVAL; return -1; } return port_event_loop(port_ev, &tval); } static const struct tevent_ops port_event_ops = { .context_init = port_event_context_init, .add_fd = port_event_add_fd, .set_fd_close_fn = tevent_common_fd_set_close_fn, .get_fd_flags = tevent_common_fd_get_flags, .set_fd_flags = port_event_set_fd_flags, .add_timer = tevent_common_add_timer_v2, .schedule_immediate = tevent_common_schedule_immediate, .add_signal = tevent_common_add_signal, .loop_once = port_event_loop_once, .loop_wait = tevent_common_loop_wait, }; _PRIVATE_ bool tevent_port_init(void) { if (!tevent_register_backend("port", &port_event_ops)) { return false; } tevent_set_default_backend("port"); return true; } ldb-2.0.8/lib/tevent/tevent_queue.c0000660000000000000000000001652113243766350017164 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Infrastructure for async requests Copyright (C) Volker Lendecke 2008 Copyright (C) Stefan Metzmacher 2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" struct tevent_queue_entry { struct tevent_queue_entry *prev, *next; struct tevent_queue *queue; bool triggered; struct tevent_req *req; struct tevent_context *ev; tevent_queue_trigger_fn_t trigger; void *private_data; }; struct tevent_queue { const char *name; const char *location; bool running; struct tevent_immediate *immediate; size_t length; struct tevent_queue_entry *list; }; static void tevent_queue_immediate_trigger(struct tevent_context *ev, struct tevent_immediate *im, void *private_data); static int tevent_queue_entry_destructor(struct tevent_queue_entry *e) { struct tevent_queue *q = e->queue; if (!q) { return 0; } DLIST_REMOVE(q->list, e); q->length--; if (!q->running) { return 0; } if (!q->list) { return 0; } if (q->list->triggered) { return 0; } tevent_schedule_immediate(q->immediate, q->list->ev, tevent_queue_immediate_trigger, q); return 0; } static int tevent_queue_destructor(struct tevent_queue *q) { q->running = false; while (q->list) { struct tevent_queue_entry *e = q->list; talloc_free(e); } return 0; } struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, const char *name, const char *location) { struct tevent_queue *queue; queue = talloc_zero(mem_ctx, struct tevent_queue); if (!queue) { return NULL; } queue->name = talloc_strdup(queue, name); if (!queue->name) { talloc_free(queue); return NULL; } queue->immediate = tevent_create_immediate(queue); if (!queue->immediate) { talloc_free(queue); return NULL; } queue->location = location; /* queue is running by default */ queue->running = true; talloc_set_destructor(queue, tevent_queue_destructor); return queue; } static void tevent_queue_immediate_trigger(struct tevent_context *ev, struct tevent_immediate *im, void *private_data) { struct tevent_queue *q = talloc_get_type_abort(private_data, struct tevent_queue); if (!q->running) { return; } if (!q->list) { return; } q->list->triggered = true; q->list->trigger(q->list->req, q->list->private_data); } static struct tevent_queue_entry *tevent_queue_add_internal( struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data, bool allow_direct) { struct tevent_queue_entry *e; e = talloc_zero(req, struct tevent_queue_entry); if (e == NULL) { return NULL; } e->queue = queue; e->req = req; e->ev = ev; e->trigger = trigger; e->private_data = private_data; /* * if there is no trigger, it is just a blocker */ if (trigger == NULL) { e->triggered = true; } if (queue->length > 0) { /* * if there are already entries in the * queue do not optimize. */ allow_direct = false; } if (req->async.fn != NULL) { /* * If the caller wants to optimize for the * empty queue case, call the trigger only * if there is no callback defined for the * request yet. */ allow_direct = false; } DLIST_ADD_END(queue->list, e); queue->length++; talloc_set_destructor(e, tevent_queue_entry_destructor); if (!queue->running) { return e; } if (queue->list->triggered) { return e; } /* * If allowed we directly call the trigger * avoiding possible delays caused by * an immediate event. */ if (allow_direct) { queue->list->triggered = true; queue->list->trigger(queue->list->req, queue->list->private_data); return e; } tevent_schedule_immediate(queue->immediate, queue->list->ev, tevent_queue_immediate_trigger, queue); return e; } bool tevent_queue_add(struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data) { struct tevent_queue_entry *e; e = tevent_queue_add_internal(queue, ev, req, trigger, private_data, false); if (e == NULL) { return false; } return true; } struct tevent_queue_entry *tevent_queue_add_entry( struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data) { return tevent_queue_add_internal(queue, ev, req, trigger, private_data, false); } struct tevent_queue_entry *tevent_queue_add_optimize_empty( struct tevent_queue *queue, struct tevent_context *ev, struct tevent_req *req, tevent_queue_trigger_fn_t trigger, void *private_data) { return tevent_queue_add_internal(queue, ev, req, trigger, private_data, true); } void tevent_queue_entry_untrigger(struct tevent_queue_entry *entry) { if (entry->queue->running) { abort(); } if (entry->queue->list != entry) { abort(); } entry->triggered = false; } void tevent_queue_start(struct tevent_queue *queue) { if (queue->running) { /* already started */ return; } queue->running = true; if (!queue->list) { return; } if (queue->list->triggered) { return; } tevent_schedule_immediate(queue->immediate, queue->list->ev, tevent_queue_immediate_trigger, queue); } void tevent_queue_stop(struct tevent_queue *queue) { queue->running = false; } size_t tevent_queue_length(struct tevent_queue *queue) { return queue->length; } bool tevent_queue_running(struct tevent_queue *queue) { return queue->running; } struct tevent_queue_wait_state { uint8_t dummy; }; static void tevent_queue_wait_trigger(struct tevent_req *req, void *private_data); struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct tevent_queue *queue) { struct tevent_req *req; struct tevent_queue_wait_state *state; bool ok; req = tevent_req_create(mem_ctx, &state, struct tevent_queue_wait_state); if (req == NULL) { return NULL; } ok = tevent_queue_add(queue, ev, req, tevent_queue_wait_trigger, NULL); if (!ok) { tevent_req_oom(req); return tevent_req_post(req, ev); } return req; } static void tevent_queue_wait_trigger(struct tevent_req *req, void *private_data) { tevent_req_done(req); } bool tevent_queue_wait_recv(struct tevent_req *req) { enum tevent_req_state state; uint64_t err; if (tevent_req_is_error(req, &state, &err)) { tevent_req_received(req); return false; } tevent_req_received(req); return true; } ldb-2.0.8/lib/tevent/tevent_req.c0000660000000000000000000003166313573675413016640 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Infrastructure for async requests Copyright (C) Volker Lendecke 2008 Copyright (C) Stefan Metzmacher 2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) { return talloc_asprintf(mem_ctx, "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " " state[%s (%p)] timer[%p] finish[%s]", req, req->internal.create_location, req->internal.state, (unsigned long long)req->internal.error, (unsigned long long)req->internal.error, req->internal.private_type, req->data, req->internal.timer, req->internal.finish_location ); } char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) { if (req == NULL) { return talloc_strdup(mem_ctx, "tevent_req[NULL]"); } if (!req->private_print) { return tevent_req_default_print(req, mem_ctx); } return req->private_print(req, mem_ctx); } static int tevent_req_destructor(struct tevent_req *req); struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, void *pdata, size_t data_size, const char *type, const char *location) { struct tevent_req *req; struct tevent_req *parent; void **ppdata = (void **)pdata; void *data; size_t payload; payload = sizeof(struct tevent_immediate) + data_size; if (payload < sizeof(struct tevent_immediate)) { /* overflow */ return NULL; } req = talloc_pooled_object( mem_ctx, struct tevent_req, 2, sizeof(struct tevent_immediate) + data_size); if (req == NULL) { return NULL; } *req = (struct tevent_req) { .internal = { .private_type = type, .create_location = location, .state = TEVENT_REQ_IN_PROGRESS, .trigger = tevent_create_immediate(req), }, }; data = talloc_zero_size(req, data_size); /* * No need to check for req->internal.trigger!=NULL or * data!=NULL, this can't fail: talloc_pooled_object has * already allocated sufficient memory. */ talloc_set_name_const(data, type); req->data = data; talloc_set_destructor(req, tevent_req_destructor); parent = talloc_get_type(talloc_parent(mem_ctx), struct tevent_req); if ((parent != NULL) && (parent->internal.profile != NULL)) { bool ok = tevent_req_set_profile(req); if (!ok) { TALLOC_FREE(req); return NULL; } req->internal.profile->parent = parent->internal.profile; DLIST_ADD_END(parent->internal.profile->subprofiles, req->internal.profile); } *ppdata = data; return req; } static int tevent_req_destructor(struct tevent_req *req) { tevent_req_received(req); return 0; } void _tevent_req_notify_callback(struct tevent_req *req, const char *location) { req->internal.finish_location = location; if (req->internal.defer_callback_ev) { (void)tevent_req_post(req, req->internal.defer_callback_ev); req->internal.defer_callback_ev = NULL; return; } if (req->async.fn != NULL) { req->async.fn(req); } } static void tevent_req_cleanup(struct tevent_req *req) { if (req->private_cleanup.fn == NULL) { return; } if (req->private_cleanup.state >= req->internal.state) { /* * Don't call the cleanup_function multiple times for the same * state recursively */ return; } req->private_cleanup.state = req->internal.state; req->private_cleanup.fn(req, req->internal.state); } static void tevent_req_finish(struct tevent_req *req, enum tevent_req_state state, const char *location) { struct tevent_req_profile *p; /* * make sure we do not timeout after * the request was already finished */ TALLOC_FREE(req->internal.timer); req->internal.state = state; req->internal.finish_location = location; tevent_req_cleanup(req); p = req->internal.profile; if (p != NULL) { p->stop_location = location; p->stop_time = tevent_timeval_current(); p->state = state; p->user_error = req->internal.error; if (p->parent != NULL) { talloc_steal(p->parent, p); req->internal.profile = NULL; } } _tevent_req_notify_callback(req, location); } void _tevent_req_done(struct tevent_req *req, const char *location) { tevent_req_finish(req, TEVENT_REQ_DONE, location); } bool _tevent_req_error(struct tevent_req *req, uint64_t error, const char *location) { if (error == 0) { return false; } req->internal.error = error; tevent_req_finish(req, TEVENT_REQ_USER_ERROR, location); return true; } void _tevent_req_oom(struct tevent_req *req, const char *location) { tevent_req_finish(req, TEVENT_REQ_NO_MEMORY, location); } bool _tevent_req_nomem(const void *p, struct tevent_req *req, const char *location) { if (p != NULL) { return false; } _tevent_req_oom(req, location); return true; } /** * @internal * * @brief Immediate event callback. * * @param[in] ev The event context to use. * * @param[in] im The immediate event. * * @param[in] priv The async request to be finished. */ static void tevent_req_trigger(struct tevent_context *ev, struct tevent_immediate *im, void *private_data) { struct tevent_req *req = talloc_get_type_abort(private_data, struct tevent_req); tevent_req_finish(req, req->internal.state, req->internal.finish_location); } struct tevent_req *tevent_req_post(struct tevent_req *req, struct tevent_context *ev) { tevent_schedule_immediate(req->internal.trigger, ev, tevent_req_trigger, req); return req; } void tevent_req_defer_callback(struct tevent_req *req, struct tevent_context *ev) { req->internal.defer_callback_ev = ev; } bool tevent_req_is_in_progress(struct tevent_req *req) { if (req->internal.state == TEVENT_REQ_IN_PROGRESS) { return true; } return false; } void tevent_req_received(struct tevent_req *req) { talloc_set_destructor(req, NULL); req->private_print = NULL; req->private_cancel = NULL; TALLOC_FREE(req->internal.trigger); TALLOC_FREE(req->internal.timer); req->internal.state = TEVENT_REQ_RECEIVED; tevent_req_cleanup(req); TALLOC_FREE(req->data); } bool tevent_req_poll(struct tevent_req *req, struct tevent_context *ev) { while (tevent_req_is_in_progress(req)) { int ret; ret = tevent_loop_once(ev); if (ret != 0) { return false; } } return true; } bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error) { if (req->internal.state == TEVENT_REQ_DONE) { return false; } if (req->internal.state == TEVENT_REQ_USER_ERROR) { *error = req->internal.error; } *state = req->internal.state; return true; } static void tevent_req_timedout(struct tevent_context *ev, struct tevent_timer *te, struct timeval now, void *private_data) { struct tevent_req *req = talloc_get_type_abort(private_data, struct tevent_req); TALLOC_FREE(req->internal.timer); tevent_req_finish(req, TEVENT_REQ_TIMED_OUT, __FUNCTION__); } bool tevent_req_set_endtime(struct tevent_req *req, struct tevent_context *ev, struct timeval endtime) { TALLOC_FREE(req->internal.timer); req->internal.timer = tevent_add_timer(ev, req, endtime, tevent_req_timedout, req); if (tevent_req_nomem(req->internal.timer, req)) { return false; } return true; } void tevent_req_reset_endtime(struct tevent_req *req) { TALLOC_FREE(req->internal.timer); } void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt) { req->async.fn = fn; req->async.private_data = pvt; } void *_tevent_req_callback_data(struct tevent_req *req) { return req->async.private_data; } void *_tevent_req_data(struct tevent_req *req) { return req->data; } void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn) { req->private_print = fn; } void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn) { req->private_cancel = fn; } bool _tevent_req_cancel(struct tevent_req *req, const char *location) { if (req->private_cancel == NULL) { return false; } return req->private_cancel(req); } void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn) { req->private_cleanup.state = req->internal.state; req->private_cleanup.fn = fn; } static int tevent_req_profile_destructor(struct tevent_req_profile *p); bool tevent_req_set_profile(struct tevent_req *req) { struct tevent_req_profile *p; if (req->internal.profile != NULL) { tevent_req_error(req, EINVAL); return false; } p = tevent_req_profile_create(req); if (tevent_req_nomem(p, req)) { return false; } p->req_name = talloc_get_name(req->data); p->start_location = req->internal.create_location; p->start_time = tevent_timeval_current(); req->internal.profile = p; return true; } static int tevent_req_profile_destructor(struct tevent_req_profile *p) { if (p->parent != NULL) { DLIST_REMOVE(p->parent->subprofiles, p); p->parent = NULL; } while (p->subprofiles != NULL) { p->subprofiles->parent = NULL; DLIST_REMOVE(p->subprofiles, p->subprofiles); } return 0; } struct tevent_req_profile *tevent_req_move_profile(struct tevent_req *req, TALLOC_CTX *mem_ctx) { return talloc_move(mem_ctx, &req->internal.profile); } const struct tevent_req_profile *tevent_req_get_profile( struct tevent_req *req) { return req->internal.profile; } void tevent_req_profile_get_name(const struct tevent_req_profile *profile, const char **req_name) { if (req_name != NULL) { *req_name = profile->req_name; } } void tevent_req_profile_get_start(const struct tevent_req_profile *profile, const char **start_location, struct timeval *start_time) { if (start_location != NULL) { *start_location = profile->start_location; } if (start_time != NULL) { *start_time = profile->start_time; } } void tevent_req_profile_get_stop(const struct tevent_req_profile *profile, const char **stop_location, struct timeval *stop_time) { if (stop_location != NULL) { *stop_location = profile->stop_location; } if (stop_time != NULL) { *stop_time = profile->stop_time; } } void tevent_req_profile_get_status(const struct tevent_req_profile *profile, pid_t *pid, enum tevent_req_state *state, uint64_t *user_error) { if (pid != NULL) { *pid = profile->pid; } if (state != NULL) { *state = profile->state; } if (user_error != NULL) { *user_error = profile->user_error; } } const struct tevent_req_profile *tevent_req_profile_get_subprofiles( const struct tevent_req_profile *profile) { return profile->subprofiles; } const struct tevent_req_profile *tevent_req_profile_next( const struct tevent_req_profile *profile) { return profile->next; } struct tevent_req_profile *tevent_req_profile_create(TALLOC_CTX *mem_ctx) { struct tevent_req_profile *result; result = talloc_zero(mem_ctx, struct tevent_req_profile); if (result == NULL) { return NULL; } talloc_set_destructor(result, tevent_req_profile_destructor); return result; } bool tevent_req_profile_set_name(struct tevent_req_profile *profile, const char *req_name) { profile->req_name = talloc_strdup(profile, req_name); return (profile->req_name != NULL); } bool tevent_req_profile_set_start(struct tevent_req_profile *profile, const char *start_location, struct timeval start_time) { profile->start_time = start_time; profile->start_location = talloc_strdup(profile, start_location); return (profile->start_location != NULL); } bool tevent_req_profile_set_stop(struct tevent_req_profile *profile, const char *stop_location, struct timeval stop_time) { profile->stop_time = stop_time; profile->stop_location = talloc_strdup(profile, stop_location); return (profile->stop_location != NULL); } void tevent_req_profile_set_status(struct tevent_req_profile *profile, pid_t pid, enum tevent_req_state state, uint64_t user_error) { profile->pid = pid; profile->state = state; profile->user_error = user_error; } void tevent_req_profile_append_sub(struct tevent_req_profile *parent_profile, struct tevent_req_profile **sub_profile) { struct tevent_req_profile *sub; sub = talloc_move(parent_profile, sub_profile); sub->parent = parent_profile; DLIST_ADD_END(parent_profile->subprofiles, sub); } ldb-2.0.8/lib/tevent/tevent_signal.c0000660000000000000000000003171513573675413017324 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. common events code for signal events Copyright (C) Andrew Tridgell 2007 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "system/wait.h" #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" /* maximum number of SA_SIGINFO signals to hold in the queue. NB. This *MUST* be a power of 2, in order for the ring buffer wrap to work correctly. Thanks to Petr Vandrovec for this. */ #define TEVENT_SA_INFO_QUEUE_COUNT 256 size_t tevent_num_signals(void) { return TEVENT_NUM_SIGNALS; } size_t tevent_sa_info_queue_count(void) { return TEVENT_SA_INFO_QUEUE_COUNT; } struct tevent_sigcounter { uint32_t count; uint32_t seen; }; #if defined(HAVE___SYNC_FETCH_AND_ADD) #define TEVENT_SIG_INCREMENT(s) __sync_fetch_and_add(&((s).count), 1) #elif defined(HAVE_ATOMIC_ADD_32) #define TEVENT_SIG_INCREMENT(s) atomic_add_32(&((s).count), 1) #else #define TEVENT_SIG_INCREMENT(s) (s).count++ #endif #define TEVENT_SIG_SEEN(s, n) (s).seen += (n) #define TEVENT_SIG_PENDING(s) ((s).seen != (s).count) struct tevent_common_signal_list { struct tevent_common_signal_list *prev, *next; struct tevent_signal *se; }; /* the poor design of signals means that this table must be static global */ static struct tevent_sig_state { struct tevent_common_signal_list *sig_handlers[TEVENT_NUM_SIGNALS+1]; struct sigaction *oldact[TEVENT_NUM_SIGNALS+1]; struct tevent_sigcounter signal_count[TEVENT_NUM_SIGNALS+1]; struct tevent_sigcounter got_signal; #ifdef SA_SIGINFO /* with SA_SIGINFO we get quite a lot of info per signal */ siginfo_t *sig_info[TEVENT_NUM_SIGNALS+1]; struct tevent_sigcounter sig_blocked[TEVENT_NUM_SIGNALS+1]; #endif } *sig_state; /* return number of sigcounter events not processed yet */ static uint32_t tevent_sig_count(struct tevent_sigcounter s) { return s.count - s.seen; } /* signal handler - redirects to registered signals */ static void tevent_common_signal_handler(int signum) { struct tevent_common_signal_list *sl; struct tevent_context *ev = NULL; int saved_errno = errno; TEVENT_SIG_INCREMENT(sig_state->signal_count[signum]); TEVENT_SIG_INCREMENT(sig_state->got_signal); /* Write to each unique event context. */ for (sl = sig_state->sig_handlers[signum]; sl; sl = sl->next) { if (sl->se->event_ctx && sl->se->event_ctx != ev) { ev = sl->se->event_ctx; tevent_common_wakeup(ev); } } errno = saved_errno; } #ifdef SA_SIGINFO /* signal handler with SA_SIGINFO - redirects to registered signals */ static void tevent_common_signal_handler_info(int signum, siginfo_t *info, void *uctx) { uint32_t count = tevent_sig_count(sig_state->signal_count[signum]); /* sig_state->signal_count[signum].seen % TEVENT_SA_INFO_QUEUE_COUNT * is the base of the unprocessed signals in the ringbuffer. */ uint32_t ofs = (sig_state->signal_count[signum].seen + count) % TEVENT_SA_INFO_QUEUE_COUNT; sig_state->sig_info[signum][ofs] = *info; tevent_common_signal_handler(signum); /* handle SA_SIGINFO */ if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) { /* we've filled the info array - block this signal until these ones are delivered */ #ifdef HAVE_UCONTEXT_T /* * This is the only way for this to work. * By default signum is blocked inside this * signal handler using a temporary mask, * but what we really need to do now is * block it in the callers mask, so it * stays blocked when the temporary signal * handler mask is replaced when we return * from here. The callers mask can be found * in the ucontext_t passed in as the * void *uctx argument. */ ucontext_t *ucp = (ucontext_t *)uctx; sigaddset(&ucp->uc_sigmask, signum); #else /* * WARNING !!! WARNING !!!! * * This code doesn't work. * By default signum is blocked inside this * signal handler, but calling sigprocmask * modifies the temporary signal mask being * used *inside* this handler, which will be * replaced by the callers signal mask once * we return from here. See Samba * bug #9550 for details. */ sigset_t set; sigemptyset(&set); sigaddset(&set, signum); sigprocmask(SIG_BLOCK, &set, NULL); #endif TEVENT_SIG_INCREMENT(sig_state->sig_blocked[signum]); } } #endif static int tevent_common_signal_list_destructor(struct tevent_common_signal_list *sl) { if (sig_state->sig_handlers[sl->se->signum]) { DLIST_REMOVE(sig_state->sig_handlers[sl->se->signum], sl); } return 0; } /* destroy a signal event */ static int tevent_signal_destructor(struct tevent_signal *se) { if (se->destroyed) { tevent_common_check_double_free(se, "tevent_signal double free"); goto done; } se->destroyed = true; TALLOC_FREE(se->additional_data); if (se->event_ctx != NULL) { DLIST_REMOVE(se->event_ctx->signal_events, se); } if (sig_state->sig_handlers[se->signum] == NULL) { /* restore old handler, if any */ if (sig_state->oldact[se->signum]) { sigaction(se->signum, sig_state->oldact[se->signum], NULL); TALLOC_FREE(sig_state->oldact[se->signum]); } #ifdef SA_SIGINFO if (se->sa_flags & SA_SIGINFO) { if (sig_state->sig_info[se->signum]) { TALLOC_FREE(sig_state->sig_info[se->signum]); } } #endif } se->event_ctx = NULL; done: if (se->busy) { return -1; } se->wrapper = NULL; return 0; } /* add a signal event return NULL on failure (memory allocation error) */ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct tevent_signal *se; struct tevent_common_signal_list *sl; sigset_t set, oldset; int ret; ret = tevent_common_wakeup_init(ev); if (ret != 0) { errno = ret; return NULL; } if (signum >= TEVENT_NUM_SIGNALS) { errno = EINVAL; return NULL; } /* the sig_state needs to be on a global context as it can last across multiple event contexts */ if (sig_state == NULL) { sig_state = talloc_zero(NULL, struct tevent_sig_state); if (sig_state == NULL) { return NULL; } } se = talloc_zero(mem_ctx?mem_ctx:ev, struct tevent_signal); if (se == NULL) return NULL; sl = talloc_zero(se, struct tevent_common_signal_list); if (!sl) { talloc_free(se); return NULL; } sl->se = se; *se = (struct tevent_signal) { .event_ctx = ev, .signum = signum, .sa_flags = sa_flags, .handler = handler, .private_data = private_data, .handler_name = handler_name, .location = location, .additional_data= sl, }; /* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */ if (!talloc_reference(se, sig_state)) { talloc_free(se); return NULL; } /* only install a signal handler if not already installed */ if (sig_state->sig_handlers[signum] == NULL) { struct sigaction act; ZERO_STRUCT(act); act.sa_handler = tevent_common_signal_handler; act.sa_flags = sa_flags; #ifdef SA_SIGINFO if (sa_flags & SA_SIGINFO) { act.sa_handler = NULL; act.sa_sigaction = tevent_common_signal_handler_info; if (sig_state->sig_info[signum] == NULL) { sig_state->sig_info[signum] = talloc_zero_array(sig_state, siginfo_t, TEVENT_SA_INFO_QUEUE_COUNT); if (sig_state->sig_info[signum] == NULL) { talloc_free(se); return NULL; } } } #endif sig_state->oldact[signum] = talloc_zero(sig_state, struct sigaction); if (sig_state->oldact[signum] == NULL) { talloc_free(se); return NULL; } if (sigaction(signum, &act, sig_state->oldact[signum]) == -1) { talloc_free(sig_state->oldact[signum]); sig_state->oldact[signum] = NULL; talloc_free(se); return NULL; } } DLIST_ADD(se->event_ctx->signal_events, se); /* Make sure the signal doesn't come in while we're mangling list. */ sigemptyset(&set); sigaddset(&set, signum); sigprocmask(SIG_BLOCK, &set, &oldset); DLIST_ADD(sig_state->sig_handlers[signum], sl); sigprocmask(SIG_SETMASK, &oldset, NULL); talloc_set_destructor(se, tevent_signal_destructor); talloc_set_destructor(sl, tevent_common_signal_list_destructor); return se; } int tevent_common_invoke_signal_handler(struct tevent_signal *se, int signum, int count, void *siginfo, bool *removed) { struct tevent_context *handler_ev = se->event_ctx; bool remove = false; if (removed != NULL) { *removed = false; } if (se->event_ctx == NULL) { return 0; } se->busy = true; if (se->wrapper != NULL) { handler_ev = se->wrapper->wrap_ev; tevent_wrapper_push_use_internal(handler_ev, se->wrapper); se->wrapper->ops->before_signal_handler( se->wrapper->wrap_ev, se->wrapper->private_state, se->wrapper->main_ev, se, signum, count, siginfo, se->handler_name, se->location); } se->handler(handler_ev, se, signum, count, siginfo, se->private_data); if (se->wrapper != NULL) { se->wrapper->ops->after_signal_handler( se->wrapper->wrap_ev, se->wrapper->private_state, se->wrapper->main_ev, se, signum, count, siginfo, se->handler_name, se->location); tevent_wrapper_pop_use_internal(handler_ev, se->wrapper); } se->busy = false; #ifdef SA_RESETHAND if (se->sa_flags & SA_RESETHAND) { remove = true; } #endif if (se->destroyed) { talloc_set_destructor(se, NULL); remove = true; } if (remove) { TALLOC_FREE(se); if (removed != NULL) { *removed = true; } } return 0; } /* check if a signal is pending return != 0 if a signal was pending */ int tevent_common_check_signal(struct tevent_context *ev) { int i; if (!sig_state || !TEVENT_SIG_PENDING(sig_state->got_signal)) { return 0; } for (i=0;isignal_count[i]; uint32_t count = tevent_sig_count(counter); int ret; #ifdef SA_SIGINFO /* Ensure we null out any stored siginfo_t entries * after processing for debugging purposes. */ bool clear_processed_siginfo = false; #endif if (count == 0) { continue; } for (sl=sig_state->sig_handlers[i];sl;sl=next) { struct tevent_signal *se = sl->se; next = sl->next; #ifdef SA_SIGINFO if (se->sa_flags & SA_SIGINFO) { uint32_t j; clear_processed_siginfo = true; for (j=0;jsignal_count[i].seen * % TEVENT_SA_INFO_QUEUE_COUNT is * the base position of the unprocessed * signals in the ringbuffer. */ uint32_t ofs = (counter.seen + j) % TEVENT_SA_INFO_QUEUE_COUNT; bool removed = false; ret = tevent_common_invoke_signal_handler( se, i, 1, (void*)&sig_state->sig_info[i][ofs], &removed); if (ret != 0) { tevent_abort(ev, "tevent_common_invoke_signal_handler() failed"); } if (removed) { break; } } continue; } #endif ret = tevent_common_invoke_signal_handler(se, i, count, NULL, NULL); if (ret != 0) { tevent_abort(ev, "tevent_common_invoke_signal_handler() failed"); } } #ifdef SA_SIGINFO if (clear_processed_siginfo && sig_state->sig_info[i] != NULL) { uint32_t j; for (j=0;jsig_info[i][ofs], '\0', sizeof(siginfo_t)); } } #endif TEVENT_SIG_SEEN(sig_state->signal_count[i], count); TEVENT_SIG_SEEN(sig_state->got_signal, count); #ifdef SA_SIGINFO if (TEVENT_SIG_PENDING(sig_state->sig_blocked[i])) { /* We'd filled the queue, unblock the signal now the queue is empty again. Note we MUST do this after the TEVENT_SIG_SEEN(sig_state->signal_count[i], count) call to prevent a new signal running out of room in the sig_state->sig_info[i][] ring buffer. */ sigset_t set; sigemptyset(&set); sigaddset(&set, i); TEVENT_SIG_SEEN(sig_state->sig_blocked[i], tevent_sig_count(sig_state->sig_blocked[i])); sigprocmask(SIG_UNBLOCK, &set, NULL); } #endif } return 1; } void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se) { tevent_signal_destructor(se); talloc_set_destructor(se, NULL); return; } ldb-2.0.8/lib/tevent/tevent_standard.c0000660000000000000000000001376713444661620017646 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. main select loop and event handling Copyright (C) Stefan Metzmacher 2013 Copyright (C) Jeremy Allison 2013 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ /* This is SAMBA's default event loop code - we try to use epoll if configure detected support for it otherwise we use poll() - if epoll is broken on the system or the kernel doesn't support it at runtime we fallback to poll() */ #include "replace.h" #include "tevent.h" #include "tevent_util.h" #include "tevent_internal.h" struct std_event_glue { const struct tevent_ops *epoll_ops; const struct tevent_ops *poll_ops; struct tevent_ops *glue_ops; bool fallback_replay; }; static int std_event_context_init(struct tevent_context *ev); static const struct tevent_ops std_event_ops = { .context_init = std_event_context_init, }; /* If this function gets called. epoll failed at runtime. Move us to using poll instead. If we return false here, caller should abort(). */ #ifdef HAVE_EPOLL static bool std_fallback_to_poll(struct tevent_context *ev, bool replay) { void *glue_ptr = talloc_parent(ev->ops); struct std_event_glue *glue = talloc_get_type_abort(glue_ptr, struct std_event_glue); int ret; struct tevent_fd *fde; glue->fallback_replay = replay; /* First switch all the ops to poll. */ glue->epoll_ops = NULL; /* * Set custom_ops the same as poll. */ *glue->glue_ops = *glue->poll_ops; glue->glue_ops->context_init = std_event_context_init; /* Next initialize the poll backend. */ ret = glue->poll_ops->context_init(ev); if (ret != 0) { return false; } /* * Now we have to change all the existing file descriptor * events from the epoll backend to the poll backend. */ for (fde = ev->fd_events; fde; fde = fde->next) { bool ok; /* Re-add this event as a poll backend event. */ ok = tevent_poll_event_add_fd_internal(ev, fde); if (!ok) { return false; } } return true; } #endif static int std_event_loop_once(struct tevent_context *ev, const char *location) { void *glue_ptr = talloc_parent(ev->ops); struct std_event_glue *glue = talloc_get_type_abort(glue_ptr, struct std_event_glue); int ret; ret = glue->epoll_ops->loop_once(ev, location); /* * If the above hasn't panicked due to an epoll interface failure, * std_fallback_to_poll() wasn't called, and hasn't cleared epoll_ops to * signify fallback to poll_ops. */ if (glue->epoll_ops != NULL) { /* No fallback */ return ret; } if (!glue->fallback_replay) { /* * The problem happened while modifying an event. * An event handler was triggered in this case * and there is no need to call loop_once() again. */ return ret; } return glue->poll_ops->loop_once(ev, location); } static int std_event_loop_wait(struct tevent_context *ev, const char *location) { void *glue_ptr = talloc_parent(ev->ops); struct std_event_glue *glue = talloc_get_type_abort(glue_ptr, struct std_event_glue); int ret; ret = glue->epoll_ops->loop_wait(ev, location); /* * If the above hasn't panicked due to an epoll interface failure, * std_fallback_to_poll() wasn't called, and hasn't cleared epoll_ops to * signify fallback to poll_ops. */ if (glue->epoll_ops != NULL) { /* No fallback */ return ret; } return glue->poll_ops->loop_wait(ev, location); } /* Initialize the epoll backend and allow it to call a switch function if epoll fails at runtime. */ static int std_event_context_init(struct tevent_context *ev) { struct std_event_glue *glue; int ret; /* * If this is the first initialization * we need to set up the allocated ops * pointers. */ if (ev->ops == &std_event_ops) { glue = talloc_zero(ev, struct std_event_glue); if (glue == NULL) { return -1; } glue->epoll_ops = tevent_find_ops_byname("epoll"); glue->poll_ops = tevent_find_ops_byname("poll"); if (glue->poll_ops == NULL) { return -1; } /* * Allocate space for our custom ops. * Allocate as a child of our epoll_ops pointer * so we can easily get to it using talloc_parent. */ glue->glue_ops = talloc_zero(glue, struct tevent_ops); if (glue->glue_ops == NULL) { talloc_free(glue); return -1; } ev->ops = glue->glue_ops; } else { void *glue_ptr = talloc_parent(ev->ops); glue = talloc_get_type_abort(glue_ptr, struct std_event_glue); } if (glue->epoll_ops != NULL) { /* * Set custom_ops the same as epoll, * except re-init using std_event_context_init() * and use std_event_loop_once() to add the * ability to fallback to a poll backend on * epoll runtime error. */ *glue->glue_ops = *glue->epoll_ops; glue->glue_ops->context_init = std_event_context_init; glue->glue_ops->loop_once = std_event_loop_once; glue->glue_ops->loop_wait = std_event_loop_wait; ret = glue->epoll_ops->context_init(ev); if (ret == -1) { goto fallback; } #ifdef HAVE_EPOLL tevent_epoll_set_panic_fallback(ev, std_fallback_to_poll); #endif return ret; } fallback: glue->epoll_ops = NULL; /* * Set custom_ops the same as poll. */ *glue->glue_ops = *glue->poll_ops; glue->glue_ops->context_init = std_event_context_init; return glue->poll_ops->context_init(ev); } _PRIVATE_ bool tevent_standard_init(void) { return tevent_register_backend("standard", &std_event_ops); } ldb-2.0.8/lib/tevent/tevent_threads.c0000660000000000000000000003257613573675413017507 0ustar rootroot00000000000000/* tevent event library. Copyright (C) Jeremy Allison 2015 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "system/filesys.h" #include "talloc.h" #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" #ifdef HAVE_PTHREAD #include "system/threads.h" struct tevent_immediate_list { struct tevent_immediate_list *next, *prev; tevent_immediate_handler_t handler; struct tevent_immediate *im; void *private_ptr; }; struct tevent_thread_proxy { pthread_mutex_t mutex; struct tevent_context *dest_ev_ctx; int read_fd; int write_fd; struct tevent_fd *pipe_read_fde; /* Pending events list. */ struct tevent_immediate_list *im_list; /* Completed events list. */ struct tevent_immediate_list *tofree_im_list; struct tevent_immediate *free_im; }; static void free_im_list(struct tevent_immediate_list **pp_list_head) { struct tevent_immediate_list *im_entry = NULL; struct tevent_immediate_list *im_next = NULL; for (im_entry = *pp_list_head; im_entry; im_entry = im_next) { im_next = im_entry->next; DLIST_REMOVE(*pp_list_head, im_entry); TALLOC_FREE(im_entry); } } static void free_list_handler(struct tevent_context *ev, struct tevent_immediate *im, void *private_ptr) { struct tevent_thread_proxy *tp = talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); int ret; ret = pthread_mutex_lock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return; } free_im_list(&tp->tofree_im_list); ret = pthread_mutex_unlock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return; } } static void schedule_immediate_functions(struct tevent_thread_proxy *tp) { struct tevent_immediate_list *im_entry = NULL; struct tevent_immediate_list *im_next = NULL; for (im_entry = tp->im_list; im_entry; im_entry = im_next) { im_next = im_entry->next; DLIST_REMOVE(tp->im_list, im_entry); tevent_schedule_immediate(im_entry->im, tp->dest_ev_ctx, im_entry->handler, im_entry->private_ptr); /* Move from pending list to free list. */ DLIST_ADD(tp->tofree_im_list, im_entry); } if (tp->tofree_im_list != NULL) { /* * Once the current immediate events * are processed, we need to reschedule * ourselves to free them. This works * as tevent_schedule_immediate() * always adds events to the *END* of * the immediate events list. */ tevent_schedule_immediate(tp->free_im, tp->dest_ev_ctx, free_list_handler, tp); } } static void pipe_read_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_ptr) { struct tevent_thread_proxy *tp = talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); ssize_t len = 64; int ret; ret = pthread_mutex_lock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return; } /* * Clear out all data in the pipe. We * don't really care if this returns -1. */ while (len == 64) { char buf[64]; len = read(tp->read_fd, buf, 64); }; schedule_immediate_functions(tp); ret = pthread_mutex_unlock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return; } } static int tevent_thread_proxy_destructor(struct tevent_thread_proxy *tp) { int ret; ret = pthread_mutex_lock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return 0; } TALLOC_FREE(tp->pipe_read_fde); if (tp->read_fd != -1) { (void)close(tp->read_fd); tp->read_fd = -1; } if (tp->write_fd != -1) { (void)close(tp->write_fd); tp->write_fd = -1; } /* Hmmm. It's probably an error if we get here with any non-NULL immediate entries.. */ free_im_list(&tp->im_list); free_im_list(&tp->tofree_im_list); TALLOC_FREE(tp->free_im); ret = pthread_mutex_unlock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return 0; } ret = pthread_mutex_destroy(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return 0; } return 0; } /* * Create a struct that can be passed to other threads * to allow them to signal the struct tevent_context * * passed in. */ struct tevent_thread_proxy *tevent_thread_proxy_create( struct tevent_context *dest_ev_ctx) { int ret; int pipefds[2]; struct tevent_thread_proxy *tp; if (dest_ev_ctx->wrapper.glue != NULL) { /* * stacking of wrappers is not supported */ tevent_debug(dest_ev_ctx->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL, "%s() not allowed on a wrapper context\n", __func__); errno = EINVAL; return NULL; } tp = talloc_zero(dest_ev_ctx, struct tevent_thread_proxy); if (tp == NULL) { return NULL; } ret = pthread_mutex_init(&tp->mutex, NULL); if (ret != 0) { goto fail; } tp->dest_ev_ctx = dest_ev_ctx; tp->read_fd = -1; tp->write_fd = -1; talloc_set_destructor(tp, tevent_thread_proxy_destructor); ret = pipe(pipefds); if (ret == -1) { goto fail; } tp->read_fd = pipefds[0]; tp->write_fd = pipefds[1]; ret = ev_set_blocking(pipefds[0], false); if (ret != 0) { goto fail; } ret = ev_set_blocking(pipefds[1], false); if (ret != 0) { goto fail; } if (!ev_set_close_on_exec(pipefds[0])) { goto fail; } if (!ev_set_close_on_exec(pipefds[1])) { goto fail; } tp->pipe_read_fde = tevent_add_fd(dest_ev_ctx, tp, tp->read_fd, TEVENT_FD_READ, pipe_read_handler, tp); if (tp->pipe_read_fde == NULL) { goto fail; } /* * Create an immediate event to free * completed lists. */ tp->free_im = tevent_create_immediate(tp); if (tp->free_im == NULL) { goto fail; } return tp; fail: TALLOC_FREE(tp); return NULL; } /* * This function schedules an immediate event to be called with argument * *pp_private in the thread context of dest_ev_ctx. Caller doesn't * wait for activation to take place, this is simply fire-and-forget. * * pp_im must be a pointer to an immediate event talloced on * a context owned by the calling thread, or the NULL context. * Ownership of *pp_im will be transfered to the tevent library. * * pp_private can be null, or contents of *pp_private must be * talloc'ed memory on a context owned by the calling thread * or the NULL context. If non-null, ownership of *pp_private will * be transfered to the tevent library. * * If you want to return a message, have the destination use the * same function call to send back to the caller. */ void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, struct tevent_immediate **pp_im, tevent_immediate_handler_t handler, void *pp_private_data) { struct tevent_immediate_list *im_entry; int ret; char c; ssize_t written; ret = pthread_mutex_lock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ return; } if (tp->write_fd == -1) { /* In the process of being destroyed. Ignore. */ goto end; } /* Create a new immediate_list entry. MUST BE ON THE NULL CONTEXT */ im_entry = talloc_zero(NULL, struct tevent_immediate_list); if (im_entry == NULL) { goto end; } im_entry->handler = handler; im_entry->im = talloc_move(im_entry, pp_im); if (pp_private_data != NULL) { void **pptr = (void **)pp_private_data; im_entry->private_ptr = talloc_move(im_entry, pptr); } DLIST_ADD(tp->im_list, im_entry); /* And notify the dest_ev_ctx to wake up. */ c = '\0'; do { written = write(tp->write_fd, &c, 1); } while (written == -1 && errno == EINTR); end: ret = pthread_mutex_unlock(&tp->mutex); if (ret != 0) { abort(); /* Notreached. */ } } #else /* !HAVE_PTHREAD */ struct tevent_thread_proxy *tevent_thread_proxy_create( struct tevent_context *dest_ev_ctx) { errno = ENOSYS; return NULL; } void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, struct tevent_immediate **pp_im, tevent_immediate_handler_t handler, void *pp_private_data) { ; } #endif static int tevent_threaded_context_destructor( struct tevent_threaded_context *tctx) { struct tevent_context *main_ev = tevent_wrapper_main_ev(tctx->event_ctx); int ret; if (main_ev != NULL) { DLIST_REMOVE(main_ev->threaded_contexts, tctx); } /* * We have to coordinate with _tevent_threaded_schedule_immediate's * unlock of the event_ctx_mutex. We're in the main thread here, * and we can be scheduled before the helper thread finalizes its * call _tevent_threaded_schedule_immediate. This means we would * pthreadpool_destroy a locked mutex, which is illegal. */ ret = pthread_mutex_lock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } ret = pthread_mutex_destroy(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } return 0; } struct tevent_threaded_context *tevent_threaded_context_create( TALLOC_CTX *mem_ctx, struct tevent_context *ev) { #ifdef HAVE_PTHREAD struct tevent_context *main_ev = tevent_wrapper_main_ev(ev); struct tevent_threaded_context *tctx; int ret; ret = tevent_common_wakeup_init(main_ev); if (ret != 0) { errno = ret; return NULL; } tctx = talloc(mem_ctx, struct tevent_threaded_context); if (tctx == NULL) { return NULL; } tctx->event_ctx = ev; ret = pthread_mutex_init(&tctx->event_ctx_mutex, NULL); if (ret != 0) { TALLOC_FREE(tctx); return NULL; } DLIST_ADD(main_ev->threaded_contexts, tctx); talloc_set_destructor(tctx, tevent_threaded_context_destructor); return tctx; #else errno = ENOSYS; return NULL; #endif } static int tevent_threaded_schedule_immediate_destructor(struct tevent_immediate *im) { if (im->event_ctx != NULL) { abort(); } return 0; } void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, struct tevent_immediate *im, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location) { #ifdef HAVE_PTHREAD const char *create_location = im->create_location; struct tevent_context *main_ev = NULL; struct tevent_wrapper_glue *glue = NULL; int ret, wakeup_fd; ret = pthread_mutex_lock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } if (tctx->event_ctx == NULL) { /* * Our event context is already gone. */ ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } return; } glue = tctx->event_ctx->wrapper.glue; if ((im->event_ctx != NULL) || (handler == NULL)) { abort(); } if (im->destroyed) { abort(); } if (im->busy) { abort(); } main_ev = tevent_wrapper_main_ev(tctx->event_ctx); *im = (struct tevent_immediate) { .event_ctx = tctx->event_ctx, .wrapper = glue, .handler = handler, .private_data = private_data, .handler_name = handler_name, .create_location = create_location, .schedule_location = location, }; /* * Make sure the event won't be destroyed while * it's part of the ev->scheduled_immediates list. * _tevent_schedule_immediate() will reset the destructor * in tevent_common_threaded_activate_immediate(). */ talloc_set_destructor(im, tevent_threaded_schedule_immediate_destructor); ret = pthread_mutex_lock(&main_ev->scheduled_mutex); if (ret != 0) { abort(); } DLIST_ADD_END(main_ev->scheduled_immediates, im); wakeup_fd = main_ev->wakeup_fd; ret = pthread_mutex_unlock(&main_ev->scheduled_mutex); if (ret != 0) { abort(); } ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } /* * We might want to wake up the main thread under the lock. We * had a slightly similar situation in pthreadpool, changed * with 1c4284c7395f23. This is not exactly the same, as the * wakeup is only a last-resort thing in case the main thread * is sleeping. Doing the wakeup under the lock can easily * lead to a contended mutex, which is much more expensive * than a noncontended one. So I'd opt for the lower footprint * initially. Maybe we have to change that later. */ tevent_common_wakeup_fd(wakeup_fd); #else /* * tevent_threaded_context_create() returned NULL with ENOSYS... */ abort(); #endif } void tevent_common_threaded_activate_immediate(struct tevent_context *ev) { #ifdef HAVE_PTHREAD int ret; ret = pthread_mutex_lock(&ev->scheduled_mutex); if (ret != 0) { abort(); } while (ev->scheduled_immediates != NULL) { struct tevent_immediate *im = ev->scheduled_immediates; struct tevent_immediate copy = *im; DLIST_REMOVE(ev->scheduled_immediates, im); tevent_debug(ev, TEVENT_DEBUG_TRACE, "Schedule immediate event \"%s\": %p from thread into main\n", im->handler_name, im); im->handler_name = NULL; _tevent_schedule_immediate(im, ev, copy.handler, copy.private_data, copy.handler_name, copy.schedule_location); } ret = pthread_mutex_unlock(&ev->scheduled_mutex); if (ret != 0) { abort(); } #else /* * tevent_threaded_context_create() returned NULL with ENOSYS... */ abort(); #endif } ldb-2.0.8/lib/tevent/tevent_timed.c0000660000000000000000000002534513573675413017153 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. common events code for timed events Copyright (C) Andrew Tridgell 2003-2006 Copyright (C) Stefan Metzmacher 2005-2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "system/time.h" #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" /** compare two timeval structures. Return -1 if tv1 < tv2 Return 0 if tv1 == tv2 Return 1 if tv1 > tv2 */ int tevent_timeval_compare(const struct timeval *tv1, const struct timeval *tv2) { if (tv1->tv_sec > tv2->tv_sec) return 1; if (tv1->tv_sec < tv2->tv_sec) return -1; if (tv1->tv_usec > tv2->tv_usec) return 1; if (tv1->tv_usec < tv2->tv_usec) return -1; return 0; } /** return a zero timeval */ struct timeval tevent_timeval_zero(void) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; return tv; } /** return a timeval for the current time */ struct timeval tevent_timeval_current(void) { struct timeval tv; gettimeofday(&tv, NULL); return tv; } /** return a timeval struct with the given elements */ struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs) { struct timeval tv; tv.tv_sec = secs; tv.tv_usec = usecs; return tv; } /** return the difference between two timevals as a timeval if tv1 comes after tv2, then return a zero timeval (this is *tv2 - *tv1) */ struct timeval tevent_timeval_until(const struct timeval *tv1, const struct timeval *tv2) { struct timeval t; if (tevent_timeval_compare(tv1, tv2) >= 0) { return tevent_timeval_zero(); } t.tv_sec = tv2->tv_sec - tv1->tv_sec; if (tv1->tv_usec > tv2->tv_usec) { t.tv_sec--; t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); } else { t.tv_usec = tv2->tv_usec - tv1->tv_usec; } return t; } /** return true if a timeval is zero */ bool tevent_timeval_is_zero(const struct timeval *tv) { return tv->tv_sec == 0 && tv->tv_usec == 0; } struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, uint32_t usecs) { struct timeval tv2 = *tv; tv2.tv_sec += secs; tv2.tv_usec += usecs; tv2.tv_sec += tv2.tv_usec / 1000000; tv2.tv_usec = tv2.tv_usec % 1000000; return tv2; } /** return a timeval in the future with a specified offset */ struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs) { struct timeval tv = tevent_timeval_current(); return tevent_timeval_add(&tv, secs, usecs); } /* destroy a timed event */ static int tevent_common_timed_destructor(struct tevent_timer *te) { if (te->destroyed) { tevent_common_check_double_free(te, "tevent_timer double free"); goto done; } te->destroyed = true; if (te->event_ctx == NULL) { return 0; } tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, "Destroying timer event %p \"%s\"\n", te, te->handler_name); if (te->event_ctx->last_zero_timer == te) { te->event_ctx->last_zero_timer = DLIST_PREV(te); } DLIST_REMOVE(te->event_ctx->timer_events, te); te->event_ctx = NULL; done: if (te->busy) { return -1; } te->wrapper = NULL; return 0; } static void tevent_common_insert_timer(struct tevent_context *ev, struct tevent_timer *te, bool optimize_zero) { struct tevent_timer *prev_te = NULL; if (te->destroyed) { tevent_abort(ev, "tevent_timer use after free"); return; } /* keep the list ordered */ if (optimize_zero && tevent_timeval_is_zero(&te->next_event)) { /* * Some callers use zero tevent_timer * instead of tevent_immediate events. * * As these can happen very often, * we remember the last zero timer * in the list. */ prev_te = ev->last_zero_timer; ev->last_zero_timer = te; } else { struct tevent_timer *cur_te; /* * we traverse the list from the tail * because it's much more likely that * timers are added at the end of the list */ for (cur_te = DLIST_TAIL(ev->timer_events); cur_te != NULL; cur_te = DLIST_PREV(cur_te)) { int ret; /* * if the new event comes before the current * we continue searching */ ret = tevent_timeval_compare(&te->next_event, &cur_te->next_event); if (ret < 0) { continue; } break; } prev_te = cur_te; } DLIST_ADD_AFTER(ev->timer_events, te, prev_te); } /* add a timed event return NULL on failure (memory allocation error) */ static struct tevent_timer *tevent_common_add_timer_internal( struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location, bool optimize_zero) { struct tevent_timer *te; te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); if (te == NULL) return NULL; *te = (struct tevent_timer) { .event_ctx = ev, .next_event = next_event, .handler = handler, .private_data = private_data, .handler_name = handler_name, .location = location, }; if (ev->timer_events == NULL) { ev->last_zero_timer = NULL; } tevent_common_insert_timer(ev, te, optimize_zero); talloc_set_destructor(te, tevent_common_timed_destructor); tevent_debug(ev, TEVENT_DEBUG_TRACE, "Added timed event \"%s\": %p\n", handler_name, te); return te; } struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location) { /* * do not use optimization, there are broken Samba * versions which use tevent_common_add_timer() * without using tevent_common_loop_timer_delay(), * it just uses DLIST_REMOVE(ev->timer_events, te) * and would leave ev->last_zero_timer behind. */ return tevent_common_add_timer_internal(ev, mem_ctx, next_event, handler, private_data, handler_name, location, false); } struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location) { /* * Here we turn on last_zero_timer optimization */ return tevent_common_add_timer_internal(ev, mem_ctx, next_event, handler, private_data, handler_name, location, true); } void tevent_update_timer(struct tevent_timer *te, struct timeval next_event) { struct tevent_context *ev = te->event_ctx; if (ev->last_zero_timer == te) { te->event_ctx->last_zero_timer = DLIST_PREV(te); } DLIST_REMOVE(ev->timer_events, te); te->next_event = next_event; /* * Not doing the zero_timer optimization. This is for new code * that should know about immediates. */ tevent_common_insert_timer(ev, te, false); } int tevent_common_invoke_timer_handler(struct tevent_timer *te, struct timeval current_time, bool *removed) { struct tevent_context *handler_ev = te->event_ctx; if (removed != NULL) { *removed = false; } if (te->event_ctx == NULL) { return 0; } /* * We need to remove the timer from the list before calling the * handler because in a semi-async inner event loop called from the * handler we don't want to come across this event again -- vl */ if (te->event_ctx->last_zero_timer == te) { te->event_ctx->last_zero_timer = DLIST_PREV(te); } DLIST_REMOVE(te->event_ctx->timer_events, te); tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, "Running timer event %p \"%s\"\n", te, te->handler_name); /* * If the timed event was registered for a zero current_time, * then we pass a zero timeval here too! To avoid the * overhead of gettimeofday() calls. * * otherwise we pass the current time */ te->busy = true; if (te->wrapper != NULL) { handler_ev = te->wrapper->wrap_ev; tevent_wrapper_push_use_internal(handler_ev, te->wrapper); te->wrapper->ops->before_timer_handler( te->wrapper->wrap_ev, te->wrapper->private_state, te->wrapper->main_ev, te, te->next_event, current_time, te->handler_name, te->location); } te->handler(handler_ev, te, current_time, te->private_data); if (te->wrapper != NULL) { te->wrapper->ops->after_timer_handler( te->wrapper->wrap_ev, te->wrapper->private_state, te->wrapper->main_ev, te, te->next_event, current_time, te->handler_name, te->location); tevent_wrapper_pop_use_internal(handler_ev, te->wrapper); } te->busy = false; tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, "Ending timer event %p \"%s\"\n", te, te->handler_name); te->wrapper = NULL; te->event_ctx = NULL; talloc_set_destructor(te, NULL); TALLOC_FREE(te); if (removed != NULL) { *removed = true; } return 0; } /* do a single event loop using the events defined in ev return the delay until the next timed event, or zero if a timed event was triggered */ struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev) { struct timeval current_time = tevent_timeval_zero(); struct tevent_timer *te = ev->timer_events; int ret; if (!te) { /* have a default tick time of 30 seconds. This guarantees that code that uses its own timeout checking will be able to proceed eventually */ return tevent_timeval_set(30, 0); } /* * work out the right timeout for the next timed event * * avoid the syscall to gettimeofday() if the timed event should * be triggered directly * * if there's a delay till the next timed event, we're done * with just returning the delay */ if (!tevent_timeval_is_zero(&te->next_event)) { struct timeval delay; current_time = tevent_timeval_current(); delay = tevent_timeval_until(¤t_time, &te->next_event); if (!tevent_timeval_is_zero(&delay)) { return delay; } } /* * ok, we have a timed event that we'll process ... */ ret = tevent_common_invoke_timer_handler(te, current_time, NULL); if (ret != 0) { tevent_abort(ev, "tevent_common_invoke_timer_handler() failed"); } return tevent_timeval_zero(); } ldb-2.0.8/lib/tevent/tevent_util.c0000660000000000000000000000454612406075657017024 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Copyright (C) Andrew Tridgell 2005 Copyright (C) Jelmer Vernooij 2005 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "talloc.h" #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" #include /** return the number of elements in a string list */ size_t ev_str_list_length(const char **list) { size_t ret; for (ret=0;list && list[ret];ret++) /* noop */ ; return ret; } /** add an entry to a string list */ const char **ev_str_list_add(const char **list, const char *s) { size_t len = ev_str_list_length(list); const char **ret; ret = talloc_realloc(NULL, list, const char *, len+2); if (ret == NULL) return NULL; ret[len] = talloc_strdup(ret, s); if (ret[len] == NULL) return NULL; ret[len+1] = NULL; return ret; } /** Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, else if SYSV use O_NDELAY if BSD use FNDELAY **/ int ev_set_blocking(int fd, bool set) { int val; #ifdef O_NONBLOCK #define FLAG_TO_SET O_NONBLOCK #else #ifdef SYSV #define FLAG_TO_SET O_NDELAY #else /* BSD */ #define FLAG_TO_SET FNDELAY #endif #endif if((val = fcntl(fd, F_GETFL, 0)) == -1) return -1; if(set) /* Turn blocking on - ie. clear nonblock flag */ val &= ~FLAG_TO_SET; else val |= FLAG_TO_SET; return fcntl( fd, F_SETFL, val); #undef FLAG_TO_SET } bool ev_set_close_on_exec(int fd) { #ifdef FD_CLOEXEC int val; val = fcntl(fd, F_GETFD, 0); if (val >= 0) { val |= FD_CLOEXEC; val = fcntl(fd, F_SETFD, val); if (val != -1) { return true; } } #endif return false; } ldb-2.0.8/lib/tevent/tevent_util.h0000660000000000000000000001137413573675413017030 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Copyright (C) Andrew Tridgell 1998-2010 Copyright (C) Jelmer Vernooij 2005 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 . */ /* To use these macros you must have a structure containing a next and prev pointer */ #ifndef _DLINKLIST_H #define _DLINKLIST_H /* February 2010 - changed list format to have a prev pointer from the list head. This makes DLIST_ADD_END() O(1) even though we only have one list pointer. The scheme is as follows: 1) with no entries in the list: list_head == NULL 2) with 1 entry in the list: list_head->next == NULL list_head->prev == list_head 3) with 2 entries in the list: list_head->next == element2 list_head->prev == element2 element2->prev == list_head element2->next == NULL 4) with N entries in the list: list_head->next == element2 list_head->prev == elementN elementN->prev == element{N-1} elementN->next == NULL This allows us to find the tail of the list by using list_head->prev, which means we can add to the end of the list in O(1) time */ /* add an element at the front of a list */ #define DLIST_ADD(list, p) \ do { \ if (!(list)) { \ (p)->prev = (list) = (p); \ (p)->next = NULL; \ } else { \ (p)->prev = (list)->prev; \ (list)->prev = (p); \ (p)->next = (list); \ (list) = (p); \ } \ } while (0) /* remove an element from a list Note that the element doesn't have to be in the list. If it isn't then this is a no-op */ #define DLIST_REMOVE(list, p) \ do { \ if ((p) == (list)) { \ if ((p)->next) (p)->next->prev = (p)->prev; \ (list) = (p)->next; \ } else if ((p)->prev && (list) && (p) == (list)->prev) { \ (p)->prev->next = NULL; \ (list)->prev = (p)->prev; \ } else { \ if ((p)->prev) (p)->prev->next = (p)->next; \ if ((p)->next) (p)->next->prev = (p)->prev; \ } \ if ((p) != (list)) (p)->next = (p)->prev = NULL; \ } while (0) /* find the head of the list given any element in it. Note that this costs O(N), so you should avoid this macro if at all possible! */ #define DLIST_HEAD(p, result_head) \ do { \ (result_head) = (p); \ while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ } while(0) /* return the last element in the list */ #define DLIST_TAIL(list) ((list)?(list)->prev:NULL) /* return the previous element in the list. */ #define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) /* insert 'p' after the given element 'el' in a list. If el is NULL then this is the same as a DLIST_ADD() */ #define DLIST_ADD_AFTER(list, p, el) \ do { \ if (!(list) || !(el)) { \ DLIST_ADD(list, p); \ } else { \ (p)->prev = (el); \ (p)->next = (el)->next; \ (el)->next = (p); \ if ((p)->next) (p)->next->prev = (p); \ if ((list)->prev == (el)) (list)->prev = (p); \ }\ } while (0) /* add to the end of a list. */ #define DLIST_ADD_END(list, p) \ do { \ if (!(list)) { \ DLIST_ADD(list, p); \ } else { \ DLIST_ADD_AFTER(list, p, (list)->prev); \ } \ } while (0) /* promote an element to the front of a list */ #define DLIST_PROMOTE(list, p) \ do { \ DLIST_REMOVE(list, p); \ DLIST_ADD(list, p); \ } while (0) /* demote an element to the end of a list. */ #define DLIST_DEMOTE(list, p) \ do { \ DLIST_REMOVE(list, p); \ DLIST_ADD_END(list, p); \ } while (0) /* concatenate two lists - putting all elements of the 2nd list at the end of the first list. */ #define DLIST_CONCATENATE(list1, list2) \ do { \ if (!(list1)) { \ (list1) = (list2); \ } else { \ (list1)->prev->next = (list2); \ if (list2) { \ void *_tmplist = (void *)(list1)->prev; \ (list1)->prev = (list2)->prev; \ (list2)->prev = _tmplist; \ } \ } \ } while (0) #endif /* _DLINKLIST_H */ const char **ev_str_list_add(const char **list, const char *s); int ev_set_blocking(int fd, bool set); size_t ev_str_list_length(const char **list); bool ev_set_close_on_exec(int fd); /* Defined here so we can build against older talloc versions that don't * have this define yet. */ #ifndef TALLOC_FREE #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) #endif ldb-2.0.8/lib/tevent/tevent_wakeup.c0000660000000000000000000000341612406075657017336 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Infrastructure for async requests Copyright (C) Volker Lendecke 2008 Copyright (C) Stefan Metzmacher 2009 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" struct tevent_wakeup_state { struct timeval wakeup_time; }; struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct timeval wakeup_time) { struct tevent_req *req; struct tevent_wakeup_state *state; req = tevent_req_create(mem_ctx, &state, struct tevent_wakeup_state); if (!req) { return NULL; } state->wakeup_time = wakeup_time; if (!tevent_req_set_endtime(req, ev, wakeup_time)) { return tevent_req_post(req, ev); } return req; } bool tevent_wakeup_recv(struct tevent_req *req) { enum tevent_req_state state; uint64_t error; if (tevent_req_is_error(req, &state, &error)) { if (state == TEVENT_REQ_TIMED_OUT) { return true; } } return false; } ldb-2.0.8/lib/tevent/tevent_wrapper.c0000660000000000000000000003176513573675413017534 0ustar rootroot00000000000000/* Infrastructure for event context wrappers Copyright (C) Stefan Metzmacher 2014 ** NOTE! The following LGPL license applies to the tevent ** 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 . */ #include "replace.h" #ifdef HAVE_PTHREAD #include "system/threads.h" #endif #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" static int tevent_wrapper_glue_context_init(struct tevent_context *ev) { tevent_abort(ev, "tevent_wrapper_glue_context_init() called"); errno = ENOSYS; return -1; } static struct tevent_fd *tevent_wrapper_glue_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int fd, uint16_t flags, tevent_fd_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct tevent_wrapper_glue *glue = ev->wrapper.glue; struct tevent_fd *fde = NULL; if (glue->destroyed) { tevent_abort(ev, "add_fd wrapper use after free"); return NULL; } if (glue->main_ev == NULL) { errno = EINVAL; return NULL; } fde = _tevent_add_fd(glue->main_ev, mem_ctx, fd, flags, handler, private_data, handler_name, location); if (fde == NULL) { return NULL; } fde->wrapper = glue; return fde; } static struct tevent_timer *tevent_wrapper_glue_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct tevent_wrapper_glue *glue = ev->wrapper.glue; struct tevent_timer *te = NULL; if (glue->destroyed) { tevent_abort(ev, "add_timer wrapper use after free"); return NULL; } if (glue->main_ev == NULL) { errno = EINVAL; return NULL; } te = _tevent_add_timer(glue->main_ev, mem_ctx, next_event, handler, private_data, handler_name, location); if (te == NULL) { return NULL; } te->wrapper = glue; return te; } static void tevent_wrapper_glue_schedule_immediate(struct tevent_immediate *im, struct tevent_context *ev, tevent_immediate_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct tevent_wrapper_glue *glue = ev->wrapper.glue; if (glue->destroyed) { tevent_abort(ev, "scheduke_immediate wrapper use after free"); return; } if (glue->main_ev == NULL) { tevent_abort(ev, location); errno = EINVAL; return; } _tevent_schedule_immediate(im, glue->main_ev, handler, private_data, handler_name, location); im->wrapper = glue; return; } static struct tevent_signal *tevent_wrapper_glue_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, int signum, int sa_flags, tevent_signal_handler_t handler, void *private_data, const char *handler_name, const char *location) { struct tevent_wrapper_glue *glue = ev->wrapper.glue; struct tevent_signal *se = NULL; if (glue->destroyed) { tevent_abort(ev, "add_signal wrapper use after free"); return NULL; } if (glue->main_ev == NULL) { errno = EINVAL; return NULL; } se = _tevent_add_signal(glue->main_ev, mem_ctx, signum, sa_flags, handler, private_data, handler_name, location); if (se == NULL) { return NULL; } se->wrapper = glue; return se; } static int tevent_wrapper_glue_loop_once(struct tevent_context *ev, const char *location) { tevent_abort(ev, "tevent_wrapper_glue_loop_once() called"); errno = ENOSYS; return -1; } static int tevent_wrapper_glue_loop_wait(struct tevent_context *ev, const char *location) { tevent_abort(ev, "tevent_wrapper_glue_loop_wait() called"); errno = ENOSYS; return -1; } static const struct tevent_ops tevent_wrapper_glue_ops = { .context_init = tevent_wrapper_glue_context_init, .add_fd = tevent_wrapper_glue_add_fd, .set_fd_close_fn = tevent_common_fd_set_close_fn, .get_fd_flags = tevent_common_fd_get_flags, .set_fd_flags = tevent_common_fd_set_flags, .add_timer = tevent_wrapper_glue_add_timer, .schedule_immediate = tevent_wrapper_glue_schedule_immediate, .add_signal = tevent_wrapper_glue_add_signal, .loop_once = tevent_wrapper_glue_loop_once, .loop_wait = tevent_wrapper_glue_loop_wait, }; static int tevent_wrapper_context_destructor(struct tevent_context *wrap_ev) { struct tevent_wrapper_glue *glue = wrap_ev->wrapper.glue; struct tevent_context *main_ev = NULL; struct tevent_fd *fd = NULL, *fn = NULL; struct tevent_timer *te = NULL, *tn = NULL; struct tevent_immediate *ie = NULL, *in = NULL; struct tevent_signal *se = NULL, *sn = NULL; #ifdef HAVE_PTHREAD struct tevent_threaded_context *tctx = NULL, *tctxn = NULL; #endif if (glue == NULL) { tevent_abort(wrap_ev, "tevent_wrapper_context_destructor() active on main"); /* static checker support, return below is never reached */ return -1; } if (glue->destroyed && glue->busy) { tevent_common_check_double_free(wrap_ev, "tevent_context wrapper double free"); } glue->destroyed = true; if (glue->busy) { return -1; } main_ev = glue->main_ev; if (main_ev == NULL) { return 0; } tevent_debug(wrap_ev, TEVENT_DEBUG_TRACE, "Destroying wrapper context %p \"%s\"\n", wrap_ev, talloc_get_name(glue->private_state)); glue->main_ev = NULL; DLIST_REMOVE(main_ev->wrapper.list, glue); #ifdef HAVE_PTHREAD for (tctx = main_ev->threaded_contexts; tctx != NULL; tctx = tctxn) { int ret; tctxn = tctx->next; if (tctx->event_ctx != glue->wrap_ev) { continue; } ret = pthread_mutex_lock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } /* * Indicate to the thread that the tevent_context is * gone. The counterpart of this is in * _tevent_threaded_schedule_immediate, there we read * this under the threaded_context's mutex. */ tctx->event_ctx = NULL; ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); } DLIST_REMOVE(main_ev->threaded_contexts, tctx); } #endif for (fd = main_ev->fd_events; fd; fd = fn) { fn = fd->next; if (fd->wrapper != glue) { continue; } tevent_fd_set_flags(fd, 0); fd->wrapper = NULL; fd->event_ctx = NULL; DLIST_REMOVE(main_ev->fd_events, fd); } for (te = main_ev->timer_events; te; te = tn) { tn = te->next; if (te->wrapper != glue) { continue; } te->wrapper = NULL; te->event_ctx = NULL; if (main_ev->last_zero_timer == te) { main_ev->last_zero_timer = DLIST_PREV(te); } DLIST_REMOVE(main_ev->timer_events, te); } for (ie = main_ev->immediate_events; ie; ie = in) { in = ie->next; if (ie->wrapper != glue) { continue; } ie->wrapper = NULL; ie->event_ctx = NULL; ie->cancel_fn = NULL; DLIST_REMOVE(main_ev->immediate_events, ie); } for (se = main_ev->signal_events; se; se = sn) { sn = se->next; if (se->wrapper != glue) { continue; } se->wrapper = NULL; tevent_cleanup_pending_signal_handlers(se); } return 0; } struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev, TALLOC_CTX *mem_ctx, const struct tevent_wrapper_ops *ops, void *pstate, size_t psize, const char *type, const char *location) { void **ppstate = (void **)pstate; struct tevent_context *ev = NULL; if (main_ev->wrapper.glue != NULL) { /* * stacking of wrappers is not supported */ tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL, "%s: %s() stacking not allowed\n", __func__, location); errno = EINVAL; return NULL; } if (main_ev->nesting.allowed) { /* * wrappers conflict with nesting */ tevent_debug(main_ev, TEVENT_DEBUG_FATAL, "%s: %s() conflicts with nesting\n", __func__, location); errno = EINVAL; return NULL; } ev = talloc_zero(mem_ctx, struct tevent_context); if (ev == NULL) { return NULL; } ev->ops = &tevent_wrapper_glue_ops; ev->wrapper.glue = talloc_zero(ev, struct tevent_wrapper_glue); if (ev->wrapper.glue == NULL) { talloc_free(ev); return NULL; } talloc_set_destructor(ev, tevent_wrapper_context_destructor); ev->wrapper.glue->wrap_ev = ev; ev->wrapper.glue->main_ev = main_ev; ev->wrapper.glue->ops = ops; ev->wrapper.glue->private_state = talloc_zero_size(ev->wrapper.glue, psize); if (ev->wrapper.glue->private_state == NULL) { talloc_free(ev); return NULL; } talloc_set_name_const(ev->wrapper.glue->private_state, type); DLIST_ADD_END(main_ev->wrapper.list, ev->wrapper.glue); *ppstate = ev->wrapper.glue->private_state; return ev; } bool tevent_context_is_wrapper(struct tevent_context *ev) { if (ev->wrapper.glue != NULL) { return true; } return false; } _PRIVATE_ struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev) { if (ev == NULL) { return NULL; } if (ev->wrapper.glue == NULL) { return ev; } return ev->wrapper.glue->main_ev; } /* * 32 stack elements should be more than enough * * e.g. Samba uses just 8 elements for [un]become_{root,user}() */ #define TEVENT_WRAPPER_STACK_SIZE 32 static struct tevent_wrapper_stack { const void *ev_ptr; const struct tevent_wrapper_glue *wrapper; } wrapper_stack[TEVENT_WRAPPER_STACK_SIZE]; static size_t wrapper_stack_idx; _PRIVATE_ void tevent_wrapper_push_use_internal(struct tevent_context *ev, struct tevent_wrapper_glue *wrapper) { /* * ev and wrapper need to belong together! * It's also fine to only have a raw ev * without a wrapper. */ if (unlikely(ev->wrapper.glue != wrapper)) { tevent_abort(ev, "tevent_wrapper_push_use_internal() invalid arguments"); return; } if (wrapper != NULL) { if (unlikely(wrapper->busy)) { tevent_abort(ev, "wrapper already busy!"); return; } wrapper->busy = true; } if (unlikely(wrapper_stack_idx >= TEVENT_WRAPPER_STACK_SIZE)) { tevent_abort(ev, "TEVENT_WRAPPER_STACK_SIZE overflow"); return; } wrapper_stack[wrapper_stack_idx] = (struct tevent_wrapper_stack) { .ev_ptr = ev, .wrapper = wrapper, }; wrapper_stack_idx++; } _PRIVATE_ void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr, struct tevent_wrapper_glue *wrapper) { struct tevent_context *main_ev = NULL; /* * Note that __ev_ptr might a a stale pointer and should not * be touched, we just compare the pointer value in order * to enforce the stack order. */ if (wrapper != NULL) { main_ev = wrapper->main_ev; } if (unlikely(wrapper_stack_idx == 0)) { tevent_abort(main_ev, "tevent_wrapper stack already empty"); return; } wrapper_stack_idx--; if (wrapper != NULL) { wrapper->busy = false; } if (wrapper_stack[wrapper_stack_idx].ev_ptr != __ev_ptr) { tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch ev!"); return; } if (wrapper_stack[wrapper_stack_idx].wrapper != wrapper) { tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch wrap!"); return; } if (wrapper == NULL) { return; } if (wrapper->destroyed) { /* * Notice that we can't use TALLOC_FREE() * here because wrapper is a talloc child * of wrapper->wrap_ev. */ talloc_free(wrapper->wrap_ev); } } bool _tevent_context_push_use(struct tevent_context *ev, const char *location) { bool ok; if (ev->wrapper.glue == NULL) { tevent_wrapper_push_use_internal(ev, NULL); return true; } if (ev->wrapper.glue->main_ev == NULL) { return false; } tevent_wrapper_push_use_internal(ev, ev->wrapper.glue); ok = ev->wrapper.glue->ops->before_use(ev->wrapper.glue->wrap_ev, ev->wrapper.glue->private_state, ev->wrapper.glue->main_ev, location); if (!ok) { tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue); return false; } return true; } void _tevent_context_pop_use(struct tevent_context *ev, const char *location) { tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue); if (ev->wrapper.glue == NULL) { return; } if (ev->wrapper.glue->main_ev == NULL) { return; } ev->wrapper.glue->ops->after_use(ev->wrapper.glue->wrap_ev, ev->wrapper.glue->private_state, ev->wrapper.glue->main_ev, location); } bool tevent_context_same_loop(struct tevent_context *ev1, struct tevent_context *ev2) { struct tevent_context *main_ev1 = tevent_wrapper_main_ev(ev1); struct tevent_context *main_ev2 = tevent_wrapper_main_ev(ev2); if (main_ev1 == NULL) { return false; } if (main_ev1 == main_ev2) { return true; } return false; } ldb-2.0.8/lib/tevent/wscript0000660000000000000000000001121613573675413015726 0ustar rootroot00000000000000#!/usr/bin/env python APPNAME = 'tevent' VERSION = '0.10.0' import sys, os # find the buildtools directory top = '.' while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: top = top + '/..' sys.path.insert(0, top + '/buildtools/wafsamba') out = 'bin' import wafsamba from wafsamba import samba_dist, samba_utils from waflib import Options, Logs, Context samba_dist.DIST_DIRS('lib/tevent:. lib/replace:lib/replace lib/talloc:lib/talloc buildtools:buildtools third_party/waf:third_party/waf') def options(opt): opt.BUILTIN_DEFAULT('replace') opt.PRIVATE_EXTENSION_DEFAULT('tevent', noextension='tevent') opt.RECURSE('lib/replace') opt.RECURSE('lib/talloc') def configure(conf): conf.RECURSE('lib/replace') conf.RECURSE('lib/talloc') conf.env.standalone_tevent = conf.IN_LAUNCH_DIR() if not conf.env.standalone_tevent: if conf.CHECK_BUNDLED_SYSTEM_PKG('tevent', minversion=VERSION, onlyif='talloc', implied_deps='replace talloc'): conf.define('USING_SYSTEM_TEVENT', 1) if not conf.env.disable_python and \ conf.CHECK_BUNDLED_SYSTEM_PYTHON('pytevent', 'tevent', minversion=VERSION): conf.define('USING_SYSTEM_PYTEVENT', 1) if conf.CHECK_FUNCS('epoll_create', headers='sys/epoll.h'): conf.DEFINE('HAVE_EPOLL', 1) tevent_num_signals = 64 v = conf.CHECK_VALUEOF('NSIG', headers='signal.h') if v is not None: tevent_num_signals = max(tevent_num_signals, v) v = conf.CHECK_VALUEOF('_NSIG', headers='signal.h') if v is not None: tevent_num_signals = max(tevent_num_signals, v) v = conf.CHECK_VALUEOF('SIGRTMAX', headers='signal.h') if v is not None: tevent_num_signals = max(tevent_num_signals, v) v = conf.CHECK_VALUEOF('SIGRTMIN', headers='signal.h') if v is not None: tevent_num_signals = max(tevent_num_signals, v*2) if not conf.CONFIG_SET('USING_SYSTEM_TEVENT'): conf.DEFINE('TEVENT_NUM_SIGNALS', tevent_num_signals) conf.SAMBA_CHECK_PYTHON() conf.SAMBA_CHECK_PYTHON_HEADERS() conf.SAMBA_CONFIG_H() conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() def build(bld): bld.RECURSE('lib/replace') bld.RECURSE('lib/talloc') SRC = '''tevent.c tevent_debug.c tevent_fd.c tevent_immediate.c tevent_queue.c tevent_req.c tevent_wrapper.c tevent_poll.c tevent_threads.c tevent_signal.c tevent_standard.c tevent_timed.c tevent_util.c tevent_wakeup.c''' if bld.CONFIG_SET('HAVE_EPOLL'): SRC += ' tevent_epoll.c' if bld.CONFIG_SET('HAVE_SOLARIS_PORTS'): SRC += ' tevent_port.c' if bld.env.standalone_tevent: bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' private_library = False else: private_library = True if not bld.CONFIG_SET('USING_SYSTEM_TEVENT'): tevent_deps = 'replace talloc' if bld.CONFIG_SET('HAVE_PTHREAD'): tevent_deps += ' pthread' bld.SAMBA_LIBRARY('tevent', SRC, deps=tevent_deps, enabled= not bld.CONFIG_SET('USING_SYSTEM_TEVENT'), includes='.', abi_directory='ABI', abi_match='tevent_* _tevent_*', vnum=VERSION, public_headers=('' if private_library else 'tevent.h'), public_headers_install=not private_library, pc_files='tevent.pc', private_library=private_library) if not bld.CONFIG_SET('USING_SYSTEM_PYTEVENT') and not bld.env.disable_python: bld.SAMBA_PYTHON('_tevent', 'pytevent.c', deps='tevent', realname='_tevent.so', cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) bld.INSTALL_WILDCARD('${PYTHONARCHDIR}', 'tevent.py', flat=False) # install out various python scripts for use by make test bld.SAMBA_SCRIPT('tevent_python', pattern='tevent.py', installdir='python') def test(ctx): '''test tevent''' print("The tevent testsuite is part of smbtorture in samba4") samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') pyret = samba_utils.RUN_PYTHON_TESTS(['bindings.py']) sys.exit(pyret) def dist(): '''makes a tarball for distribution''' samba_dist.dist() def reconfigure(ctx): '''reconfigure if config scripts have changed''' samba_utils.reconfigure(ctx) ldb-2.0.8/third_party/popt/CHANGES0000660000000000000000000000244112406075661016534 0ustar rootroot000000000000001.5 -> 1.6 - add ability to perform callbacks for every, not just first, match. 1.3 -> 1.5 - heavy dose of const's - poptParseArgvString() now NULL terminates the list 1.2.3 -> 1.3 - added support for single - - misc bug fixes - portability improvements 1.2.2 -> 1.2.3 - fixed memset() in help message generation (Dale Hawkins) - added extern "C" stuff to popt.h for C++ compilers (Dale Hawkins) - const'ified poptParseArgvString (Jeff Garzik) 1.2.1 -> 1.2.2 - fixed bug in chaind alias happens which seems to have only affected --triggers in rpm - added POPT_ARG_VAL - popt.3 installed by default 1.2 -> 1.2.1 - added POPT_ARG_INTL_DOMAIN (Elliot Lee) - updated Makefile's to be more GNUish (Elliot Lee) 1.1 -> 1.2 - added popt.3 man page (Robert Lynch) - don't use mmap anymore (its lack of portability isn't worth the trouble) - added test script - added support for exec - removed support for *_POPT_ALIASES env variable -- it was a bad idea - reorganized into multiple source files - added automatic help generation, POPT_AUTOHELP - added table callbacks - added table inclusion - updated man page for new features - added test scripts 1.0 -> 1.1 - moved to autoconf (Fred Fish) - added STRERROR replacement (Norbert Warmuth) - added const keywords (Bruce Perens) ldb-2.0.8/third_party/popt/COPYING0000660000000000000000000000237512406075661016602 0ustar rootroot00000000000000Copyright (c) 1998 Red Hat Software Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. ldb-2.0.8/third_party/popt/README0000660000000000000000000000132113444661622016416 0ustar rootroot00000000000000This is the popt(3) 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 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 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. ldb-2.0.8/third_party/popt/findme.h0000660000000000000000000000077012406075661017157 0ustar rootroot00000000000000/** \ingroup popt * \file popt/findme.h */ /* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.rpm.org/pub/rpm/dist. */ #ifndef H_FINDME #define H_FINDME /** * Return absolute path to executable by searching PATH. * @param argv0 name of executable * @return (malloc'd) absolute path to executable (or NULL) */ /*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0) /*@*/; #endif ldb-2.0.8/third_party/popt/lookup3.c0000660000000000000000000007572713444661622017323 0ustar rootroot00000000000000/* -------------------------------------------------------------------- */ /* * 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 #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 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>(8-j)); c[0] = jlu32l(m, a, hlen); 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; lz) 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 #endif #include #include "poptint.h" #ifdef MYDEBUG /*@unchecked@*/ 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) { extern int sys_nerr; extern char * sys_errlist[]; if ((0 <= errno) && (errno < sys_nerr)) return sys_errlist[errno]; else return POPT_("unknown errno"); } #endif #ifdef MYDEBUG /*@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", con, con->os, (con->os->nextCharArg ? con->os->nextCharArg : ""), (con->os->nextArg ? con->os->nextArg : ""), con->os->next, (con->os->argv && con->os->argv[con->os->next] ? con->os->argv[con->os->next] : "")); } #endif void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) { con->execPath = _free(con->execPath); con->execPath = xstrdup(path); con->execAbsolute = allowAbsolute; return; } static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt) /*@globals internalState@*/ /*@modifies internalState@*/ { 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; } } } static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt) /*@globals internalState@*/ /*@modifies internalState@*/ { 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; } } } static void invokeCallbacksOPTION(poptContext con, 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; 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 && !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; } /*@switchbreak@*/ break; } } } poptContext poptGetContext(const char * name, int argc, const char ** argv, const struct poptOption * options, unsigned int flags) { poptContext con = 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? */ con->os->argv = argv; /*@=dependenttrans =assignexpose@*/ con->os->argb = NULL; if (!(flags & POPT_CONTEXT_KEEP_FIRST)) con->os->next = 1; /* skip argv[0] */ con->leftovers = calloc( (size_t)(argc + 1), sizeof(*con->leftovers) ); /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ con->options = options; /*@=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->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); invokeCallbacksPRE(con, con->options); return con; } static void cleanOSE(/*@special@*/ struct optionStackEntry *os) /*@uses 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); } void poptResetContext(poptContext con) { int i; if (con == NULL) return; while (con->os > con->optionStack) { cleanOSE(con->os--); } con->os->argb = PBM_FREE(con->os->argb); con->os->currAlias = NULL; con->os->nextCharArg = NULL; con->os->nextArg = NULL; con->os->next = 1; /* skip argv[0] */ con->numLeftovers = 0; con->nextLeftover = 0; con->restLeftover = 0; con->doExec = NULL; if (con->finalArgv != NULL) for (i = 0; i < con->finalArgvCount; i++) { /*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */ con->finalArgv[i] = _free(con->finalArgv[i]); /*@=unqualifiedtrans@*/ } con->finalArgvCount = 0; con->arg_strip = PBM_FREE(con->arg_strip); /*@-nullstate@*/ /* FIX: con->finalArgv != NULL */ return; /*@=nullstate@*/ } /* Only one of longName, shortName should be set, not both. */ static int handleExec(/*@special@*/ poptContext con, /*@null@*/ const char * longName, char shortName) /*@uses con->execs, con->numExecs, con->flags, con->doExec, con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/ /*@modifies con @*/ { poptItem item; int i; if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */ return 0; for (i = con->numExecs - 1; i >= 0; i--) { item = con->execs + i; if (longName && !(item->option.longName && !strcmp(longName, item->option.longName))) continue; else if (shortName != item->option.shortName) continue; break; } if (i < 0) return 0; if (con->flags & POPT_CONTEXT_NO_EXEC) return 1; if (con->doExec == NULL) { con->doExec = con->execs + i; return 1; } /* We already have an exec to do; remember this option for next time 'round */ if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { con->finalArgvAlloced += 10; con->finalArgv = 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("--")); if (s != NULL) { /* XXX can't happen */ con->finalArgv[i] = s; *s++ = '-'; if (longName) s = stpcpy( stpcpy(s, "-"), longName); else *s++ = shortName; *s = '\0'; } else con->finalArgv[i] = NULL; } return 1; } /** * 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; } /* 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) /*@uses con->aliases, con->numAliases, con->optionStack, con->os, con->os->currAlias, con->os->currAlias->option.longName @*/ /*@modifies con @*/ { poptItem item = con->os->currAlias; int rc; int i; if (item) { if (longName && item->option.longName != NULL && longOptionStrcmp(&item->option, longName, longNameLen)) return 0; else if (shortName && shortName == item->option.shortName) return 0; } if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */ return 0; 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) continue; break; } if (i < 0) return 0; if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) return POPT_ERROR_OPTSTOODEEP; if (longName == NULL && nextArg != NULL && *nextArg != '\0') con->os->nextCharArg = nextArg; con->os++; con->os->next = 0; con->os->stuffed = 0; 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); } 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; } static int execCommand(poptContext con) /*@globals internalState @*/ /*@modifies internalState @*/ { poptItem item = con->doExec; poptArgv argv = NULL; int argc = 0; int rc; int ec = POPT_ERROR_ERRNO; if (item == NULL) /*XXX can't happen*/ return POPT_ERROR_NOARG; if (item->argv == NULL || item->argc < 1 || (!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[argc] = s; } else argv[argc] = findProgramPath(item->argv[0]); if (argv[argc++] == NULL) { ec = POPT_ERROR_NOARG; goto exit; } if (item->argc > 1) { memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); argc += (item->argc - 1); } if (con->finalArgv != NULL && con->finalArgvCount > 0) { memcpy(argv + argc, con->finalArgv, sizeof(*argv) * con->finalArgvCount); argc += con->finalArgvCount; } if (con->leftovers != NULL && con->numLeftovers > 0) { 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; rc = setresuid(getuid(), getuid(),-1); if (rc) goto exit; #else /* * XXX " ... on BSD systems setuid() should be preferred over setreuid()" * XXX sez' Timur Bakeyev * XXX from Norbert Warmuth */ #if defined(HAVE_SETUID) rc = setgid(getgid()); if (rc) goto exit; rc = setuid(getuid()); if (rc) goto exit; #elif defined (HAVE_SETREUID) rc = setregid(getgid(), getgid()); if (rc) goto exit; rc = setreuid(getuid(), getuid()); if (rc) goto exit; #else ; /* Can't drop privileges */ #endif #endif #ifdef MYDEBUG if (_popt_debug) { poptArgv avp; fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc); for (avp = argv; *avp; avp++) fprintf(stderr, " '%s'", *avp); fprintf(stderr, "\n"); } #endif /*@-nullstate@*/ rc = execvp(argv[0], (char *const *)argv); /*@=nullstate@*/ exit: if (argv) { if (argv[0]) free((void *)argv[0]); free(argv); } return ec; } /*@observer@*/ /*@null@*/ static const struct poptOption * findOption(const struct poptOption * opt, /*@null@*/ const char * longName, size_t longNameLen, char shortName, /*@null@*/ /*@out@*/ poptCallbackType * callback, /*@null@*/ /*@out@*/ const void ** callbackData, unsigned int argInfo) /*@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')) 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; poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ if (arg.ptr == NULL) continue; /* XXX program error */ opt2 = findOption(arg.opt, longName, longNameLen, shortName, callback, callbackData, argInfo); 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 @*/ return opt2; } /*@notreached@*/ /*@switchbreak@*/ break; case 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)) { break; } else if (shortName && shortName == opt->shortName) { break; } } if (opt->longName == NULL && !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 @*/ return opt; } static const char * findNextArg(/*@special@*/ poptContext con, unsigned argx, int delete_arg) /*@uses con->optionStack, con->os, con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ /*@modifies con @*/ { struct optionStackEntry * os = con->os; const char * arg; do { int i; arg = NULL; while (os->next == os->argc && os > con->optionStack) os--; if (os->next == os->argc && os == con->optionStack) break; if (os->argv != NULL) for (i = os->next; i < os->argc; i++) { /*@-sizeoftype@*/ if (os->argb && PBM_ISSET(i, os->argb)) /*@innercontinue@*/ continue; if (*os->argv[i] == '-') /*@innercontinue@*/ continue; if (--argx > 0) /*@innercontinue@*/ continue; arg = os->argv[i]; if (delete_arg) { if (os->argb == NULL) os->argb = PBM_ALLOC(os->argc); if (os->argb != NULL) /* XXX can't happen */ PBM_SET(i, os->argb); } /*@innerbreak@*/ break; /*@=sizeoftype@*/ } if (os > con->optionStack) os--; } while (arg == NULL); return arg; } static /*@only@*/ /*@null@*/ const char * expandNextArg(/*@special@*/ poptContext con, const char * s) /*@uses con->optionStack, con->os, con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ /*@modifies con @*/ { const char * a = NULL; char *t, *te; size_t tn = strlen(s) + 1; char c; te = t = 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 */ case '\\': /* escape */ c = *s++; /*@switchbreak@*/ break; #endif case '!': if (!(s[0] == '#' && s[1] == ':' && s[2] == '+')) /*@switchbreak@*/ break; /* XXX Make sure that findNextArg deletes only next arg. */ if (a == NULL) { if ((a = findNextArg(con, 1U, 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); } continue; /*@notreached@*/ /*@switchbreak@*/ break; default: /*@switchbreak@*/ break; } *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@*/ } return t; } static void poptStripArg(/*@special@*/ poptContext con, int which) /*@uses con->optionStack @*/ /*@defines con->arg_strip @*/ /*@modifies con @*/ { /*@-compdef -sizeoftype -usedef @*/ if (con->arg_strip == NULL) con->arg_strip = PBM_ALLOC(con->optionStack[0].argc); if (con->arg_strip != NULL) /* XXX can't happen */ PBM_SET(which, con->arg_strip); 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; } int poptBitsChk(poptBits bits, const char * s) { 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 ) 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)) { case 0: *arg = aLongLong; break; case POPT_ARGFLAG_OR: *(unsigned long long *)arg |= (unsigned long long)aLongLong; break; case POPT_ARGFLAG_AND: *(unsigned long long *)arg &= (unsigned long long)aLongLong; break; case POPT_ARGFLAG_XOR: *(unsigned long long *)arg ^= (unsigned long long)aLongLong; break; default: return POPT_ERROR_BADOPERATION; /*@notreached@*/ break; } return 0; } int poptSaveLong(long * 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 = 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; break; case POPT_ARGFLAG_OR: *(unsigned short *)arg |= (unsigned short) aLong; break; case POPT_ARGFLAG_AND: *(unsigned short *)arg &= (unsigned short) aLong; break; case POPT_ARGFLAG_XOR: *(unsigned short *)arg ^= (unsigned short) aLong; break; 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 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; } /* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ int poptGetNextOpt(poptContext con) { const struct poptOption * opt = NULL; int done = 0; if (con == NULL) return -1; while (!done) { const char * origOptString = NULL; poptCallbackType cb = NULL; const void * cbData = NULL; const char * longArg = NULL; int canstrip = 0; int shorty = 0; while (!con->os->nextCharArg && con->os->next == con->os->argc && con->os > con->optionStack) { cleanOSE(con->os--); } if (!con->os->nextCharArg && con->os->next == con->os->argc) { invokeCallbacksPOST(con, con->options); if (con->maincall) { /*@-noeffectuncon @*/ (void) (*con->maincall) (con->finalArgvCount, con->finalArgv); /*@=noeffectuncon @*/ return -1; } if (con->doExec) return execCommand(con); return -1; } /* Process next long option */ if (!con->os->nextCharArg) { const char * optString; size_t optStringLen; int thisopt; /*@-sizeoftype@*/ if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { con->os->next++; continue; } /*@=sizeoftype@*/ thisopt = con->os->next; if (con->os->argv != NULL) /* XXX can't happen */ origOptString = con->os->argv[con->os->next++]; if (origOptString == NULL) /* XXX can't happen */ return POPT_ERROR_BADOPT; if (con->restLeftover || *origOptString != '-' || (*origOptString == '-' && origOptString[1] == '\0')) { if (con->flags & POPT_CONTEXT_POSIXMEHARDER) con->restLeftover = 1; if (con->flags & POPT_CONTEXT_ARG_OPTS) { con->os->nextArg = xstrdup(origOptString); return 0; } if (con->leftovers != NULL) /* XXX can't happen */ con->leftovers[con->numLeftovers++] = origOptString; continue; } /* Make a copy we can hack at */ optString = origOptString; if (optString[0] == '\0') return POPT_ERROR_BADOPT; if (optString[1] == '-' && !optString[2]) { con->restLeftover = 1; continue; } else { const char *oe; unsigned int argInfo = 0; optString++; if (*optString == '-') 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; /* XXX aliases with arg substitution need "--alias=arg" */ if (handleAlias(con, optString, optStringLen, '\0', longArg)) { longArg = NULL; continue; } if (handleExec(con, optString, '\0')) continue; opt = findOption(con->options, optString, optStringLen, '\0', &cb, &cbData, argInfo); if (!opt && !LF_ISSET(ONEDASH)) return POPT_ERROR_BADOPT; } if (!opt) { con->os->nextCharArg = origOptString + 1; longArg = NULL; } else { if (con->os == con->optionStack && F_ISSET(opt, STRIP)) { canstrip = 1; poptStripArg(con, thisopt); } shorty = 0; } } /* Process next short option */ if (con->os->nextCharArg) { const char * nextCharArg = con->os->nextCharArg; con->os->nextCharArg = NULL; if (handleAlias(con, NULL, 0, *nextCharArg, nextCharArg + 1)) continue; if (handleExec(con, NULL, *nextCharArg)) { /* Restore rest of short options for further processing */ nextCharArg++; if (*nextCharArg != '\0') con->os->nextCharArg = nextCharArg; continue; } opt = findOption(con->options, NULL, 0, *nextCharArg, &cb, &cbData, 0); if (!opt) return POPT_ERROR_BADOPT; shorty = 1; nextCharArg++; if (*nextCharArg != '\0') con->os->nextCharArg = nextCharArg + (int)(*nextCharArg == '='); } 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)) return POPT_ERROR_BADOPERATION; } else if (poptArgType(opt) == POPT_ARG_VAL) { if (opt->arg) { unsigned int argInfo = poptArgInfo(con, opt); if (poptSaveInt((int *)opt->arg, argInfo, (long)opt->val)) return POPT_ERROR_BADOPERATION; } } else if (poptArgType(opt) != POPT_ARG_NONE) { int rc; con->os->nextArg = _free(con->os->nextArg); if (longArg) { longArg = expandNextArg(con, longArg); con->os->nextArg = (char *) longArg; } else if (con->os->nextCharArg) { longArg = expandNextArg(con, con->os->nextCharArg); con->os->nextArg = (char *) longArg; con->os->nextCharArg = NULL; } else { while (con->os->next == con->os->argc && con->os > con->optionStack) { cleanOSE(con->os--); } if (con->os->next == con->os->argc) { if (!F_ISSET(opt, OPTIONAL)) return POPT_ERROR_NOARG; con->os->nextArg = NULL; } else { /* * 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) { 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; } } } } longArg = NULL; /* Save the option argument through a (*opt->arg) pointer. */ if (opt->arg != NULL && (rc = poptSaveArg(con, opt)) != 0) return rc; } if (cb) invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); else if (opt->val && (poptArgType(opt) != POPT_ARG_VAL)) done = 1; if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { con->finalArgvAlloced += 10; con->finalArgv = realloc(con->finalArgv, sizeof(*con->finalArgv) * con->finalArgvAlloced); } if (con->finalArgv != NULL) { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + sizeof("--")); if (s != NULL) { /* XXX can't happen */ 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) /*@-ifempty@*/ ; /*@=ifempty@*/ else if (poptArgType(opt) == POPT_ARG_VAL) /*@-ifempty@*/ ; /*@=ifempty@*/ else if (poptArgType(opt) != POPT_ARG_NONE) { if (con->finalArgv != NULL && con->os->nextArg != NULL) con->finalArgv[con->finalArgvCount++] = xstrdup(con->os->nextArg); } } return (opt ? opt->val : -1); /* XXX can't happen */ } char * poptGetOptArg(poptContext con) { char * ret = NULL; if (con) { ret = con->os->nextArg; con->os->nextArg = NULL; } return ret; } const char * poptGetArg(poptContext con) { const char * ret = NULL; if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) ret = con->leftovers[con->nextLeftover++]; return ret; } const char * poptPeekArg(poptContext con) { const char * ret = NULL; if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) ret = con->leftovers[con->nextLeftover]; return ret; } const char ** poptGetArgs(poptContext con) { if (con == NULL || con->leftovers == NULL || con->numLeftovers == con->nextLeftover) return NULL; /* some apps like [like RPM ;-) ] need this NULL terminated */ con->leftovers[con->numLeftovers] = NULL; /*@-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; } poptContext poptFreeContext(poptContext con) { if (con == NULL) return con; poptResetContext(con); con->os->argb = _free(con->os->argb); con->aliases = poptFreeItems(con->aliases, con->numAliases); con->numAliases = 0; con->execs = poptFreeItems(con->execs, con->numExecs); con->numExecs = 0; 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); con = _free(con); return con; } int poptAddAlias(poptContext con, struct poptAlias alias, /*@unused@*/ UNUSED(int flags)) { struct poptItem_s item_buf; poptItem item = &item_buf; memset(item, 0, sizeof(*item)); item->option.longName = alias.longName; item->option.shortName = alias.shortName; item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; item->option.arg = 0; item->option.val = 0; item->option.descrip = NULL; item->option.argDescrip = NULL; item->argc = alias.argc; item->argv = alias.argv; return poptAddItem(con, item, 0); } int poptAddItem(poptContext con, poptItem newItem, int flags) { poptItem * items, item; int * nitems; switch (flags) { case 1: items = &con->execs; nitems = &con->numExecs; break; case 0: items = &con->aliases; nitems = &con->numAliases; break; default: return 1; /*@notreached@*/ break; } *items = realloc((*items), ((*nitems) + 1) * sizeof(**items)); if ((*items) == NULL) return 1; item = (*items) + (*nitems); item->option.longName = (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL); item->option.shortName = newItem->option.shortName; item->option.argInfo = newItem->option.argInfo; item->option.arg = newItem->option.arg; item->option.val = newItem->option.val; item->option.descrip = (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL); item->option.argDescrip = (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL); item->argc = newItem->argc; item->argv = newItem->argv; (*nitems)++; return 0; } const char * poptBadOption(poptContext con, unsigned 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); } const char * poptStrerror(const int error) { switch (error) { case POPT_ERROR_NOARG: return POPT_("missing argument"); case POPT_ERROR_BADOPT: return POPT_("unknown option"); case POPT_ERROR_BADOPERATION: return POPT_("mutually exclusive logical operations requested"); case POPT_ERROR_NULLARG: return POPT_("opt->arg should not be NULL"); case POPT_ERROR_OPTSTOODEEP: return POPT_("aliases nested too deeply"); case POPT_ERROR_BADQUOTE: return POPT_("error in parameter quoting"); case POPT_ERROR_BADNUMBER: return POPT_("invalid numeric value"); case POPT_ERROR_OVERFLOW: 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: return POPT_("unknown error"); } } int poptStuffArgs(poptContext con, const char ** argv) { int argc; int rc; if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) return POPT_ERROR_OPTSTOODEEP; for (argc = 0; argv[argc]; argc++) {}; con->os++; con->os->next = 0; con->os->nextArg = NULL; con->os->nextCharArg = NULL; con->os->currAlias = NULL; rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv); con->os->argb = NULL; con->os->stuffed = 1; return rc; } const char * poptGetInvocationName(poptContext con) { return (con->os->argv ? con->os->argv[0] : ""); } int poptStrippedArgv(poptContext con, int argc, char ** argv) { int numargs = argc; int j = 1; int i; /*@-sizeoftype@*/ if (con->arg_strip) for (i = 1; i < argc; i++) { if (PBM_ISSET(i, con->arg_strip)) numargs--; } for (i = 1; i < argc; i++) { if (con->arg_strip && PBM_ISSET(i, con->arg_strip)) continue; argv[j] = (j < numargs) ? argv[i] : NULL; j++; } /*@=sizeoftype@*/ return numargs; } ldb-2.0.8/third_party/popt/popt.h0000660000000000000000000005410413444661622016700 0ustar rootroot00000000000000/** \file popt/popt.h * \ingroup popt */ /* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.rpm.org/pub/rpm/dist. */ #ifndef H_POPT #define H_POPT #include /* for FILE * */ #define POPT_OPTION_DEPTH 10 /** \ingroup popt * \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 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 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 /*@}*/ /** \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_LOGICALOPS \ (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) #define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) /*!< set arg bit(s) */ #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 */ /*@}*/ /** \ingroup popt * \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, not the subtable */ #define POPT_CBFLAG_SKIPOPTION 0x10000000U /*!< don't callback with option */ #define POPT_CBFLAG_CONTINUE 0x08000000U /*!< continue callbacks with option */ /*@}*/ /** \ingroup popt * \name Error return values */ /*@{*/ #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_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 */ /*@}*/ /** \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 */ /*@}*/ /** \ingroup popt */ struct poptOption { /*@observer@*/ /*@null@*/ const char * longName; /*!< may be NULL */ char shortName; /*!< may be NUL */ unsigned int argInfo; /*@shared@*/ /*@null@*/ void * arg; /*!< depends on argInfo */ int val; /*!< 0 means don't return, just update flag */ /*@observer@*/ /*@null@*/ const char * descrip; /*!< description for autohelp -- may be NULL */ /*@observer@*/ /*@null@*/ const char * argDescrip; /*!< argument description for autohelp */ }; /** \ingroup popt * A popt alias argument for poptAddAlias(). */ struct poptAlias { /*@owned@*/ /*@null@*/ const char * longName; /*!< may be NULL */ char shortName; /*!< may be NUL */ int argc; /*@owned@*/ const char ** argv; /*!< must be free()able */ }; /** \ingroup popt * A popt alias or exec argument for poptAddItem(). */ /*@-exporttype@*/ typedef struct poptItem_s { struct poptOption option; /*!< alias/exec name(s) and description. */ int argc; /*!< (alias) no. of args. */ /*@owned@*/ const char ** argv; /*!< (alias) args, must be free()able. */ } * poptItem; /*@=exporttype@*/ /** \ingroup popt * \name Auto-generated help/usage */ /*@{*/ /** * Empty table marker to enable displaying popt alias/exec options. */ /*@-exportvar@*/ /*@unchecked@*/ /*@observer@*/ extern struct poptOption poptAliasOptions[]; /*@=exportvar@*/ #define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ 0, "Options implemented via popt alias/exec:", NULL }, /** * Auto help table options. */ /*@-exportvar@*/ /*@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 } /*@}*/ /** \ingroup popt */ /*@-exporttype@*/ typedef /*@abstract@*/ struct poptContext_s * poptContext; /*@=exporttype@*/ /** \ingroup popt */ #ifndef __cplusplus /*@-exporttype -typeuse@*/ typedef struct poptOption * poptOption; /*@=exporttype =typeuse@*/ #endif /** \ingroup popt */ /*@-exportconst@*/ enum poptCallbackReason { POPT_CALLBACK_REASON_PRE = 0, POPT_CALLBACK_REASON_POST = 1, POPT_CALLBACK_REASON_OPTION = 2 }; /*@=exportconst@*/ #ifdef __cplusplus extern "C" { #endif /*@-type@*/ /** \ingroup popt * Table callback prototype. * @param con context * @param reason reason for callback * @param opt option that triggered callback * @param arg @todo Document. * @param data @todo Document. */ typedef void (*poptCallbackType) (poptContext con, enum poptCallbackReason reason, /*@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. * @param name context name (usually argv[0] program name) * @param argc no. of arguments * @param argv argument array * @param options address of popt option table * @param flags or'd POPT_CONTEXT_* bits * @return initialized popt context */ /*@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 @*/; /** \ingroup popt * Reinitialize popt context. * @param con context */ /*@unused@*/ void poptResetContext(/*@null@*/poptContext con) /*@modifies con @*/; /** \ingroup popt * Return value of next option found. * @param con context * @return next option val, -1 on last item, POPT_ERROR_* on error */ int poptGetNextOpt(/*@null@*/poptContext con) /*@globals fileSystem, internalState @*/ /*@modifies con, fileSystem, internalState @*/; /** \ingroup popt * Return next option argument (if any). * @param con context * @return option argument, NULL if no argument is available */ /*@observer@*/ /*@null@*/ /*@unused@*/ char * poptGetOptArg(/*@null@*/poptContext con) /*@modifies con @*/; /** \ingroup popt * Return next argument. * @param con context * @return next argument, NULL if no argument is available */ /*@observer@*/ /*@null@*/ /*@unused@*/ const char * poptGetArg(/*@null@*/poptContext con) /*@modifies con @*/; /** \ingroup popt * Peek at current argument. * @param con context * @return current argument, NULL if no argument is available */ /*@observer@*/ /*@null@*/ /*@unused@*/ const char * poptPeekArg(/*@null@*/poptContext con) /*@*/; /** \ingroup popt * Return remaining arguments. * @param con context * @return argument array, NULL terminated */ /*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con) /*@modifies con @*/; /** \ingroup popt * Return the option which caused the most recent error. * @param con context * @param flags * @return offending option */ /*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, unsigned int flags) /*@*/; /** \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 @*/; /** \ingroup popt * Add alias to context. * @todo Pass alias by reference, not value. * @deprecated Use poptAddItem instead. * @param con context * @param alias alias to add * @param flags (unused) * @return 0 on success */ /*@unused@*/ int poptAddAlias(poptContext con, struct poptAlias alias, int flags) /*@modifies con @*/; /** \ingroup popt * Add alias/exec item to context. * @param con context * @param newItem alias/exec item to add * @param flags 0 for alias, 1 for exec * @return 0 on success */ 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 @*/ /*@modifies con->execs, con->numExecs, errno, fileSystem, internalState @*/; /** \ingroup popt * Read default configuration from /etc/popt and $HOME/.popt. * @param con context * @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, fileSystem, internalState @*/; /** \ingroup popt * Duplicate an argument array. * @note: The argument array is malloc'd as a single area, so only argv must * be free'd. * * @param argc no. of arguments * @param argv argument array * @retval argcPtr address of returned no. of arguments * @retval argvPtr address of returned argument array * @return 0 on success, POPT_ERROR_NOARG on failure */ int poptDupArgv(int argc, /*@null@*/ const char **argv, /*@null@*/ /*@out@*/ int * argcPtr, /*@null@*/ /*@out@*/ const char *** argvPtr) /*@modifies *argcPtr, *argvPtr @*/; /** \ingroup popt * Parse a string into an argument array. * The parse allows ', ", and \ quoting, but ' is treated the same as " and * both may include \ quotes. * @note: The argument array is malloc'd as a single area, so only argv must * be free'd. * * @param s string to parse * @retval argcPtr address of returned no. of arguments * @retval argvPtr address of returned argument array */ int poptParseArgvString(const char * s, /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) /*@modifies *argcPtr, *argvPtr @*/; /** \ingroup popt * Parses an input configuration file and returns an string that is a * command line. For use with popt. You must free the return value when done. * * Given the file: \verbatim # this line is ignored # this one too aaa bbb ccc bla=bla this_is = fdsafdas bad_line= reall bad line reall bad line = again 5555= 55555 test = with lots of spaces \endverbatim * * The result is: \verbatim --aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" \endverbatim * * Passing this to poptParseArgvString() yields an argv of: \verbatim '--aaa' '--bbb' '--ccc' '--bla=bla' '--this_is=fdsafdas' '--5555=55555' '--test=with lots of spaces' \endverbatim * * @bug NULL is returned if file line is too long. * @bug Silently ignores invalid lines. * * @param fp file handle to read * @param *argstrp return string of options (malloc'd) * @param flags unused * @return 0 on success * @see poptParseArgvString */ /*@-fcnuse@*/ int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) /*@globals fileSystem @*/ /*@modifies *fp, *argstrp, fileSystem @*/; /*@=fcnuse@*/ /** \ingroup popt * Return formatted error string for popt failure. * @param error popt error * @return error string */ /*@observer@*/ const char * poptStrerror(const int error) /*@*/; /** \ingroup popt * Limit search for executables. * @param con context * @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 flags (unused) */ void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) /*@globals fileSystem @*/ /*@modifies fp, fileSystem @*/; /** \ingroup popt * Print terse description of options. * @param con context * @param fp ouput file handle * @param flags (unused) */ void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) /*@globals fileSystem @*/ /*@modifies fp, fileSystem @*/; /** \ingroup popt * Provide text to replace default "[OPTION...]" in help/usage output. * @param con context * @param text replacement text */ /*@-fcnuse@*/ void poptSetOtherOptionHelp(poptContext con, const char * text) /*@modifies con @*/; /*@=fcnuse@*/ /** \ingroup popt * Return argv[0] from context. * @param con context * @return argv[0] */ /*@-fcnuse@*/ /*@observer@*/ const char * poptGetInvocationName(poptContext con) /*@*/; /*@=fcnuse@*/ /** \ingroup popt * Shuffle argv pointers to remove stripped args, returns new argc. * @param con context * @param argc no. of args * @param argv arg vector * @return new argc */ /*@-fcnuse@*/ int poptStrippedArgv(poptContext con, int argc, char ** argv) /*@modifies *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. * @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 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 @*/ /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; /*@=incondefs@*/ /** * Save an integer, 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 aLong value to use * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION */ /*@-incondefs@*/ /*@unused@*/ int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong) /*@globals internalState @*/ /*@modifies *arg, internalState @*/ /*@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 #endif ldb-2.0.8/third_party/popt/poptconfig.c0000660000000000000000000003233413444661622020062 0ustar rootroot00000000000000/** \ingroup popt * \file popt/poptconfig.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 "poptint.h" #include #if defined(HAVE_FNMATCH_H) #include #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 #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 @*/ { char *b = NULL; size_t nb = 0; char * se = line; const char * appName; const char * entryType; const char * opt; struct poptItem_s item_buf; poptItem item = &item_buf; int i, j; int rc = POPT_ERROR_BADCONFIG; if (con->appName == NULL) goto exit; memset(item, 0, sizeof(*item)); appName = se; while (*se != '\0' && !_isspaceptr(se)) se++; if (*se == '\0') goto exit; else *se++ = '\0'; if (configAppMatch(con, appName)) goto exit; while (*se != '\0' && _isspaceptr(se)) se++; entryType = se; while (*se != '\0' && !_isspaceptr(se)) se++; if (*se != '\0') *se++ = '\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 (*se != '\0' && _isspaceptr(se)) se++; if (opt[0] == '-' && *se == '\0') goto exit; /*@-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; /* 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; /* 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@*/ item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; for (i = 0, j = 0; i < item->argc; i++, j++) { const char * f; if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { f = item->argv[i] + sizeof("--POPTdesc="); if (f[0] == '$' && f[1] == '"') f++; item->option.descrip = f; item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; j--; } else if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { f = item->argv[i] + sizeof("--POPTargs="); if (f[0] == '$' && f[1] == '"') f++; item->option.argDescrip = f; item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; item->option.argInfo |= POPT_ARG_STRING; j--; } else if (j != i) item->argv[j] = item->argv[i]; } if (j != i) { item->argv[j] = NULL; item->argc = j; } /*@=modobserver@*/ /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ if (!strcmp(entryType, "alias")) rc = 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; } /*@=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; if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0) return (errno == ENOENT ? 0 : rc); if (b == NULL || nb == 0) return POPT_ERROR_BADCONFIG; if ((t = malloc(nb + 1)) == NULL) goto exit; te = t; be = (b + nb); for (se = b; se < be; se++) { switch (*se) { case '\n': *te = '\0'; te = t; while (*te && _isspaceptr(te)) te++; if (*te && *te != '#') xx = poptConfigLine(con, te); /*@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; } /*@switchbreak@*/ break; default: *te++ = *se; /*@switchbreak@*/ break; /*@=usedef@*/ } } 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; } int poptReadDefaultConfig(poptContext con, /*@unused@*/ 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; #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; 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; #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; } 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; } ldb-2.0.8/third_party/popt/popthelp.c0000660000000000000000000006153213444661622017547 0ustar rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /** \ingroup popt * \file popt/popthelp.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" #define POPT_USE_TIOCGWINSZ #ifdef POPT_USE_TIOCGWINSZ #include #endif #define POPT_WCHAR_HACK #ifdef POPT_WCHAR_HACK #include /* for mbsrtowcs */ /*@access mbstate_t @*/ #endif #include "poptint.h" /*@access poptContext@*/ /** * Display arguments. * @param con context * @param foo (unused) * @param key option(s) * @param arg (unused) * @param data (unused) */ /*@exits@*/ static void displayArgs(poptContext con, /*@unused@*/ UNUSED(enum poptCallbackReason foo), struct poptOption * key, /*@unused@*/ UNUSED(const char * arg), /*@unused@*/ UNUSED(void * data)) /*@globals fileSystem@*/ /*@modifies fileSystem@*/ { if (key->shortName == '?') poptPrintHelp(con, stdout, 0); else poptPrintUsage(con, stdout, 0); #if !defined(__LCLINT__) /* XXX keep both splint & valgrind happy */ con = poptFreeContext(con); #endif exit(0); } #ifdef NOTYET /*@unchecked@*/ static int show_option_defaults = 0; #endif /** * Empty table marker to enable displaying popt alias/exec options. */ /*@observer@*/ /*@unchecked@*/ struct poptOption poptAliasOptions[] = { POPT_TABLEEND }; /** * Auto help table options. */ /*@-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 }, #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) */ /*@observer@*/ /*@null@*/ static const char * getTableTranslationDomain(/*@null@*/ const struct poptOption *opt) /*@*/ { if (opt != NULL) for (; opt->longName || opt->shortName || opt->arg; opt++) { if (opt->argInfo == POPT_ARG_INTL_DOMAIN) return opt->arg; } return NULL; } /** * @param opt option(s) * @param translation_domain translation domain */ /*@observer@*/ /*@null@*/ static const char * getArgDescrip(const struct poptOption * opt, /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ /*@null@*/ const char * translation_domain) /*@=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); } switch (poptArgType(opt)) { case POPT_ARG_NONE: return POPT_("NONE"); #ifdef DYING case POPT_ARG_VAL: return POPT_("VAL"); #else 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 opt option(s) * @param translation_domain translation domain * @return */ static /*@only@*/ /*@null@*/ char * singleOptionDefaultValue(size_t lineLength, const struct poptOption * opt, /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ /*@null@*/ const char * translation_domain) /*@=paramuse@*/ /*@*/ { const char * defstr = D_(translation_domain, "default"); char * le = malloc(4*lineLength + 1); char * l = le; if (le == NULL) return NULL; /* XXX can't happen */ *le = '\0'; *le++ = '('; le = stpcpy(le, defstr); *le++ = ':'; *le++ = ' '; if (opt->arg) { /* XXX programmer error */ poptArg arg = { .ptr = opt->arg }; switch (poptArgType(opt)) { 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; case POPT_ARG_LONG: le += sprintf(le, "%ld", arg.longp[0]); break; case POPT_ARG_LONGLONG: le += sprintf(le, "%lld", arg.longlongp[0]); break; case POPT_ARG_FLOAT: { double aDouble = (double) arg.floatp[0]; 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; 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; *le++ = '"'; strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le)); if (slen == limit && s[limit]) le[-1] = le[-2] = le[-3] = '.'; *le++ = '"'; } } break; case POPT_ARG_NONE: default: l = _free(l); return NULL; /*@notreached@*/ break; } } *le++ = ')'; *le = '\0'; return l; } /** * Display help text for an option. * @param fp output file handle * @param columns output display width control * @param opt option(s) * @param translation_domain translation domain */ static void singleOptionHelp(FILE * fp, columns_t columns, const struct poptOption * opt, /*@null@*/ const char * translation_domain) /*@globals fileSystem @*/ /*@modifies fp, fileSystem @*/ { size_t maxLeftCol = columns->cur; size_t indentLength = maxLeftCol + 5; size_t lineLength = columns->max - 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; char * defs = NULL; char * left; size_t nb = maxLeftCol + 1; int displaypad = 0; int xx; /* 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); 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 (argDescrip) { char * le = left + strlen(left); if (F_ISSET(opt, 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) + strlen(defs) + sizeof(" ")); if (t) { char * te = t; if (help) te = stpcpy(te, help); *te++ = ' '; strcpy(te, defs); defs = _free(defs); defs = t; } } } if (opt->argDescrip == NULL) { switch (poptArgType(opt)) { 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); /* Don't bother displaying typical values */ if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L)) break; *le++ = '['; switch (ops) { case POPT_ARGFLAG_OR: *le++ = '|'; /*@innerbreak@*/ break; case POPT_ARGFLAG_AND: *le++ = '&'; /*@innerbreak@*/ break; case POPT_ARGFLAG_XOR: *le++ = '^'; /*@innerbreak@*/ break; default: /*@innerbreak@*/ break; } *le++ = (opt->longName != NULL ? '=' : ' '); if (negate) *le++ = '~'; /*@-formatconst@*/ le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong); /*@=formatconst@*/ *le++ = ']'; } #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); 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)); } if (F_ISSET(opt, OPTIONAL)) *le++ = ']'; *le = '\0'; } if (help) xx = POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left); else { xx = POPT_fprintf(fp," %s\n", left); goto out; } left = _free(left); if (defs) help = defs; helpLength = strlen(help); while (helpLength > lineLength) { const char * ch; char format[16]; ch = help + lineLength - 1; while (ch > help && !_isspaceptr(ch)) ch = POPT_prev_char(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); } } help = ch; while (_isspaceptr(help) && *help) help = POPT_next_char(help); helpLength = strlen(help); } if (helpLength) fprintf(fp, "%s\n", help); help = NULL; out: /*@-dependenttrans@*/ defs = _free(defs); /*@=dependenttrans@*/ left = _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, /*@null@*/ const char * translation_domain) /*@*/ { size_t max = 0; size_t len = 0; const char * argDescrip; if (opt != NULL) while (opt->longName || opt->shortName || opt->arg) { if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) { if (opt->arg) /* XXX program error */ len = maxArgWidth(opt->arg, translation_domain); if (len > max) max = len; } else if (!F_ISSET(opt, DOC_HIDDEN)) { len = sizeof(" ")-1; /* XXX --long always padded for alignment with/without "-X, ". */ len += sizeof("-X, ")-1; if (opt->longName) { len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : 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; if (len > max) max = len; } opt++; } return max; } /** * Display popt alias and exec help. * @param fp output file handle * @param items alias/exec array * @param nitems no. of alias/exec entries * @param columns output display width control * @param translation_domain translation domain */ static void itemHelp(FILE * fp, /*@null@*/ poptItem items, int nitems, columns_t columns, /*@null@*/ const char * translation_domain) /*@globals fileSystem @*/ /*@modifies fp, fileSystem @*/ { poptItem item; int i; if (items != NULL) 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); } } /** * Display help text for a table of options. * @param con context * @param fp output file handle * @param table option(s) * @param columns output display width control * @param translation_domain translation domain */ static void singleTableHelp(poptContext con, FILE * fp, /*@null@*/ const struct poptOption * table, columns_t columns, /*@null@*/ const char * translation_domain) /*@globals fileSystem @*/ /*@modifies fp, columns->cur, 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); 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); } if (table != NULL) for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { if (poptArgType(opt) != POPT_ARG_INCLUDE_TABLE) continue; sub_transdom = getTableTranslationDomain(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)); singleTableHelp(con, fp, opt->arg, columns, sub_transdom); } } /** * @param con context * @param fp output file handle */ static size_t showHelpIntro(poptContext con, FILE * fp) /*@globals fileSystem @*/ /*@modifies fp, fileSystem @*/ { size_t len = (size_t)6; int xx; xx = POPT_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); 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; } return len; } void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags)) { columns_t columns = calloc((size_t)1, sizeof(*columns)); int xx; (void) showHelpIntro(con, fp); if (con->otherHelp) xx = POPT_fprintf(fp, " %s\n", con->otherHelp); else xx = POPT_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); } } /** * Display usage text for an option. * @param fp output file handle * @param columns output display width control * @param opt option(s) * @param translation_domain translation domain */ static size_t singleOptionUsage(FILE * fp, columns_t columns, const struct poptOption * opt, /*@null@*/ const char *translation_domain) /*@globals fileSystem @*/ /*@modifies fp, columns->cur, fileSystem @*/ { size_t len = sizeof(" []")-1; 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; len += strlen(opt->longName); } 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 ((columns->cur + len) > columns->max) { fprintf(fp, "\n "); columns->cur = (size_t)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); } fprintf(fp, "]"); return columns->cur + len + 1; } /** * Display popt alias and exec usage. * @param fp output file handle * @param columns output display width control * @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, /*@null@*/ const char * translation_domain) /*@globals fileSystem @*/ /*@modifies fp, columns->cur, fileSystem @*/ { int i; if (item != NULL) for (i = 0; i < nitems; i++, item++) { const struct poptOption * opt; opt = &item->option; if (poptArgType(opt) == 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); } } return columns->cur; } /** * Keep track of option tables already processed. */ typedef struct poptDone_s { int nopts; int maxopts; /*@null@*/ const void ** opts; } * poptDone; /** * Display usage text for a table of options. * @param con context * @param fp output file handle * @param columns output display width control * @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, /*@null@*/ const struct poptOption * opt, /*@null@*/ const char * translation_domain, /*@null@*/ poptDone done) /*@globals fileSystem @*/ /*@modifies fp, columns->cur, done, fileSystem @*/ { if (opt != NULL) for (; (opt->longName || opt->shortName || opt->arg) ; opt++) { if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) { translation_domain = (const char *)opt->arg; } else if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) { if (done) { int i = 0; if (done->opts != NULL) for (i = 0; i < done->nopts; i++) { const void * that = done->opts[i]; if (that == NULL || that != opt->arg) /*@innercontinue@*/ continue; /*@innerbreak@*/ break; } /* Skip if this table has already been processed. */ if (opt->arg == NULL || i < done->nopts) continue; if (done->opts != NULL && done->nopts < done->maxopts) done->opts[done->nopts++] = (const void *) opt->arg; } columns->cur = singleTableUsage(con, fp, columns, opt->arg, translation_domain, done); } else if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) { columns->cur = singleOptionUsage(fp, columns, opt, translation_domain); } } return columns->cur; } /** * Return concatenated short options for display. * @todo Sub-tables should be recursed. * @param opt option(s) * @param fp output file handle * @retval str concatenation of short options * @return length of display string */ static size_t showShortOptions(const struct poptOption * opt, FILE * fp, /*@null@*/ char * str) /*@globals 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; 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->arg) /* XXX program error */ len = showShortOptions(opt->arg, fp, s); } /* On return to top level, print the short options, return print length. */ 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)) { columns_t columns = calloc((size_t)1, sizeof(*columns)); struct poptDone_s done_buf; poptDone done = &done_buf; 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); if (con->otherHelp) { columns->cur += strlen(con->otherHelp) + 1; if (columns->cur > columns->max) 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 = xstrdup(text); } ldb-2.0.8/third_party/popt/poptint.c0000660000000000000000000001103313444661622017400 0ustar rootroot00000000000000#include "system.h" #include #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) */ ldb-2.0.8/third_party/popt/poptint.h0000660000000000000000000001275413444661622017420 0ustar rootroot00000000000000/** \ingroup popt * \file popt/poptint.h */ /* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.rpm.org/pub/rpm/dist. */ #ifndef H_POPTINT #define H_POPTINT #include /** * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL. * @param p memory to free * @retval NULL always */ /*@unused@*/ static inline /*@null@*/ void * _free(/*@only@*/ /*@null@*/ const void * p) /*@modifies p @*/ { if (p != NULL) free((void *)p); return NULL; } /* Bit mask macros. */ /*@-exporttype -redef @*/ typedef unsigned int __pbm_bits; /*@=exporttype =redef @*/ #define __PBM_NBITS (8 * sizeof (__pbm_bits)) #define __PBM_IX(d) ((d) / __PBM_NBITS) #define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS)) /*@-exporttype -redef @*/ typedef struct { __pbm_bits bits[1]; } pbm_set; /*@=exporttype =redef @*/ #define __PBM_BITS(set) ((set)->bits) #define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits)) #define PBM_FREE(s) _free(s); #define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d)) #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; /*@only@*/ /*@null@*/ pbm_set * argb; int next; /*@only@*/ /*@null@*/ char * nextArg; /*@observer@*/ /*@null@*/ const char * nextCharArg; /*@dependent@*/ /*@null@*/ poptItem currAlias; int stuffed; }; struct poptContext_s { struct optionStackEntry optionStack[POPT_OPTION_DEPTH]; /*@dependent@*/ struct optionStackEntry * os; /*@owned@*/ /*@null@*/ poptArgv leftovers; int numLeftovers; int nextLeftover; /*@keep@*/ const struct poptOption * options; int restLeftover; /*@only@*/ /*@null@*/ const char * appName; /*@only@*/ /*@null@*/ poptItem aliases; int numAliases; unsigned int flags; /*@owned@*/ /*@null@*/ poptItem execs; int numExecs; /*@only@*/ /*@null@*/ poptArgv finalArgv; int finalArgvCount; int finalArgvAlloced; /*@null@*/ int (*maincall) (int argc, const char **argv); /*@dependent@*/ /*@null@*/ poptItem doExec; /*@only@*/ /*@null@*/ const char * execPath; int execAbsolute; /*@only@*/ /*@relnull@*/ const char * otherHelp; /*@null@*/ pbm_set * arg_strip; }; #if defined(POPT_fprintf) #define POPT_dgettext dgettext #else #ifdef HAVE_ICONV #include #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 #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) #include #endif #if defined(ENABLE_NLS) && 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) #define POPT_(foo) D_("popt", foo) #else #define D_(dom, str) str #define POPT_(foo) foo #endif #define N_(foo) foo ldb-2.0.8/third_party/popt/poptparse.c0000660000000000000000000001227113444661622017725 0ustar rootroot00000000000000/** \ingroup popt * \file popt/poptparse.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" #define POPT_ARGV_ARRAY_GROW_DELTA 5 int poptDupArgv(int argc, const char **argv, int * argcPtr, const char *** argvPtr) { size_t nb = (argc + 1) * sizeof(*argv); const char ** argv2; char * dst; int i; if (argc <= 0 || argv == NULL) /* XXX can't happen */ return POPT_ERROR_NOARG; for (i = 0; i < argc; i++) { if (argv[i] == NULL) return POPT_ERROR_NOARG; nb += strlen(argv[i]) + 1; } dst = malloc(nb); if (dst == NULL) /* XXX can't happen */ return POPT_ERROR_MALLOC; argv2 = (void *) dst; dst += (argc + 1) * sizeof(*argv); *dst = '\0'; for (i = 0; i < argc; i++) { argv2[i] = dst; dst = stpcpy(dst, argv[i]); dst++; /* trailing NUL */ } argv2[argc] = NULL; if (argvPtr) { *argvPtr = argv2; } else { free(argv2); argv2 = NULL; } if (argcPtr) *argcPtr = argc; return 0; } 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); int argc = 0; size_t buflen = strlen(s) + 1; char * buf, * bufOrig = NULL; 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++) { if (quote == *src) { quote = '\0'; } else if (quote != '\0') { if (*src == '\\') { src++; if (!*src) { rc = POPT_ERROR_BADQUOTE; goto exit; } if (*src != quote) *buf++ = '\\'; } *buf++ = *src; } else if (_isspaceptr(src)) { if (*argv[argc] != '\0') { buf++, argc++; if (argc == argvAlloced) { argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; argv = realloc(argv, sizeof(*argv) * argvAlloced); if (argv == NULL) goto exit; } argv[argc] = buf; } } else switch (*src) { case '"': case '\'': quote = *src; /*@switchbreak@*/ break; case '\\': src++; if (!*src) { rc = POPT_ERROR_BADQUOTE; goto exit; } /*@fallthrough@*/ default: *buf++ = *src; /*@switchbreak@*/ break; } } if (strlen(argv[argc])) { argc++, buf++; } rc = poptDupArgv(argc, argv, argcPtr, argvPtr); exit: if (bufOrig) free(bufOrig); if (argv) free(argv); return rc; } /* 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)) { char line[999]; char * argstr; char * p; char * q; char * x; size_t t; size_t argvlen = 0; size_t maxlinelen = sizeof(line); size_t linelen; size_t maxargvlen = (size_t)480; *argstrp = NULL; /* | this_is = our_line * p q x */ if (fp == NULL) return POPT_ERROR_NULLARG; argstr = calloc(maxargvlen, sizeof(*argstr)); if (argstr == NULL) return POPT_ERROR_MALLOC; while (fgets(line, (int)maxlinelen, fp) != NULL) { p = line; /* loop until first non-space char or EOL */ while( *p != '\0' && _isspaceptr(p) ) p++; linelen = strlen(p); if (linelen >= maxlinelen-1) { free(argstr); 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 != '=') q++; if (_isspaceptr(q)) { /* a space after the name, find next non space */ *q++='\0'; while( *q != '\0' && _isspaceptr(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); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; argstr = realloc(argstr, maxargvlen); if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); strcat(argstr, p); continue; } if (*q != '=') continue; /* XXX for now, silently ignore bogus line */ /* *q is an equal sign. */ *q++ = '\0'; /* find next non-space letter of value */ while (*q != '\0' && _isspaceptr(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) */ /* rest of line accept */ t = (size_t)(x - p); argvlen += t + (sizeof("' --='")-1); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; argstr = realloc(argstr, maxargvlen); if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); strcat(argstr, p); strcat(argstr, "=\""); strcat(argstr, q); strcat(argstr, "\""); } *argstrp = argstr; return 0; } ldb-2.0.8/third_party/popt/system.h0000660000000000000000000000527113444661622017243 0ustar rootroot00000000000000/** * \file popt/system.h */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined (__GLIBC__) && defined(__LCLINT__) /*@-declundef@*/ /*@unchecked@*/ extern __const __int32_t *__ctype_tolower; /*@unchecked@*/ extern __const __int32_t *__ctype_toupper; /*@=declundef@*/ #endif #include /* XXX isspace(3) has i18n encoding signednesss issues on Solaris. */ #define _isspaceptr(_chp) isspace((int)(*(unsigned char *)(_chp))) #include #include #include #ifdef HAVE_MCHECK_H #include #endif #include #include #include #if defined(HAVE_UNISTD_H) && !defined(__LCLINT__) #include #endif #ifdef __NeXT /* access macros are not declared in non posix mode in unistd.h - don't try to use posix on NeXTstep 3.3 ! */ #include #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) @*/ /*@*/; /*@mayexit@*/ /*@only@*/ /*@unused@*/ void * xrealloc (/*@null@*/ /*@only@*/ void * ptr, size_t size) /*@ensures maxSet(result) == (size - 1) @*/ /*@modifies *ptr @*/; /*@mayexit@*/ /*@only@*/ /*@unused@*/ 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; 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__) #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__) */ #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" ldb-2.0.8/third_party/popt/wscript0000660000000000000000000000126313573675414017170 0ustar rootroot00000000000000#!/usr/bin/env python from waflib import Options def configure(conf): if conf.CHECK_POPT(): conf.define('USING_SYSTEM_POPT', 1) return conf.CHECK_HEADERS('float.h') conf.CHECK_FUNCS('stpcpy') conf.CHECK_LIB('iconv', shlib=True) 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, deps='iconv', allow_warnings=True, private_library=True) ldb-2.0.8/third_party/cmocka/cmocka.c0000660000000000000000000033537313573675414017442 0ustar rootroot00000000000000/* * Copyright 2008 Google Inc. * Copyright 2014-2018 Andreas Schneider * Copyright 2015 Jakub Hrozek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #ifdef HAVE_SIGNAL_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #include #include #include #include #include #include /* * This allows to add a platform specific header file. Some embedded platforms * sometimes miss certain types and definitions. * * Example: * * typedef unsigned long int uintptr_t * #define _UINTPTR_T 1 * #define _UINTPTR_T_DEFINED 1 */ #ifdef CMOCKA_PLATFORM_INCLUDE # include "cmocka_platform.h" #endif /* CMOCKA_PLATFORM_INCLUDE */ #include #include /* Size of guard bytes around dynamically allocated blocks. */ #define MALLOC_GUARD_SIZE 16 /* Pattern used to initialize guard blocks. */ #define MALLOC_GUARD_PATTERN 0xEF /* Pattern used to initialize memory allocated with test_malloc(). */ #define MALLOC_ALLOC_PATTERN 0xBA #define MALLOC_FREE_PATTERN 0xCD /* Alignment of allocated blocks. NOTE: This must be base2. */ #define MALLOC_ALIGNMENT sizeof(size_t) /* Printf formatting for source code locations. */ #define SOURCE_LOCATION_FORMAT "%s:%u" #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE) # define CMOCKA_THREAD __thread #elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE) # define CMOCKA_THREAD __declspec(thread) #else # define CMOCKA_THREAD #endif #ifdef HAVE_CLOCK_REALTIME #define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts)) #else #define CMOCKA_CLOCK_GETTIME(clock_id, ts) #endif #ifndef MAX #define MAX(a,b) ((a) < (b) ? (b) : (a)) #endif /** * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp. */ #ifdef HAVE_SIGLONGJMP # define cm_jmp_buf sigjmp_buf # define cm_setjmp(env) sigsetjmp(env, 1) # define cm_longjmp(env, val) siglongjmp(env, val) #else # define cm_jmp_buf jmp_buf # define cm_setjmp(env) setjmp(env) # define cm_longjmp(env, val) longjmp(env, val) #endif /* * Declare and initialize the pointer member of ValuePointer variable name * with ptr. */ #define declare_initialize_value_pointer_pointer(name, ptr) \ ValuePointer name ; \ name.value = 0; \ name.x.pointer = (void*)(ptr) /* * Declare and initialize the value member of ValuePointer variable name * with val. */ #define declare_initialize_value_pointer_value(name, val) \ ValuePointer name ; \ name.value = val /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */ #define cast_largest_integral_type_to_pointer( \ pointer_type, largest_integral_type) \ ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer) /* Used to cast LargetIntegralType to void* and vice versa. */ typedef union ValuePointer { LargestIntegralType value; struct { #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4) unsigned int padding; #endif void *pointer; } x; } ValuePointer; /* Doubly linked list node. */ typedef struct ListNode { const void *value; int refcount; struct ListNode *next; struct ListNode *prev; } ListNode; /* Debug information for malloc(). */ struct MallocBlockInfoData { void* block; /* Address of the block returned by malloc(). */ size_t allocated_size; /* Total size of the allocated block. */ size_t size; /* Request block size. */ SourceLocation location; /* Where the block was allocated. */ ListNode node; /* Node within list of all allocated blocks. */ }; typedef union { struct MallocBlockInfoData *data; char *ptr; } MallocBlockInfo; /* State of each test. */ typedef struct TestState { const ListNode *check_point; /* Check point of the test if there's a */ /* setup function. */ void *state; /* State associated with the test. */ } TestState; /* Determines whether two values are the same. */ typedef int (*EqualityFunction)(const void *left, const void *right); /* Value of a symbol and the place it was declared. */ typedef struct SymbolValue { SourceLocation location; LargestIntegralType value; } SymbolValue; /* * Contains a list of values for a symbol. * NOTE: Each structure referenced by symbol_values_list_head must have a * SourceLocation as its' first member. */ typedef struct SymbolMapValue { const char *symbol_name; ListNode symbol_values_list_head; } SymbolMapValue; /* Where a particular ordering was located and its symbol name */ typedef struct FuncOrderingValue { SourceLocation location; const char * function; } FuncOrderingValue; /* Used by list_free() to deallocate values referenced by list nodes. */ typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data); /* Structure used to check the range of integer types.a */ typedef struct CheckIntegerRange { CheckParameterEvent event; LargestIntegralType minimum; LargestIntegralType maximum; } CheckIntegerRange; /* Structure used to check whether an integer value is in a set. */ typedef struct CheckIntegerSet { CheckParameterEvent event; const LargestIntegralType *set; size_t size_of_set; } CheckIntegerSet; /* Used to check whether a parameter matches the area of memory referenced by * this structure. */ typedef struct CheckMemoryData { CheckParameterEvent event; const void *memory; size_t size; } CheckMemoryData; static ListNode* list_initialize(ListNode * const node); static ListNode* list_add(ListNode * const head, ListNode *new_node); static ListNode* list_add_value(ListNode * const head, const void *value, const int count); static ListNode* list_remove( ListNode * const node, const CleanupListValue cleanup_value, void * const cleanup_value_data); static void list_remove_free( ListNode * const node, const CleanupListValue cleanup_value, void * const cleanup_value_data); static int list_empty(const ListNode * const head); static int list_find( ListNode * const head, const void *value, const EqualityFunction equal_func, ListNode **output); static int list_first(ListNode * const head, ListNode **output); static ListNode* list_free( ListNode * const head, const CleanupListValue cleanup_value, void * const cleanup_value_data); static void add_symbol_value( ListNode * const symbol_map_head, const char * const symbol_names[], const size_t number_of_symbol_names, const void* value, const int count); static int get_symbol_value( ListNode * const symbol_map_head, const char * const symbol_names[], const size_t number_of_symbol_names, void **output); static void free_value(const void *value, void *cleanup_value_data); static void free_symbol_map_value( const void *value, void *cleanup_value_data); 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 size_t check_for_leftover_values( const ListNode * const map_head, const char * const error_message, const size_t number_of_symbol_names); static void remove_always_return_values_from_list(ListNode * const map_head); /* * This must be called at the beginning of a test to initialize some data * structures. */ static void initialize_testing(const char *test_name); /* This must be called at the end of a test to free() allocated structures. */ static void teardown_testing(const char *test_name); static enum cm_message_output cm_get_output(void); static int cm_error_message_enabled = 1; static CMOCKA_THREAD char *cm_error_message; void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); /* * Keeps track of the calling context returned by setenv() so that the fail() * method can jump out of a test. */ static CMOCKA_THREAD cm_jmp_buf global_run_test_env; static CMOCKA_THREAD int global_running_test = 0; /* Keeps track of the calling context returned by setenv() so that */ /* mock_assert() can optionally jump back to expect_assert_failure(). */ jmp_buf global_expect_assert_env; int global_expecting_assert = 0; const char *global_last_failed_assert = NULL; static int global_skip_test; /* Keeps a map of the values that functions will have to return to provide */ /* mocked interfaces. */ static CMOCKA_THREAD ListNode global_function_result_map_head; /* Location of the last mock value returned was declared. */ static CMOCKA_THREAD SourceLocation global_last_mock_value_location; /* Keeps a map of the values that functions expect as parameters to their * mocked interfaces. */ static CMOCKA_THREAD ListNode global_function_parameter_map_head; /* Location of last parameter value checked was declared. */ static CMOCKA_THREAD SourceLocation global_last_parameter_location; /* List (acting as FIFO) of call ordering. */ static CMOCKA_THREAD ListNode global_call_ordering_head; /* Location of last call ordering that was declared. */ static CMOCKA_THREAD SourceLocation global_last_call_ordering_location; /* List of all currently allocated blocks. */ static CMOCKA_THREAD ListNode global_allocated_blocks; static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT; static const char *global_test_filter_pattern; #ifndef _WIN32 /* Signals caught by exception_handler(). */ static const int exception_signals[] = { SIGFPE, SIGILL, SIGSEGV, #ifdef SIGBUS SIGBUS, #endif #ifdef SIGSYS SIGSYS, #endif }; /* Default signal functions that should be restored after a test is complete. */ typedef void (*SignalFunction)(int signal); static SignalFunction default_signal_functions[ ARRAY_SIZE(exception_signals)]; #else /* _WIN32 */ /* The default exception filter. */ static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; /* Fatal exceptions. */ typedef struct ExceptionCodeInfo { DWORD code; const char* description; } ExceptionCodeInfo; #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} static const ExceptionCodeInfo exception_codes[] = { EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), }; #endif /* !_WIN32 */ enum CMUnitTestStatus { CM_TEST_NOT_STARTED, CM_TEST_PASSED, CM_TEST_FAILED, CM_TEST_ERROR, CM_TEST_SKIPPED, }; struct CMUnitTestState { const ListNode *check_point; /* Check point of the test if there's a setup function. */ const struct CMUnitTest *test; /* Point to array element in the tests we get passed */ void *state; /* State associated with the test */ const char *error_message; /* The error messages by the test */ enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ double runtime; /* Time calculations */ }; /* Exit the currently executing test. */ static void exit_test(const int quit_application) { const char *env = getenv("CMOCKA_TEST_ABORT"); int abort_test = 0; if (env != NULL && strlen(env) == 1) { abort_test = (env[0] == '1'); } if (global_skip_test == 0 && abort_test == 1) { print_error("%s", cm_error_message); abort(); } else if (global_running_test) { cm_longjmp(global_run_test_env, 1); } else if (quit_application) { exit(-1); } } void _skip(const char * const file, const int line) { cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line); global_skip_test = 1; exit_test(1); } /* Initialize a SourceLocation structure. */ static void initialize_source_location(SourceLocation * const location) { assert_non_null(location); location->file = NULL; location->line = 0; } /* Determine whether a source location is currently set. */ static int source_location_is_set(const SourceLocation * const location) { assert_non_null(location); return location->file && location->line; } /* Set a source location. */ static void set_source_location( SourceLocation * const location, const char * const file, const int line) { assert_non_null(location); location->file = file; location->line = line; } static int c_strreplace(char *src, size_t src_len, const char *pattern, const char *repl, int *str_replaced) { char *p = NULL; p = strstr(src, pattern); if (p == NULL) { return -1; } do { size_t of = p - src; size_t l = strlen(src); size_t pl = strlen(pattern); size_t rl = strlen(repl); /* overflow check */ if (src_len <= l + MAX(pl, rl) + 1) { return -1; } if (rl != pl) { memmove(src + of + rl, src + of + pl, l - of - pl + 1); } memcpy(src + of, repl, rl); if (str_replaced != NULL) { *str_replaced = 1; } p = strstr(src, pattern); } while (p != NULL); return 0; } static int c_strmatch(const char *str, const char *pattern) { int ok; if (str == NULL || pattern == NULL) { return 0; } for (;;) { /* Check if pattern is done */ if (*pattern == '\0') { /* If string is at the end, we're good */ if (*str == '\0') { return 1; } return 0; } if (*pattern == '*') { /* Move on */ pattern++; /* If we are at the end, everything is fine */ if (*pattern == '\0') { return 1; } /* Try to match each position */ for (; *str != '\0'; str++) { ok = c_strmatch(str, pattern); if (ok) { return 1; } } /* No match */ return 0; } /* If we are at the end, leave */ if (*str == '\0') { return 0; } /* Check if we have a single wildcard or matching char */ if (*pattern != '?' && *str != *pattern) { return 0; } /* Move string and pattern */ str++; pattern++; } return 0; } /* Create function results and expected parameter lists. */ void initialize_testing(const char *test_name) { (void)test_name; list_initialize(&global_function_result_map_head); initialize_source_location(&global_last_mock_value_location); list_initialize(&global_function_parameter_map_head); initialize_source_location(&global_last_parameter_location); list_initialize(&global_call_ordering_head); initialize_source_location(&global_last_parameter_location); } static void fail_if_leftover_values(const char *test_name) { int error_occurred = 0; (void)test_name; remove_always_return_values(&global_function_result_map_head, 1); if (check_for_leftover_values( &global_function_result_map_head, "%s() has remaining non-returned values.\n", 1)) { error_occurred = 1; } remove_always_return_values(&global_function_parameter_map_head, 2); if (check_for_leftover_values( &global_function_parameter_map_head, "'%s' parameter still has values that haven't been checked.\n", 2)) { error_occurred = 1; } remove_always_return_values_from_list(&global_call_ordering_head); if (check_for_leftover_values_list(&global_call_ordering_head, "%s function was expected to be called but was not not.\n")) { error_occurred = 1; } if (error_occurred) { exit_test(1); } } static void teardown_testing(const char *test_name) { (void)test_name; list_free(&global_function_result_map_head, free_symbol_map_value, (void*)0); initialize_source_location(&global_last_mock_value_location); list_free(&global_function_parameter_map_head, free_symbol_map_value, (void*)1); initialize_source_location(&global_last_parameter_location); list_free(&global_call_ordering_head, free_value, (void*)0); initialize_source_location(&global_last_call_ordering_location); } /* Initialize a list node. */ static ListNode* list_initialize(ListNode * const node) { node->value = NULL; node->next = node; node->prev = node; node->refcount = 1; return node; } /* * Adds a value at the tail of a given list. * The node referencing the value is allocated from the heap. */ static ListNode* list_add_value(ListNode * const head, const void *value, const int refcount) { ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode)); assert_non_null(head); assert_non_null(value); new_node->value = value; new_node->refcount = refcount; return list_add(head, new_node); } /* Add new_node to the end of the list. */ static ListNode* list_add(ListNode * const head, ListNode *new_node) { assert_non_null(head); assert_non_null(new_node); new_node->next = head; new_node->prev = head->prev; head->prev->next = new_node; head->prev = new_node; return new_node; } /* Remove a node from a list. */ static ListNode* list_remove( ListNode * const node, const CleanupListValue cleanup_value, void * const cleanup_value_data) { assert_non_null(node); node->prev->next = node->next; node->next->prev = node->prev; if (cleanup_value) { cleanup_value(node->value, cleanup_value_data); } return node; } /* Remove a list node from a list and free the node. */ static void list_remove_free( ListNode * const node, const CleanupListValue cleanup_value, void * const cleanup_value_data) { assert_non_null(node); free(list_remove(node, cleanup_value, cleanup_value_data)); } /* * Frees memory kept by a linked list The cleanup_value function is called for * every "value" field of nodes in the list, except for the head. In addition * to each list value, cleanup_value_data is passed to each call to * cleanup_value. The head of the list is not deallocated. */ static ListNode* list_free( ListNode * const head, const CleanupListValue cleanup_value, void * const cleanup_value_data) { assert_non_null(head); while (!list_empty(head)) { list_remove_free(head->next, cleanup_value, cleanup_value_data); } return head; } /* Determine whether a list is empty. */ static int list_empty(const ListNode * const head) { assert_non_null(head); return head->next == head; } /* * Find a value in the list using the equal_func to compare each node with the * value. */ static int list_find(ListNode * const head, const void *value, const EqualityFunction equal_func, ListNode **output) { ListNode *current; assert_non_null(head); for (current = head->next; current != head; current = current->next) { if (equal_func(current->value, value)) { *output = current; return 1; } } return 0; } /* Returns the first node of a list */ static int list_first(ListNode * const head, ListNode **output) { ListNode *target_node = NULL; assert_non_null(head); if (list_empty(head)) { return 0; } target_node = head->next; *output = target_node; return 1; } /* Deallocate a value referenced by a list. */ static void free_value(const void *value, void *cleanup_value_data) { (void)cleanup_value_data; assert_non_null(value); free((void*)value); } /* Releases memory associated to a symbol_map_value. */ static void free_symbol_map_value(const void *value, void *cleanup_value_data) { SymbolMapValue * const map_value = (SymbolMapValue*)value; const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data); assert_non_null(value); list_free(&map_value->symbol_values_list_head, children ? free_symbol_map_value : free_value, (void *) ((uintptr_t)children - 1)); free(map_value); } /* * Determine whether a symbol name referenced by a symbol_map_value matches the * specified function name. */ static int symbol_names_match(const void *map_value, const void *symbol) { return !strcmp(((SymbolMapValue*)map_value)->symbol_name, (const char*)symbol); } /* * Adds a value to the queue of values associated with the given hierarchy of * symbols. It's assumed value is allocated from the heap. */ static void add_symbol_value(ListNode * const symbol_map_head, const char * const symbol_names[], const size_t number_of_symbol_names, const void* value, const int refcount) { const char* symbol_name; ListNode *target_node; SymbolMapValue *target_map_value; assert_non_null(symbol_map_head); assert_non_null(symbol_names); assert_true(number_of_symbol_names); symbol_name = symbol_names[0]; if (!list_find(symbol_map_head, symbol_name, symbol_names_match, &target_node)) { SymbolMapValue * const new_symbol_map_value = (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value)); new_symbol_map_value->symbol_name = symbol_name; list_initialize(&new_symbol_map_value->symbol_values_list_head); target_node = list_add_value(symbol_map_head, new_symbol_map_value, 1); } target_map_value = (SymbolMapValue*)target_node->value; if (number_of_symbol_names == 1) { list_add_value(&target_map_value->symbol_values_list_head, value, refcount); } else { add_symbol_value(&target_map_value->symbol_values_list_head, &symbol_names[1], number_of_symbol_names - 1, value, refcount); } } /* * Gets the next value associated with the given hierarchy of symbols. * The value is returned as an output parameter with the function returning the * node's old refcount value if a value is found, 0 otherwise. This means that * a return value of 1 indicates the node was just removed from the list. */ static int get_symbol_value( ListNode * const head, const char * const symbol_names[], const size_t number_of_symbol_names, void **output) { const char* symbol_name = NULL; ListNode *target_node = NULL; assert_non_null(head); assert_non_null(symbol_names); assert_true(number_of_symbol_names); assert_non_null(output); symbol_name = symbol_names[0]; if (list_find(head, symbol_name, symbol_names_match, &target_node)) { SymbolMapValue *map_value = NULL; ListNode *child_list = NULL; int return_value = 0; assert_non_null(target_node); assert_non_null(target_node->value); map_value = (SymbolMapValue*)target_node->value; child_list = &map_value->symbol_values_list_head; if (number_of_symbol_names == 1) { ListNode *value_node = NULL; return_value = list_first(child_list, &value_node); assert_true(return_value); /* Add a check to silence clang analyzer */ if (return_value == 0) { goto out; } *output = (void*) value_node->value; return_value = value_node->refcount; if (value_node->refcount - 1 == 0) { list_remove_free(value_node, NULL, NULL); } else if (value_node->refcount > WILL_RETURN_ONCE) { --value_node->refcount; } } else { return_value = get_symbol_value( child_list, &symbol_names[1], number_of_symbol_names - 1, output); } if (list_empty(child_list)) { list_remove_free(target_node, free_symbol_map_value, (void*)0); } return return_value; } out: cm_print_error("No entries for symbol %s.\n", symbol_name); return 0; } /** * Taverse a list of nodes and remove first symbol value in list that has a * refcount < -1 (i.e. should always be returned and has been returned at * least once). */ static void remove_always_return_values_from_list(ListNode * const map_head) { ListNode * current = NULL; ListNode * next = NULL; assert_non_null(map_head); for (current = map_head->next, next = current->next; current != map_head; current = next, next = current->next) { if (current->refcount < -1) { list_remove_free(current, free_value, NULL); } } } /* * Traverse down a tree of symbol values and remove the first symbol value * in each branch that has a refcount < -1 (i.e should always be returned * and has been returned at least once). */ static void remove_always_return_values(ListNode * const map_head, const size_t number_of_symbol_names) { ListNode *current; assert_non_null(map_head); assert_true(number_of_symbol_names); current = map_head->next; while (current != map_head) { SymbolMapValue * const value = (SymbolMapValue*)current->value; ListNode * const next = current->next; ListNode *child_list; assert_non_null(value); child_list = &value->symbol_values_list_head; if (!list_empty(child_list)) { if (number_of_symbol_names == 1) { ListNode * const child_node = child_list->next; /* If this item has been returned more than once, free it. */ if (child_node->refcount < -1) { list_remove_free(child_node, free_value, NULL); } } else { remove_always_return_values(child_list, number_of_symbol_names - 1); } } if (list_empty(child_list)) { list_remove_free(current, free_value, NULL); } current = next; } } static size_t check_for_leftover_values_list(const ListNode * head, const char * const error_message) { ListNode *child_node; size_t leftover_count = 0; if (!list_empty(head)) { for (child_node = head->next; child_node != head; child_node = child_node->next, ++leftover_count) { const FuncOrderingValue *const o = (const FuncOrderingValue*) child_node->value; cm_print_error(error_message, o->function); cm_print_error(SOURCE_LOCATION_FORMAT ": note: remaining item was declared here\n", o->location.file, o->location.line); } } return leftover_count; } /* * Checks if there are any leftover values set up by the test that were never * retrieved through execution, and fail the test if that is the case. */ static size_t check_for_leftover_values( const ListNode * const map_head, const char * const error_message, const size_t number_of_symbol_names) { const ListNode *current; size_t symbols_with_leftover_values = 0; assert_non_null(map_head); assert_true(number_of_symbol_names); for (current = map_head->next; current != map_head; current = current->next) { const SymbolMapValue * const value = (SymbolMapValue*)current->value; const ListNode *child_list; assert_non_null(value); child_list = &value->symbol_values_list_head; if (!list_empty(child_list)) { if (number_of_symbol_names == 1) { const ListNode *child_node; cm_print_error(error_message, value->symbol_name); for (child_node = child_list->next; child_node != child_list; child_node = child_node->next) { const SourceLocation * const location = (const SourceLocation*)child_node->value; cm_print_error(SOURCE_LOCATION_FORMAT ": note: remaining item was declared here\n", location->file, location->line); } } else { cm_print_error("%s: ", value->symbol_name); check_for_leftover_values(child_list, error_message, number_of_symbol_names - 1); } symbols_with_leftover_values ++; } } return symbols_with_leftover_values; } /* Get the next return value for the specified mock function. */ LargestIntegralType _mock(const char * const function, const char* const file, const int line) { void *result; const int rc = get_symbol_value(&global_function_result_map_head, &function, 1, &result); if (rc) { SymbolValue * const symbol = (SymbolValue*)result; const LargestIntegralType value = symbol->value; global_last_mock_value_location = symbol->location; if (rc == 1) { free(symbol); } return value; } else { cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " "to mock function %s\n", file, line, function); if (source_location_is_set(&global_last_mock_value_location)) { cm_print_error(SOURCE_LOCATION_FORMAT ": note: Previously returned mock value was declared here\n", global_last_mock_value_location.file, global_last_mock_value_location.line); } else { cm_print_error("There were no previously returned mock values for " "this test.\n"); } exit_test(1); } return 0; } /* Ensure that function is being called in proper order */ void _function_called(const char *const function, const char *const file, const int line) { ListNode *first_value_node = NULL; ListNode *value_node = NULL; int rc; rc = list_first(&global_call_ordering_head, &value_node); first_value_node = value_node; if (rc) { FuncOrderingValue *expected_call; int cmp; expected_call = (FuncOrderingValue *)value_node->value; cmp = strcmp(expected_call->function, function); if (value_node->refcount < -1) { /* * Search through value nodes until either function is found or * encounter a non-zero refcount greater than -2 */ if (cmp != 0) { value_node = value_node->next; expected_call = (FuncOrderingValue *)value_node->value; cmp = strcmp(expected_call->function, function); while (value_node->refcount < -1 && cmp != 0 && value_node != first_value_node->prev) { value_node = value_node->next; if (value_node == NULL) { break; } expected_call = (FuncOrderingValue *)value_node->value; if (expected_call == NULL) { continue; } cmp = strcmp(expected_call->function, function); } if (expected_call == NULL || value_node == first_value_node->prev) { cm_print_error(SOURCE_LOCATION_FORMAT ": error: No expected mock calls matching " "called() invocation in %s", file, line, function); exit_test(1); } } } if (cmp == 0) { if (value_node->refcount > -2 && --value_node->refcount == 0) { list_remove_free(value_node, free_value, NULL); } } else { cm_print_error(SOURCE_LOCATION_FORMAT ": error: Expected call to %s but received called() " "in %s\n", file, line, expected_call->function, function); exit_test(1); } } else { cm_print_error(SOURCE_LOCATION_FORMAT ": error: No mock calls expected but called() was " "invoked in %s\n", file, line, function); exit_test(1); } } /* Add a return value for the specified mock function name. */ void _will_return(const char * const function_name, const char * const file, const int line, const LargestIntegralType value, const int count) { SymbolValue * const return_value = (SymbolValue*)malloc(sizeof(*return_value)); assert_true(count != 0); return_value->value = value; set_source_location(&return_value->location, file, line); add_symbol_value(&global_function_result_map_head, &function_name, 1, return_value, count); } /* * Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event * parameter is provided it must be allocated on the heap and doesn't need to * be deallocated by the caller. */ void _expect_check( const char* const function, const char* const parameter, const char* const file, const int line, const CheckParameterValue check_function, const LargestIntegralType check_data, CheckParameterEvent * const event, const int count) { CheckParameterEvent * const check = event ? event : (CheckParameterEvent*)malloc(sizeof(*check)); const char* symbols[] = {function, parameter}; check->parameter_name = parameter; check->check_value = check_function; check->check_value_data = check_data; set_source_location(&check->location, file, line); add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, count); } /* * Add an call expectations that a particular function is called correctly. * This is used for code under test that makes calls to several functions * in depended upon components (mocks). */ void _expect_function_call( const char * const function_name, const char * const file, const int line, const int count) { FuncOrderingValue *ordering; assert_non_null(function_name); assert_non_null(file); assert_true(count != 0); ordering = (FuncOrderingValue *)malloc(sizeof(*ordering)); set_source_location(&ordering->location, file, line); ordering->function = function_name; list_add_value(&global_call_ordering_head, ordering, count); } /* Returns 1 if the specified values are equal. If the values are not equal * an error is displayed and 0 is returned. */ static int values_equal_display_error(const LargestIntegralType left, const LargestIntegralType right) { const int equal = left == right; if (!equal) { cm_print_error(LargestIntegralTypePrintfFormat " != " LargestIntegralTypePrintfFormat "\n", left, right); } return equal; } /* * Returns 1 if the specified values are not equal. If the values are equal * an error is displayed and 0 is returned. */ static int values_not_equal_display_error(const LargestIntegralType left, const LargestIntegralType right) { const int not_equal = left != right; if (!not_equal) { cm_print_error(LargestIntegralTypePrintfFormat " == " LargestIntegralTypePrintfFormat "\n", left, right); } return not_equal; } /* * Determine whether value is contained within check_integer_set. * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is * returned and an error is displayed. If invert is 1 and the value is not * in the set 1 is returned, otherwise 0 is returned and an error is * displayed. */ static int value_in_set_display_error( const LargestIntegralType value, const CheckIntegerSet * const check_integer_set, const int invert) { int succeeded = invert; assert_non_null(check_integer_set); { const LargestIntegralType * const set = check_integer_set->set; const size_t size_of_set = check_integer_set->size_of_set; size_t i; for (i = 0; i < size_of_set; i++) { if (set[i] == value) { /* If invert = 0 and item is found, succeeded = 1. */ /* If invert = 1 and item is found, succeeded = 0. */ succeeded = !succeeded; break; } } if (succeeded) { return 1; } cm_print_error(LargestIntegralTypePrintfFormatDecimal " is %sin the set (", value, invert ? "" : "not "); for (i = 0; i < size_of_set; i++) { cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]); } cm_print_error(")\n"); } return 0; } /* * Determine whether a value is within the specified range. If the value is * within the specified range 1 is returned. If the value isn't within the * specified range an error is displayed and 0 is returned. */ static int integer_in_range_display_error( const LargestIntegralType value, const LargestIntegralType range_min, const LargestIntegralType range_max) { if (value >= range_min && value <= range_max) { return 1; } cm_print_error(LargestIntegralTypePrintfFormatDecimal " is not within the range " LargestIntegralTypePrintfFormatDecimal "-" LargestIntegralTypePrintfFormatDecimal "\n", value, range_min, range_max); return 0; } /* * Determine whether a value is within the specified range. If the value * is not within the range 1 is returned. If the value is within the * specified range an error is displayed and zero is returned. */ static int integer_not_in_range_display_error( const LargestIntegralType value, const LargestIntegralType range_min, const LargestIntegralType range_max) { if (value < range_min || value > range_max) { return 1; } cm_print_error(LargestIntegralTypePrintfFormatDecimal " is within the range " LargestIntegralTypePrintfFormatDecimal "-" LargestIntegralTypePrintfFormatDecimal "\n", value, range_min, range_max); return 0; } /* * Determine whether the specified strings are equal. If the strings are equal * 1 is returned. If they're not equal an error is displayed and 0 is * returned. */ static int string_equal_display_error( const char * const left, const char * const right) { if (strcmp(left, right) == 0) { return 1; } cm_print_error("\"%s\" != \"%s\"\n", left, right); return 0; } /* * Determine whether the specified strings are equal. If the strings are not * equal 1 is returned. If they're not equal an error is displayed and 0 is * returned */ static int string_not_equal_display_error( const char * const left, const char * const right) { if (strcmp(left, right) != 0) { return 1; } cm_print_error("\"%s\" == \"%s\"\n", left, right); return 0; } /* * Determine whether the specified areas of memory are equal. If they're equal * 1 is returned otherwise an error is displayed and 0 is returned. */ static int memory_equal_display_error(const char* const a, const char* const b, const size_t size) { size_t differences = 0; size_t i; for (i = 0; i < size; i++) { const char l = a[i]; const char r = b[i]; if (l != r) { if (differences < 16) { cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n", i, l, r); } differences ++; } } if (differences > 0) { if (differences >= 16) { cm_print_error("...\n"); } cm_print_error("%"PRIdS " bytes of %p and %p differ\n", differences, (void *)a, (void *)b); return 0; } return 1; } /* * Determine whether the specified areas of memory are not equal. If they're * not equal 1 is returned otherwise an error is displayed and 0 is * returned. */ static int memory_not_equal_display_error( const char* const a, const char* const b, const size_t size) { size_t same = 0; size_t i; for (i = 0; i < size; i++) { const char l = a[i]; const char r = b[i]; if (l == r) { same ++; } } if (same == size) { cm_print_error("%"PRIdS "bytes of %p and %p the same\n", same, (void *)a, (void *)b); return 0; } return 1; } /* CheckParameterValue callback to check whether a value is within a set. */ static int check_in_set(const LargestIntegralType value, const LargestIntegralType check_value_data) { return value_in_set_display_error(value, cast_largest_integral_type_to_pointer(CheckIntegerSet*, check_value_data), 0); } /* CheckParameterValue callback to check whether a value isn't within a set. */ static int check_not_in_set(const LargestIntegralType value, const LargestIntegralType check_value_data) { return value_in_set_display_error(value, cast_largest_integral_type_to_pointer(CheckIntegerSet*, check_value_data), 1); } /* Create the callback data for check_in_set() or check_not_in_set() and * register a check event. */ static void expect_set( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const CheckParameterValue check_function, const int count) { CheckIntegerSet * const check_integer_set = (CheckIntegerSet*)malloc(sizeof(*check_integer_set) + (sizeof(values[0]) * number_of_values)); LargestIntegralType * const set = (LargestIntegralType*)( check_integer_set + 1); declare_initialize_value_pointer_pointer(check_data, check_integer_set); assert_non_null(values); assert_true(number_of_values); memcpy(set, values, number_of_values * sizeof(values[0])); check_integer_set->set = set; check_integer_set->size_of_set = number_of_values; _expect_check( function, parameter, file, line, check_function, check_data.value, &check_integer_set->event, count); } /* Add an event to check whether a value is in a set. */ void _expect_in_set( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count) { expect_set(function, parameter, file, line, values, number_of_values, check_in_set, count); } /* Add an event to check whether a value isn't in a set. */ void _expect_not_in_set( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count) { expect_set(function, parameter, file, line, values, number_of_values, check_not_in_set, count); } /* CheckParameterValue callback to check whether a value is within a range. */ static int check_in_range(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckIntegerRange * const check_integer_range = cast_largest_integral_type_to_pointer(CheckIntegerRange*, check_value_data); assert_non_null(check_integer_range); return integer_in_range_display_error(value, check_integer_range->minimum, check_integer_range->maximum); } /* CheckParameterValue callback to check whether a value is not within a range. */ static int check_not_in_range(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckIntegerRange * const check_integer_range = cast_largest_integral_type_to_pointer(CheckIntegerRange*, check_value_data); assert_non_null(check_integer_range); return integer_not_in_range_display_error( value, check_integer_range->minimum, check_integer_range->maximum); } /* Create the callback data for check_in_range() or check_not_in_range() and * register a check event. */ static void expect_range( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const CheckParameterValue check_function, const int count) { CheckIntegerRange * const check_integer_range = (CheckIntegerRange*)malloc(sizeof(*check_integer_range)); declare_initialize_value_pointer_pointer(check_data, check_integer_range); check_integer_range->minimum = minimum; check_integer_range->maximum = maximum; _expect_check(function, parameter, file, line, check_function, check_data.value, &check_integer_range->event, count); } /* Add an event to determine whether a parameter is within a range. */ void _expect_in_range( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count) { expect_range(function, parameter, file, line, minimum, maximum, check_in_range, count); } /* Add an event to determine whether a parameter is not within a range. */ void _expect_not_in_range( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count) { expect_range(function, parameter, file, line, minimum, maximum, check_not_in_range, count); } /* CheckParameterValue callback to check whether a value is equal to an * expected value. */ static int check_value(const LargestIntegralType value, const LargestIntegralType check_value_data) { return values_equal_display_error(value, check_value_data); } /* Add an event to check a parameter equals an expected value. */ void _expect_value( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType value, const int count) { _expect_check(function, parameter, file, line, check_value, value, NULL, count); } /* CheckParameterValue callback to check whether a value is not equal to an * expected value. */ static int check_not_value(const LargestIntegralType value, const LargestIntegralType check_value_data) { return values_not_equal_display_error(value, check_value_data); } /* Add an event to check a parameter is not equal to an expected value. */ void _expect_not_value( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType value, const int count) { _expect_check(function, parameter, file, line, check_not_value, value, NULL, count); } /* CheckParameterValue callback to check whether a parameter equals a string. */ static int check_string(const LargestIntegralType value, const LargestIntegralType check_value_data) { return string_equal_display_error( cast_largest_integral_type_to_pointer(char*, value), cast_largest_integral_type_to_pointer(char*, check_value_data)); } /* Add an event to check whether a parameter is equal to a string. */ void _expect_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, const int count) { declare_initialize_value_pointer_pointer(string_pointer, discard_const(string)); _expect_check(function, parameter, file, line, check_string, string_pointer.value, NULL, count); } /* CheckParameterValue callback to check whether a parameter is not equals to * a string. */ static int check_not_string(const LargestIntegralType value, const LargestIntegralType check_value_data) { return string_not_equal_display_error( cast_largest_integral_type_to_pointer(char*, value), cast_largest_integral_type_to_pointer(char*, check_value_data)); } /* Add an event to check whether a parameter is not equal to a string. */ void _expect_not_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, const int count) { declare_initialize_value_pointer_pointer(string_pointer, discard_const(string)); _expect_check(function, parameter, file, line, check_not_string, string_pointer.value, NULL, count); } /* CheckParameterValue callback to check whether a parameter equals an area of * memory. */ static int check_memory(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckMemoryData * const check = cast_largest_integral_type_to_pointer( CheckMemoryData*, check_value_data); assert_non_null(check); return memory_equal_display_error( cast_largest_integral_type_to_pointer(const char*, value), (const char*)check->memory, check->size); } /* Create the callback data for check_memory() or check_not_memory() and * register a check event. */ static void expect_memory_setup( const char* const function, const char* const parameter, const char* const file, const int line, const void * const memory, const size_t size, const CheckParameterValue check_function, const int count) { CheckMemoryData * const check_data = (CheckMemoryData*)malloc(sizeof(*check_data) + size); void * const mem = (void*)(check_data + 1); declare_initialize_value_pointer_pointer(check_data_pointer, check_data); assert_non_null(memory); assert_true(size); memcpy(mem, memory, size); check_data->memory = mem; check_data->size = size; _expect_check(function, parameter, file, line, check_function, check_data_pointer.value, &check_data->event, count); } /* Add an event to check whether a parameter matches an area of memory. */ void _expect_memory( const char* const function, const char* const parameter, const char* const file, const int line, const void* const memory, const size_t size, const int count) { expect_memory_setup(function, parameter, file, line, memory, size, check_memory, count); } /* CheckParameterValue callback to check whether a parameter is not equal to * an area of memory. */ static int check_not_memory(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckMemoryData * const check = cast_largest_integral_type_to_pointer( CheckMemoryData*, check_value_data); assert_non_null(check); return memory_not_equal_display_error( cast_largest_integral_type_to_pointer(const char*, value), (const char*)check->memory, check->size); } /* Add an event to check whether a parameter doesn't match an area of memory. */ void _expect_not_memory( const char* const function, const char* const parameter, const char* const file, const int line, const void* const memory, const size_t size, const int count) { expect_memory_setup(function, parameter, file, line, memory, size, check_not_memory, count); } /* CheckParameterValue callback that always returns 1. */ static int check_any(const LargestIntegralType value, const LargestIntegralType check_value_data) { (void)value; (void)check_value_data; return 1; } /* Add an event to allow any value for a parameter. */ void _expect_any( const char* const function, const char* const parameter, const char* const file, const int line, const int count) { _expect_check(function, parameter, file, line, check_any, 0, NULL, count); } void _check_expected( const char * const function_name, const char * const parameter_name, const char* file, const int line, const LargestIntegralType value) { void *result = NULL; const char* symbols[] = {function_name, parameter_name}; const int rc = get_symbol_value(&global_function_parameter_map_head, symbols, 2, &result); if (rc) { CheckParameterEvent * const check = (CheckParameterEvent*)result; int check_succeeded; global_last_parameter_location = check->location; check_succeeded = check->check_value(value, check->check_value_data); if (rc == 1) { free(check); } if (!check_succeeded) { cm_print_error(SOURCE_LOCATION_FORMAT ": error: Check of parameter %s, function %s failed\n" SOURCE_LOCATION_FORMAT ": note: Expected parameter declared here\n", file, line, parameter_name, function_name, global_last_parameter_location.file, global_last_parameter_location.line); _fail(file, line); } } else { cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " "to check parameter %s of function %s\n", file, line, parameter_name, function_name); if (source_location_is_set(&global_last_parameter_location)) { cm_print_error(SOURCE_LOCATION_FORMAT ": note: Previously declared parameter value was declared here\n", global_last_parameter_location.file, global_last_parameter_location.line); } else { cm_print_error("There were no previously declared parameter values " "for this test.\n"); } exit_test(1); } } /* Replacement for assert. */ void mock_assert(const int result, const char* const expression, const char* const file, const int line) { if (!result) { if (global_expecting_assert) { global_last_failed_assert = expression; longjmp(global_expect_assert_env, result); } else { cm_print_error("ASSERT: %s\n", expression); _fail(file, line); } } } void _assert_true(const LargestIntegralType result, const char * const expression, const char * const file, const int line) { if (!result) { cm_print_error("%s\n", expression); _fail(file, line); } } void _assert_return_code(const LargestIntegralType result, size_t rlen, const LargestIntegralType error, const char * const expression, const char * const file, const int line) { LargestIntegralType valmax; switch (rlen) { case 1: valmax = 255; break; case 2: valmax = 32767; break; case 4: valmax = 2147483647; break; case 8: default: if (rlen > sizeof(valmax)) { valmax = 2147483647; } else { valmax = 9223372036854775807L; } break; } if (result > valmax - 1) { if (error > 0) { cm_print_error("%s < 0, errno(" LargestIntegralTypePrintfFormatDecimal "): %s\n", expression, error, strerror((int)error)); } else { cm_print_error("%s < 0\n", expression); } _fail(file, line); } } void _assert_int_equal( const LargestIntegralType a, const LargestIntegralType b, const char * const file, const int line) { if (!values_equal_display_error(a, b)) { _fail(file, line); } } void _assert_int_not_equal( const LargestIntegralType a, const LargestIntegralType b, const char * const file, const int line) { if (!values_not_equal_display_error(a, b)) { _fail(file, line); } } void _assert_string_equal(const char * const a, const char * const b, const char * const file, const int line) { if (!string_equal_display_error(a, b)) { _fail(file, line); } } void _assert_string_not_equal(const char * const a, const char * const b, const char *file, const int line) { if (!string_not_equal_display_error(a, b)) { _fail(file, line); } } void _assert_memory_equal(const void * const a, const void * const b, const size_t size, const char* const file, const int line) { if (!memory_equal_display_error((const char*)a, (const char*)b, size)) { _fail(file, line); } } void _assert_memory_not_equal(const void * const a, const void * const b, const size_t size, const char* const file, const int line) { if (!memory_not_equal_display_error((const char*)a, (const char*)b, size)) { _fail(file, line); } } void _assert_in_range( const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char* const file, const int line) { if (!integer_in_range_display_error(value, minimum, maximum)) { _fail(file, line); } } void _assert_not_in_range( const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char* const file, const int line) { if (!integer_not_in_range_display_error(value, minimum, maximum)) { _fail(file, line); } } void _assert_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char* const file, const int line) { CheckIntegerSet check_integer_set; check_integer_set.set = values; check_integer_set.size_of_set = number_of_values; if (!value_in_set_display_error(value, &check_integer_set, 0)) { _fail(file, line); } } void _assert_not_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char* const file, const int line) { CheckIntegerSet check_integer_set; check_integer_set.set = values; check_integer_set.size_of_set = number_of_values; if (!value_in_set_display_error(value, &check_integer_set, 1)) { _fail(file, line); } } /* Get the list of allocated blocks. */ static ListNode* get_allocated_blocks_list(void) { /* If it initialized, initialize the list of allocated blocks. */ if (!global_allocated_blocks.value) { list_initialize(&global_allocated_blocks); global_allocated_blocks.value = (void*)1; } return &global_allocated_blocks; } static void *libc_malloc(size_t size) { #undef malloc return malloc(size); #define malloc test_malloc } static void libc_free(void *ptr) { #undef free free(ptr); #define free test_free } static void *libc_realloc(void *ptr, size_t size) { #undef realloc return realloc(ptr, size); #define realloc test_realloc } static void vcm_print_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); /* It's important to use the libc malloc and free here otherwise * the automatic free of leaked blocks can reap the error messages */ static void vcm_print_error(const char* const format, va_list args) { char buffer[1024]; size_t msg_len = 0; va_list ap; int len; va_copy(ap, args); len = vsnprintf(buffer, sizeof(buffer), format, args); if (len < 0) { /* TODO */ goto end; } if (cm_error_message == NULL) { /* CREATE MESSAGE */ cm_error_message = libc_malloc(len + 1); if (cm_error_message == NULL) { /* TODO */ goto end; } } else { /* APPEND MESSAGE */ char *tmp; msg_len = strlen(cm_error_message); tmp = libc_realloc(cm_error_message, msg_len + len + 1); if (tmp == NULL) { goto end; } cm_error_message = tmp; } if (((size_t)len) < sizeof(buffer)) { /* Use len + 1 to also copy '\0' */ memcpy(cm_error_message + msg_len, buffer, len + 1); } else { vsnprintf(cm_error_message + msg_len, len, format, ap); } end: va_end(ap); } static void vcm_free_error(char *err_msg) { libc_free(err_msg); } /* Use the real malloc in this function. */ #undef malloc void* _test_malloc(const size_t size, const char* file, const int line) { char *ptr = NULL; MallocBlockInfo block_info; ListNode * const block_list = get_allocated_blocks_list(); size_t allocate_size; char *block = NULL; allocate_size = size + (MALLOC_GUARD_SIZE * 2) + sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT; assert_true(allocate_size > size); block = (char *)malloc(allocate_size); assert_non_null(block); /* Calculate the returned address. */ ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); /* Initialize the guard blocks. */ memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); memset(ptr, MALLOC_ALLOC_PATTERN, size); block_info.ptr = ptr - (MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData)); set_source_location(&block_info.data->location, file, line); block_info.data->allocated_size = allocate_size; block_info.data->size = size; block_info.data->block = block; block_info.data->node.value = block_info.ptr; list_add(block_list, &block_info.data->node); return ptr; } #define malloc test_malloc void* _test_calloc(const size_t number_of_elements, const size_t size, const char* file, const int line) { void* const ptr = _test_malloc(number_of_elements * size, file, line); if (ptr) { memset(ptr, 0, number_of_elements * size); } return ptr; } /* Use the real free in this function. */ #undef free void _test_free(void* const ptr, const char* file, const int line) { unsigned int i; char *block = discard_const_p(char, ptr); MallocBlockInfo block_info; if (ptr == NULL) { return; } _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line); block_info.ptr = block - (MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData)); /* Check the guard blocks. */ { char *guards[2] = {block - MALLOC_GUARD_SIZE, block + block_info.data->size}; for (i = 0; i < ARRAY_SIZE(guards); i++) { unsigned int j; char * const guard = guards[i]; for (j = 0; j < MALLOC_GUARD_SIZE; j++) { const char diff = guard[j] - MALLOC_GUARD_PATTERN; if (diff) { cm_print_error(SOURCE_LOCATION_FORMAT ": error: Guard block of %p size=%lu is corrupt\n" SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n", file, line, ptr, (unsigned long)block_info.data->size, block_info.data->location.file, block_info.data->location.line, (void *)&guard[j]); _fail(file, line); } } } } list_remove(&block_info.data->node, NULL, NULL); block = discard_const_p(char, block_info.data->block); memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size); free(block); } #define free test_free #undef realloc void *_test_realloc(void *ptr, const size_t size, const char *file, const int line) { MallocBlockInfo block_info; char *block = ptr; size_t block_size = size; void *new_block; if (ptr == NULL) { return _test_malloc(size, file, line); } if (size == 0) { _test_free(ptr, file, line); return NULL; } block_info.ptr = block - (MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData)); new_block = _test_malloc(size, file, line); if (new_block == NULL) { return NULL; } if (block_info.data->size < size) { block_size = block_info.data->size; } memcpy(new_block, ptr, block_size); /* Free previous memory */ _test_free(ptr, file, line); return new_block; } #define realloc test_realloc /* Crudely checkpoint the current heap state. */ static const ListNode* check_point_allocated_blocks(void) { return get_allocated_blocks_list()->prev; } /* 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) { const ListNode * const head = get_allocated_blocks_list(); const ListNode *node; size_t allocated_blocks = 0; assert_non_null(check_point); assert_non_null(check_point->next); for (node = check_point->next; node != head; node = node->next) { const MallocBlockInfo block_info = { .ptr = discard_const(node->value), }; assert_non_null(block_info.ptr); if (allocated_blocks == 0) { cm_print_error("Blocks allocated...\n"); } cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n", block_info.data->location.file, block_info.data->location.line, block_info.data->block); allocated_blocks++; } return allocated_blocks; } /* Free all blocks allocated after the specified check point. */ static void free_allocated_blocks(const ListNode * const check_point) { const ListNode * const head = get_allocated_blocks_list(); const ListNode *node; assert_non_null(check_point); node = check_point->next; assert_non_null(node); while (node != head) { const MallocBlockInfo block_info = { .ptr = discard_const(node->value), }; node = node->next; free(discard_const_p(char, block_info.data) + sizeof(struct MallocBlockInfoData) + MALLOC_GUARD_SIZE); } } /* 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) { free_allocated_blocks(check_point); cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name, allocated_blocks); exit_test(1); } } void _fail(const char * const file, const int line) { enum cm_message_output output = cm_get_output(); switch(output) { case CM_OUTPUT_STDOUT: cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); break; default: cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); break; } exit_test(1); } #ifndef _WIN32 static void exception_handler(int sig) { const char *sig_strerror = ""; #ifdef HAVE_STRSIGNAL sig_strerror = strsignal(sig); #endif cm_print_error("Test failed with exception: %s(%d)", sig_strerror, sig); exit_test(1); } #else /* _WIN32 */ static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { EXCEPTION_RECORD * const exception_record = exception_pointers->ExceptionRecord; const DWORD code = exception_record->ExceptionCode; unsigned int i; for (i = 0; i < ARRAY_SIZE(exception_codes); i++) { const ExceptionCodeInfo * const code_info = &exception_codes[i]; if (code == code_info->code) { static int shown_debug_message = 0; fflush(stdout); cm_print_error("%s occurred at %p.\n", code_info->description, exception_record->ExceptionAddress); if (!shown_debug_message) { cm_print_error( "\n" "To debug in Visual Studio...\n" "1. Select menu item File->Open Project\n" "2. Change 'Files of type' to 'Executable Files'\n" "3. Open this executable.\n" "4. Select menu item Debug->Start\n" "\n" "Alternatively, set the environment variable \n" "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" "then click 'Debug' in the popup dialog box.\n" "\n"); shown_debug_message = 1; } exit_test(0); return EXCEPTION_EXECUTE_HANDLER; } } return EXCEPTION_CONTINUE_SEARCH; } #endif /* !_WIN32 */ void cm_print_error(const char * const format, ...) { va_list args; va_start(args, format); if (cm_error_message_enabled) { vcm_print_error(format, args); } else { vprint_error(format, args); } va_end(args); } /* Standard output and error print methods. */ void vprint_message(const char* const format, va_list args) { char buffer[1024]; vsnprintf(buffer, sizeof(buffer), format, args); printf("%s", buffer); fflush(stdout); #ifdef _WIN32 OutputDebugString(buffer); #endif /* _WIN32 */ } void vprint_error(const char* const format, va_list args) { char buffer[1024]; vsnprintf(buffer, sizeof(buffer), format, args); fprintf(stderr, "%s", buffer); fflush(stderr); #ifdef _WIN32 OutputDebugString(buffer); #endif /* _WIN32 */ } void print_message(const char* const format, ...) { va_list args; va_start(args, format); vprint_message(format, args); va_end(args); } void print_error(const char* const format, ...) { va_list args; va_start(args, format); vprint_error(format, args); va_end(args); } /* New formatter */ static enum cm_message_output cm_get_output(void) { enum cm_message_output output = global_msg_output; char *env; env = getenv("CMOCKA_MESSAGE_OUTPUT"); if (env != NULL) { if (strcasecmp(env, "STDOUT") == 0) { output = CM_OUTPUT_STDOUT; } else if (strcasecmp(env, "SUBUNIT") == 0) { output = CM_OUTPUT_SUBUNIT; } else if (strcasecmp(env, "TAP") == 0) { output = CM_OUTPUT_TAP; } else if (strcasecmp(env, "XML") == 0) { output = CM_OUTPUT_XML; } } return output; } enum cm_printf_type { PRINTF_TEST_START, PRINTF_TEST_SUCCESS, PRINTF_TEST_FAILURE, PRINTF_TEST_ERROR, PRINTF_TEST_SKIPPED, }; static int xml_printed; static int file_append; static void cmprintf_group_finish_xml(const char *group_name, size_t total_executed, size_t total_failed, size_t total_errors, size_t total_skipped, double total_runtime, struct CMUnitTestState *cm_tests) { FILE *fp = stdout; int file_opened = 0; int multiple_files = 0; char *env; size_t i; env = getenv("CMOCKA_XML_FILE"); if (env != NULL) { char buf[1024]; int rc; snprintf(buf, sizeof(buf), "%s", env); rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files); if (rc < 0) { snprintf(buf, sizeof(buf), "%s", env); } fp = fopen(buf, "r"); if (fp == NULL) { fp = fopen(buf, "w"); if (fp != NULL) { file_append = 1; file_opened = 1; } else { fp = stderr; } } else { fclose(fp); if (file_append) { fp = fopen(buf, "a"); if (fp != NULL) { file_opened = 1; xml_printed = 1; } else { fp = stderr; } } else { fp = stderr; } } } if (!xml_printed || (file_opened && !file_append)) { fprintf(fp, "\n"); if (!file_opened) { xml_printed = 1; } } fprintf(fp, "\n"); fprintf(fp, " \n", group_name, total_runtime, /* seconds */ (unsigned)total_executed, (unsigned)total_failed, (unsigned)total_errors, (unsigned)total_skipped); for (i = 0; i < total_executed; i++) { struct CMUnitTestState *cmtest = &cm_tests[i]; fprintf(fp, " \n", cmtest->test->name, cmtest->runtime); switch (cmtest->status) { case CM_TEST_ERROR: case CM_TEST_FAILED: if (cmtest->error_message != NULL) { fprintf(fp, " \n", cmtest->error_message); } else { fprintf(fp, " \n"); } break; case CM_TEST_SKIPPED: fprintf(fp, " \n"); break; case CM_TEST_PASSED: case CM_TEST_NOT_STARTED: break; } fprintf(fp, " \n"); } fprintf(fp, " \n"); fprintf(fp, "\n"); if (file_opened) { fclose(fp); } } static void cmprintf_group_start_standard(const size_t num_tests) { print_message("[==========] Running %u test(s).\n", (unsigned)num_tests); } static void cmprintf_group_finish_standard(size_t total_executed, size_t total_passed, size_t total_failed, size_t total_errors, size_t total_skipped, struct CMUnitTestState *cm_tests) { size_t i; print_message("[==========] %u test(s) run.\n", (unsigned)total_executed); print_error("[ PASSED ] %u test(s).\n", (unsigned)(total_passed)); if (total_skipped) { print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped); for (i = 0; i < total_executed; i++) { struct CMUnitTestState *cmtest = &cm_tests[i]; if (cmtest->status == CM_TEST_SKIPPED) { print_error("[ SKIPPED ] %s\n", cmtest->test->name); } } print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped)); } if (total_failed) { print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); for (i = 0; i < total_executed; i++) { struct CMUnitTestState *cmtest = &cm_tests[i]; if (cmtest->status == CM_TEST_FAILED) { print_error("[ FAILED ] %s\n", cmtest->test->name); } } print_error("\n %u FAILED TEST(S)\n", (unsigned)(total_failed + total_errors)); } } static void cmprintf_standard(enum cm_printf_type type, const char *test_name, const char *error_message) { switch (type) { case PRINTF_TEST_START: print_message("[ RUN ] %s\n", test_name); break; case PRINTF_TEST_SUCCESS: print_message("[ OK ] %s\n", test_name); break; case PRINTF_TEST_FAILURE: if (error_message != NULL) { print_error("[ ERROR ] --- %s\n", error_message); } print_message("[ FAILED ] %s\n", test_name); break; case PRINTF_TEST_SKIPPED: print_message("[ SKIPPED ] %s\n", test_name); break; case PRINTF_TEST_ERROR: if (error_message != NULL) { print_error("%s\n", error_message); } print_error("[ ERROR ] %s\n", test_name); break; } } static void cmprintf_group_start_tap(const size_t num_tests) { print_message("1..%u\n", (unsigned)num_tests); } static void cmprintf_group_finish_tap(const char *group_name, size_t total_executed, size_t total_passed, size_t total_skipped) { const char *status = "not ok"; if (total_passed + total_skipped == total_executed) { status = "ok"; } print_message("# %s - %s\n", status, group_name); } static void cmprintf_tap(enum cm_printf_type type, uint32_t test_number, const char *test_name, const char *error_message) { switch (type) { case PRINTF_TEST_START: break; case PRINTF_TEST_SUCCESS: print_message("ok %u - %s\n", (unsigned)test_number, test_name); break; case PRINTF_TEST_FAILURE: print_message("not ok %u - %s\n", (unsigned)test_number, test_name); if (error_message != NULL) { char *msg; char *p; msg = strdup(error_message); if (msg == NULL) { return; } p = msg; while (p[0] != '\0') { char *q = p; p = strchr(q, '\n'); if (p != NULL) { p[0] = '\0'; } print_message("# %s\n", q); if (p == NULL) { break; } p++; } libc_free(msg); } break; case PRINTF_TEST_SKIPPED: print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name); break; case PRINTF_TEST_ERROR: print_message("not ok %u - %s %s\n", (unsigned)test_number, test_name, error_message); break; } } static void cmprintf_subunit(enum cm_printf_type type, const char *test_name, const char *error_message) { switch (type) { case PRINTF_TEST_START: print_message("test: %s\n", test_name); break; case PRINTF_TEST_SUCCESS: print_message("success: %s\n", test_name); break; case PRINTF_TEST_FAILURE: print_message("failure: %s", test_name); if (error_message != NULL) { print_message(" [\n%s\n]\n", error_message); } break; case PRINTF_TEST_SKIPPED: print_message("skip: %s\n", test_name); break; case PRINTF_TEST_ERROR: print_message("error: %s [ %s ]\n", test_name, error_message); break; } } static void cmprintf_group_start(const size_t num_tests) { enum cm_message_output output; output = cm_get_output(); switch (output) { case CM_OUTPUT_STDOUT: cmprintf_group_start_standard(num_tests); break; case CM_OUTPUT_SUBUNIT: break; case CM_OUTPUT_TAP: cmprintf_group_start_tap(num_tests); break; case CM_OUTPUT_XML: break; } } static void cmprintf_group_finish(const char *group_name, size_t total_executed, size_t total_passed, size_t total_failed, size_t total_errors, size_t total_skipped, double total_runtime, struct CMUnitTestState *cm_tests) { enum cm_message_output output; output = cm_get_output(); switch (output) { case CM_OUTPUT_STDOUT: cmprintf_group_finish_standard(total_executed, total_passed, total_failed, total_errors, total_skipped, cm_tests); break; case CM_OUTPUT_SUBUNIT: break; case CM_OUTPUT_TAP: cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped); break; case CM_OUTPUT_XML: cmprintf_group_finish_xml(group_name, total_executed, total_failed, total_errors, total_skipped, total_runtime, cm_tests); break; } } static void cmprintf(enum cm_printf_type type, size_t test_number, const char *test_name, const char *error_message) { enum cm_message_output output; output = cm_get_output(); switch (output) { case CM_OUTPUT_STDOUT: cmprintf_standard(type, test_name, error_message); break; case CM_OUTPUT_SUBUNIT: cmprintf_subunit(type, test_name, error_message); break; case CM_OUTPUT_TAP: cmprintf_tap(type, test_number, test_name, error_message); break; case CM_OUTPUT_XML: break; } } void cmocka_set_message_output(enum cm_message_output output) { global_msg_output = output; } void cmocka_set_test_filter(const char *pattern) { global_test_filter_pattern = pattern; } /**************************************************************************** * TIME CALCULATIONS ****************************************************************************/ #ifdef HAVE_STRUCT_TIMESPEC static struct timespec cm_tspecdiff(struct timespec time1, struct timespec time0) { struct timespec ret; int xsec = 0; int sign = 1; if (time0.tv_nsec > time1.tv_nsec) { xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); time0.tv_nsec -= (long int) (1E9 * xsec); time0.tv_sec += xsec; } if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); time0.tv_nsec += (long int) (1E9 * xsec); time0.tv_sec -= xsec; } ret.tv_sec = time1.tv_sec - time0.tv_sec; ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; if (time1.tv_sec < time0.tv_sec) { sign = -1; } ret.tv_sec = ret.tv_sec * sign; return ret; } static double cm_secdiff(struct timespec clock1, struct timespec clock0) { double ret; struct timespec diff; diff = cm_tspecdiff(clock1, clock0); ret = diff.tv_sec; ret += (double) diff.tv_nsec / (double) 1E9; return ret; } #endif /* HAVE_STRUCT_TIMESPEC */ /**************************************************************************** * CMOCKA TEST RUNNER ****************************************************************************/ static int cmocka_run_one_test_or_fixture(const char *function_name, CMUnitTestFunction test_func, CMFixtureFunction setup_func, CMFixtureFunction teardown_func, void ** const volatile state, const void *const heap_check_point) { const ListNode * const volatile check_point = (const ListNode*) (heap_check_point != NULL ? heap_check_point : check_point_allocated_blocks()); int handle_exceptions = 1; void *current_state = NULL; int rc = 0; /* FIXME check only one test or fixture is set */ /* Detect if we should handle exceptions */ #ifdef _WIN32 handle_exceptions = !IsDebuggerPresent(); #endif /* _WIN32 */ #ifdef UNIT_TESTING_DEBUG handle_exceptions = 0; #endif /* UNIT_TESTING_DEBUG */ if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { default_signal_functions[i] = signal( exception_signals[i], exception_handler); } #else /* _WIN32 */ previous_exception_filter = SetUnhandledExceptionFilter( exception_filter); #endif /* !_WIN32 */ } /* Init the test structure */ initialize_testing(function_name); global_running_test = 1; if (cm_setjmp(global_run_test_env) == 0) { if (test_func != NULL) { test_func(state != NULL ? state : ¤t_state); fail_if_blocks_allocated(check_point, function_name); rc = 0; } else if (setup_func != NULL) { rc = setup_func(state != NULL ? state : ¤t_state); /* * For setup we can ignore any allocated blocks. We just need to * ensure they're deallocated on tear down. */ } else if (teardown_func != NULL) { rc = teardown_func(state != NULL ? state : ¤t_state); fail_if_blocks_allocated(check_point, function_name); } else { /* ERROR */ } fail_if_leftover_values(function_name); global_running_test = 0; } else { /* TEST FAILED */ global_running_test = 0; rc = -1; } teardown_testing(function_name); if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { signal(exception_signals[i], default_signal_functions[i]); } #else /* _WIN32 */ if (previous_exception_filter) { SetUnhandledExceptionFilter(previous_exception_filter); previous_exception_filter = NULL; } #endif /* !_WIN32 */ } return rc; } static int cmocka_run_group_fixture(const char *function_name, CMFixtureFunction setup_func, CMFixtureFunction teardown_func, void **state, const void *const heap_check_point) { int rc; if (setup_func != NULL) { rc = cmocka_run_one_test_or_fixture(function_name, NULL, setup_func, NULL, state, heap_check_point); } else { rc = cmocka_run_one_test_or_fixture(function_name, NULL, NULL, teardown_func, state, heap_check_point); } return rc; } static int cmocka_run_one_tests(struct CMUnitTestState *test_state) { #ifdef HAVE_STRUCT_TIMESPEC struct timespec start = { .tv_sec = 0, .tv_nsec = 0, }; struct timespec finish = { .tv_sec = 0, .tv_nsec = 0, }; #endif int rc = 0; /* Run setup */ if (test_state->test->setup_func != NULL) { /* Setup the memory check point, it will be evaluated on teardown */ test_state->check_point = check_point_allocated_blocks(); rc = cmocka_run_one_test_or_fixture(test_state->test->name, NULL, test_state->test->setup_func, NULL, &test_state->state, test_state->check_point); if (rc != 0) { test_state->status = CM_TEST_ERROR; cm_print_error("Test setup failed"); } } /* Run test */ #ifdef HAVE_STRUCT_TIMESPEC CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start); #endif if (rc == 0) { rc = cmocka_run_one_test_or_fixture(test_state->test->name, test_state->test->test_func, NULL, NULL, &test_state->state, NULL); if (rc == 0) { test_state->status = CM_TEST_PASSED; } else { if (global_skip_test) { test_state->status = CM_TEST_SKIPPED; global_skip_test = 0; /* Do not skip the next test */ } else { test_state->status = CM_TEST_FAILED; } } rc = 0; } test_state->runtime = 0.0; #ifdef HAVE_STRUCT_TIMESPEC CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish); test_state->runtime = cm_secdiff(finish, start); #endif /* Run teardown */ if (rc == 0 && test_state->test->teardown_func != NULL) { rc = cmocka_run_one_test_or_fixture(test_state->test->name, NULL, NULL, test_state->test->teardown_func, &test_state->state, test_state->check_point); if (rc != 0) { test_state->status = CM_TEST_ERROR; cm_print_error("Test teardown failed"); } } test_state->error_message = cm_error_message; cm_error_message = NULL; return rc; } int _cmocka_run_group_tests(const char *group_name, const struct CMUnitTest * const tests, const size_t num_tests, CMFixtureFunction group_setup, CMFixtureFunction group_teardown) { struct CMUnitTestState *cm_tests; const ListNode *group_check_point = check_point_allocated_blocks(); void *group_state = NULL; size_t total_tests = 0; size_t total_failed = 0; size_t total_passed = 0; size_t total_executed = 0; size_t total_errors = 0; size_t total_skipped = 0; double total_runtime = 0; size_t i; int rc; /* Make sure LargestIntegralType is at least the size of a pointer. */ assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests); if (cm_tests == NULL) { return -1; } /* Setup cmocka test array */ for (i = 0; i < num_tests; i++) { if (tests[i].name != NULL && (tests[i].test_func != NULL || tests[i].setup_func != NULL || tests[i].teardown_func != NULL)) { if (global_test_filter_pattern != NULL) { int ok; ok = c_strmatch(tests[i].name, global_test_filter_pattern); if (!ok) { continue; } } cm_tests[total_tests] = (struct CMUnitTestState) { .test = &tests[i], .status = CM_TEST_NOT_STARTED, .state = NULL, }; total_tests++; } } cmprintf_group_start(total_tests); rc = 0; /* Run group setup */ if (group_setup != NULL) { rc = cmocka_run_group_fixture("cmocka_group_setup", group_setup, NULL, &group_state, group_check_point); } if (rc == 0) { /* Execute tests */ for (i = 0; i < total_tests; i++) { struct CMUnitTestState *cmtest = &cm_tests[i]; size_t test_number = i + 1; cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL); if (group_state != NULL) { cmtest->state = group_state; } else if (cmtest->test->initial_state != NULL) { cmtest->state = cmtest->test->initial_state; } rc = cmocka_run_one_tests(cmtest); total_executed++; total_runtime += cmtest->runtime; if (rc == 0) { switch (cmtest->status) { case CM_TEST_PASSED: cmprintf(PRINTF_TEST_SUCCESS, test_number, cmtest->test->name, cmtest->error_message); total_passed++; break; case CM_TEST_SKIPPED: cmprintf(PRINTF_TEST_SKIPPED, test_number, cmtest->test->name, cmtest->error_message); total_skipped++; break; case CM_TEST_FAILED: cmprintf(PRINTF_TEST_FAILURE, test_number, cmtest->test->name, cmtest->error_message); total_failed++; break; default: cmprintf(PRINTF_TEST_ERROR, test_number, cmtest->test->name, "Internal cmocka error"); total_errors++; break; } } else { char err_msg[2048] = {0}; snprintf(err_msg, sizeof(err_msg), "Could not run test: %s", cmtest->error_message); cmprintf(PRINTF_TEST_ERROR, test_number, cmtest->test->name, err_msg); total_errors++; } } } else { if (cm_error_message != NULL) { print_error("[ ERROR ] --- %s\n", cm_error_message); vcm_free_error(cm_error_message); cm_error_message = NULL; } cmprintf(PRINTF_TEST_ERROR, 0, group_name, "[ FAILED ] GROUP SETUP"); total_errors++; } /* Run group teardown */ if (group_teardown != NULL) { rc = cmocka_run_group_fixture("cmocka_group_teardown", NULL, group_teardown, &group_state, group_check_point); if (rc != 0) { if (cm_error_message != NULL) { print_error("[ ERROR ] --- %s\n", cm_error_message); vcm_free_error(cm_error_message); cm_error_message = NULL; } cmprintf(PRINTF_TEST_ERROR, 0, group_name, "[ FAILED ] GROUP TEARDOWN"); } } cmprintf_group_finish(group_name, total_executed, total_passed, total_failed, total_errors, total_skipped, total_runtime, cm_tests); for (i = 0; i < total_tests; i++) { vcm_free_error(discard_const_p(char, cm_tests[i].error_message)); } libc_free(cm_tests); fail_if_blocks_allocated(group_check_point, "cmocka_group_tests"); return total_failed + total_errors; } /**************************************************************************** * DEPRECATED TEST RUNNER ****************************************************************************/ int _run_test( const char * const function_name, const UnitTestFunction Function, void ** const volatile state, const UnitTestFunctionType function_type, const void* const heap_check_point) { const ListNode * const volatile check_point = (const ListNode*) (heap_check_point ? heap_check_point : check_point_allocated_blocks()); void *current_state = NULL; volatile int rc = 1; int handle_exceptions = 1; #ifdef _WIN32 handle_exceptions = !IsDebuggerPresent(); #endif /* _WIN32 */ #ifdef UNIT_TESTING_DEBUG handle_exceptions = 0; #endif /* UNIT_TESTING_DEBUG */ cm_error_message_enabled = 0; if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { default_signal_functions[i] = signal( exception_signals[i], exception_handler); } #else /* _WIN32 */ previous_exception_filter = SetUnhandledExceptionFilter( exception_filter); #endif /* !_WIN32 */ } if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { print_message("[ RUN ] %s\n", function_name); } initialize_testing(function_name); global_running_test = 1; if (cm_setjmp(global_run_test_env) == 0) { Function(state ? state : ¤t_state); fail_if_leftover_values(function_name); /* If this is a setup function then ignore any allocated blocks * only ensure they're deallocated on tear down. */ if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { fail_if_blocks_allocated(check_point, function_name); } global_running_test = 0; if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { print_message("[ OK ] %s\n", function_name); } rc = 0; } else { global_running_test = 0; print_message("[ FAILED ] %s\n", function_name); } teardown_testing(function_name); if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { signal(exception_signals[i], default_signal_functions[i]); } #else /* _WIN32 */ if (previous_exception_filter) { SetUnhandledExceptionFilter(previous_exception_filter); previous_exception_filter = NULL; } #endif /* !_WIN32 */ } return rc; } int _run_tests(const UnitTest * const tests, const size_t number_of_tests) { /* Whether to execute the next test. */ int run_next_test = 1; /* Whether the previous test failed. */ int previous_test_failed = 0; /* Whether the previous setup failed. */ int previous_setup_failed = 0; /* Check point of the heap state. */ const ListNode * const check_point = check_point_allocated_blocks(); /* Current test being executed. */ size_t current_test = 0; /* Number of tests executed. */ size_t tests_executed = 0; /* Number of failed tests. */ size_t total_failed = 0; /* Number of setup functions. */ size_t setups = 0; /* Number of teardown functions. */ size_t teardowns = 0; size_t i; /* * A stack of test states. A state is pushed on the stack * when a test setup occurs and popped on tear down. */ TestState* test_states = (TestState*)malloc(number_of_tests * sizeof(*test_states)); /* The number of test states which should be 0 at the end */ long number_of_test_states = 0; /* Names of the tests that failed. */ const char** failed_names = (const char**)malloc(number_of_tests * sizeof(*failed_names)); void **current_state = NULL; /* Count setup and teardown functions */ for (i = 0; i < number_of_tests; i++) { const UnitTest * const test = &tests[i]; if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) { setups++; } if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) { teardowns++; } } print_message("[==========] Running %"PRIdS " test(s).\n", number_of_tests - setups - teardowns); /* Make sure LargestIntegralType is at least the size of a pointer. */ assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); while (current_test < number_of_tests) { const ListNode *test_check_point = NULL; TestState *current_TestState; const UnitTest * const test = &tests[current_test++]; if (!test->function) { continue; } switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: if (! previous_setup_failed) { run_next_test = 1; } break; case UNIT_TEST_FUNCTION_TYPE_SETUP: { /* Checkpoint the heap before the setup. */ current_TestState = &test_states[number_of_test_states++]; current_TestState->check_point = check_point_allocated_blocks(); test_check_point = current_TestState->check_point; current_state = ¤t_TestState->state; *current_state = NULL; run_next_test = 1; break; } case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: /* Check the heap based on the last setup checkpoint. */ assert_true(number_of_test_states); current_TestState = &test_states[--number_of_test_states]; test_check_point = current_TestState->check_point; current_state = ¤t_TestState->state; break; default: print_error("Invalid unit test function type %d\n", test->function_type); exit_test(1); break; } if (run_next_test) { int failed = _run_test(test->name, test->function, current_state, test->function_type, test_check_point); if (failed) { failed_names[total_failed] = test->name; } switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: previous_test_failed = failed; total_failed += failed; tests_executed ++; break; case UNIT_TEST_FUNCTION_TYPE_SETUP: if (failed) { total_failed ++; tests_executed ++; /* Skip forward until the next test or setup function. */ run_next_test = 0; previous_setup_failed = 1; } previous_test_failed = 0; break; case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: /* If this test failed. */ if (failed && !previous_test_failed) { total_failed ++; } break; default: #ifndef _HPUX assert_null("BUG: shouldn't be here!"); #endif break; } } } print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); if (total_failed > 0) { print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); for (i = 0; i < total_failed; i++) { print_error("[ FAILED ] %s\n", failed_names[i]); } } else { print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); } if (number_of_test_states != 0) { print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and " "teardown %"PRIdS " functions\n", setups, teardowns); total_failed = (size_t)-1; } free(test_states); free((void*)failed_names); fail_if_blocks_allocated(check_point, "run_tests"); return (int)total_failed; } int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests) { UnitTestFunction setup = NULL; const char *setup_name; size_t num_setups = 0; UnitTestFunction teardown = NULL; const char *teardown_name = NULL; size_t num_teardowns = 0; size_t current_test = 0; size_t i; /* Number of tests executed. */ size_t tests_executed = 0; /* Number of failed tests. */ size_t total_failed = 0; /* Check point of the heap state. */ const ListNode * const check_point = check_point_allocated_blocks(); const char **failed_names = NULL; void **current_state = NULL; TestState group_state = { .check_point = NULL, }; if (number_of_tests == 0) { return -1; } failed_names = (const char **)malloc(number_of_tests * sizeof(*failed_names)); if (failed_names == NULL) { return -2; } /* Find setup and teardown function */ for (i = 0; i < number_of_tests; i++) { const UnitTest * const test = &tests[i]; if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) { if (setup == NULL) { setup = test->function; setup_name = test->name; num_setups = 1; } else { print_error("[ ERROR ] More than one group setup function detected\n"); exit_test(1); } } if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) { if (teardown == NULL) { teardown = test->function; teardown_name = test->name; num_teardowns = 1; } else { print_error("[ ERROR ] More than one group teardown function detected\n"); exit_test(1); } } } print_message("[==========] Running %"PRIdS " test(s).\n", number_of_tests - num_setups - num_teardowns); if (setup != NULL) { int failed; group_state.check_point = check_point_allocated_blocks(); current_state = &group_state.state; *current_state = NULL; failed = _run_test(setup_name, setup, current_state, UNIT_TEST_FUNCTION_TYPE_SETUP, group_state.check_point); if (failed) { failed_names[total_failed] = setup_name; } total_failed += failed; tests_executed++; } while (current_test < number_of_tests) { int run_test = 0; const UnitTest * const test = &tests[current_test++]; if (test->function == NULL) { continue; } switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: run_test = 1; break; case UNIT_TEST_FUNCTION_TYPE_SETUP: case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP: case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN: break; default: print_error("Invalid unit test function type %d\n", test->function_type); break; } if (run_test) { int failed; failed = _run_test(test->name, test->function, current_state, test->function_type, NULL); if (failed) { failed_names[total_failed] = test->name; } total_failed += failed; tests_executed++; } } if (teardown != NULL) { int failed; failed = _run_test(teardown_name, teardown, current_state, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, group_state.check_point); if (failed) { failed_names[total_failed] = teardown_name; } total_failed += failed; tests_executed++; } print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); if (total_failed) { print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); for (i = 0; i < total_failed; i++) { print_error("[ FAILED ] %s\n", failed_names[i]); } } else { print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); } free((void*)failed_names); fail_if_blocks_allocated(check_point, "run_group_tests"); return (int)total_failed; } ldb-2.0.8/third_party/cmocka/cmocka.h0000660000000000000000000021622713573675414017443 0ustar rootroot00000000000000/* * Copyright 2008 Google Inc. * Copyright 2014-2018 Andreas Schneider * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CMOCKA_H_ #define CMOCKA_H_ #ifdef _WIN32 # ifdef _MSC_VER #define __func__ __FUNCTION__ # ifndef inline #define inline __inline # endif /* inline */ # if _MSC_VER < 1500 # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ int __stdcall IsDebuggerPresent(); # ifdef __cplusplus } /* extern "C" */ # endif /* __cplusplus */ # endif /* _MSC_VER < 1500 */ # endif /* _MSC_VER */ #endif /* _WIN32 */ /** * @defgroup cmocka The CMocka API * * These headers or their equivalents should be included prior to including * this header file. * @code * #include * #include * #include * @endcode * * This allows test applications to use custom definitions of C standard * library functions and types. * * @{ */ /* If __WORDSIZE is not set, try to figure it out and default to 32 bit. */ #ifndef __WORDSIZE # if (defined(__x86_64__) && !defined(__ILP32__)) || defined(__sparc_v9__) || defined(__sparcv9) # define __WORDSIZE 64 # else # define __WORDSIZE 32 # endif #endif #ifdef DOXYGEN /** * Largest integral type. This type should be large enough to hold any * pointer or integer supported by the compiler. */ typedef uintmax_t LargestIntegralType; #else /* DOXGEN */ #ifndef LargestIntegralType # if __WORDSIZE == 64 && !defined(_WIN64) # define LargestIntegralType unsigned long int # else # define LargestIntegralType unsigned long long int # endif #endif /* LargestIntegralType */ #endif /* DOXYGEN */ /* Printf format used to display LargestIntegralType as a hexidecimal. */ #ifndef LargestIntegralTypePrintfFormat # ifdef _WIN32 # define LargestIntegralTypePrintfFormat "0x%I64x" # else # if __WORDSIZE == 64 # define LargestIntegralTypePrintfFormat "%#lx" # else # define LargestIntegralTypePrintfFormat "%#llx" # endif # endif /* _WIN32 */ #endif /* LargestIntegralTypePrintfFormat */ /* Printf format used to display LargestIntegralType as a decimal. */ #ifndef LargestIntegralTypePrintfFormatDecimal # ifdef _WIN32 # define LargestIntegralTypePrintfFormatDecimal "%I64u" # else # if __WORDSIZE == 64 # define LargestIntegralTypePrintfFormatDecimal "%lu" # else # define LargestIntegralTypePrintfFormatDecimal "%llu" # endif # endif /* _WIN32 */ #endif /* LargestIntegralTypePrintfFormat */ /* Perform an unsigned cast to LargestIntegralType. */ #define cast_to_largest_integral_type(value) \ ((LargestIntegralType)(value)) /* Smallest integral type capable of holding a pointer. */ #if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) # if defined(_WIN32) /* WIN32 is an ILP32 platform */ typedef unsigned int uintptr_t; # elif defined(_WIN64) typedef unsigned long int uintptr_t # else /* _WIN32 */ /* ILP32 and LP64 platforms */ # ifdef __WORDSIZE /* glibc */ # if __WORDSIZE == 64 typedef unsigned long int uintptr_t; # else typedef unsigned int uintptr_t; # endif /* __WORDSIZE == 64 */ # else /* __WORDSIZE */ # if defined(_LP64) || defined(_I32LPx) typedef unsigned long int uintptr_t; # else typedef unsigned int uintptr_t; # endif # endif /* __WORDSIZE */ # endif /* _WIN32 */ # define _UINTPTR_T # define _UINTPTR_T_DEFINED #endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */ /* Perform an unsigned cast to uintptr_t. */ #define cast_to_pointer_integral_type(value) \ ((uintptr_t)((size_t)(value))) /* Perform a cast of a pointer to LargestIntegralType */ #define cast_ptr_to_largest_integral_type(value) \ cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) /* GCC have printf type attribute check. */ #ifdef __GNUC__ #define CMOCKA_PRINTF_ATTRIBUTE(a,b) \ __attribute__ ((__format__ (__printf__, a, b))) #else #define CMOCKA_PRINTF_ATTRIBUTE(a,b) #endif /* __GNUC__ */ #if defined(__GNUC__) #define CMOCKA_DEPRECATED __attribute__ ((deprecated)) #elif defined(_MSC_VER) #define CMOCKA_DEPRECATED __declspec(deprecated) #else #define CMOCKA_DEPRECATED #endif #define WILL_RETURN_ALWAYS -1 #define WILL_RETURN_ONCE -2 /** * @defgroup cmocka_mock Mock Objects * @ingroup cmocka * * Mock objects mock objects are simulated objects that mimic the behavior of * real objects. Instead of calling the real objects, the tested object calls a * mock object that merely asserts that the correct methods were called, with * the expected parameters, in the correct order. * *
    *
  • will_return(function, value) - The will_return() macro * pushes a value onto a stack of mock values. This macro is intended to be * used by the unit test itself, while programming the behaviour of the mocked * object.
  • * *
  • mock() - the mock macro pops a value from a stack of * test values. The user of the mock() macro is the mocked object that uses it * to learn how it should behave.
  • *
* * Because the will_return() and mock() are intended to be used in pairs, the * cmocka library would fail the test if there are more values pushed onto the * stack using will_return() than consumed with mock() and vice-versa. * * The following unit test stub illustrates how would a unit test instruct the * mock object to return a particular value: * * @code * will_return(chef_cook, "hotdog"); * will_return(chef_cook, 0); * @endcode * * Now the mock object can check if the parameter it received is the parameter * which is expected by the test driver. This can be done the following way: * * @code * int chef_cook(const char *order, char **dish_out) * { * check_expected(order); * } * @endcode * * For a complete example please at a look * here. * * @{ */ #ifdef DOXYGEN /** * @brief Retrieve a return value of the current function. * * @return The value which was stored to return by this function. * * @see will_return() */ LargestIntegralType mock(void); #else #define mock() _mock(__func__, __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Retrieve a typed return value of the current function. * * The value would be casted to type internally to avoid having the * caller to do the cast manually. * * @param[in] #type The expected type of the return value * * @return The value which was stored to return by this function. * * @code * int param; * * param = mock_type(int); * @endcode * * @see will_return() * @see mock() * @see mock_ptr_type() */ #type mock_type(#type); #else #define mock_type(type) ((type) mock()) #endif #ifdef DOXYGEN /** * @brief Retrieve a typed return value of the current function. * * The value would be casted to type internally to avoid having the * caller to do the cast manually but also casted to uintptr_t to make * sure the result has a valid size to be used as a pointer. * * @param[in] #type The expected type of the return value * * @return The value which was stored to return by this function. * * @code * char *param; * * param = mock_ptr_type(char *); * @endcode * * @see will_return() * @see mock() * @see mock_type() */ type mock_ptr_type(#type); #else #define mock_ptr_type(type) ((type) (uintptr_t) mock()) #endif #ifdef DOXYGEN /** * @brief Store a value to be returned by mock() later. * * @param[in] #function The function which should return the given value. * * @param[in] value The value to be returned by mock(). * * @code * int return_integer(void) * { * return (int)mock(); * } * * static void test_integer_return(void **state) * { * will_return(return_integer, 42); * * assert_int_equal(my_function_calling_return_integer(), 42); * } * @endcode * * @see mock() * @see will_return_count() */ void will_return(#function, LargestIntegralType value); #else #define will_return(function, value) \ _will_return(#function, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), 1) #endif #ifdef DOXYGEN /** * @brief Store a value to be returned by mock() later. * * @param[in] #function The function which should return the given value. * * @param[in] value The value to be returned by mock(). * * @param[in] count The parameter indicates the number of times the value should * be returned by mock(). If count is set to -1, the value * will always be returned but must be returned at least once. * If count is set to -2, the value will always be returned * by mock(), but is not required to be returned. * * @see mock() */ void will_return_count(#function, LargestIntegralType value, int count); #else #define will_return_count(function, value, count) \ _will_return(#function, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) #endif #ifdef DOXYGEN /** * @brief Store a value that will be always returned by mock(). * * @param[in] #function The function which should return the given value. * * @param[in] #value The value to be returned by mock(). * * This is equivalent to: * @code * will_return_count(function, value, -1); * @endcode * * @see will_return_count() * @see mock() */ void will_return_always(#function, LargestIntegralType value); #else #define will_return_always(function, value) \ will_return_count(function, (value), WILL_RETURN_ALWAYS) #endif #ifdef DOXYGEN /** * @brief Store a value that may be always returned by mock(). * * This stores a value which will always be returned by mock() but is not * required to be returned by at least one call to mock(). Therefore, * in contrast to will_return_always() which causes a test failure if it * is not returned at least once, will_return_maybe() will never cause a test * to fail if its value is not returned. * * @param[in] #function The function which should return the given value. * * @param[in] #value The value to be returned by mock(). * * This is equivalent to: * @code * will_return_count(function, value, -2); * @endcode * * @see will_return_count() * @see mock() */ void will_return_maybe(#function, LargestIntegralType value); #else #define will_return_maybe(function, value) \ will_return_count(function, (value), WILL_RETURN_ONCE) #endif /** @} */ /** * @defgroup cmocka_param Checking Parameters * @ingroup cmocka * * Functionality to store expected values for mock function parameters. * * In addition to storing the return values of mock functions, cmocka provides * functionality to store expected values for mock function parameters using * the expect_*() functions provided. A mock function parameter can then be * validated using the check_expected() macro. * * Successive calls to expect_*() macros for a parameter queues values to check * the specified parameter. check_expected() checks a function parameter * against the next value queued using expect_*(), if the parameter check fails * a test failure is signalled. In addition if check_expected() is called and * no more parameter values are queued a test failure occurs. * * The following test stub illustrates how to do this. First is the the function * we call in the test driver: * * @code * static void test_driver(void **state) * { * expect_string(chef_cook, order, "hotdog"); * } * @endcode * * Now the chef_cook function can check if the parameter we got passed is the * parameter which is expected by the test driver. This can be done the * following way: * * @code * int chef_cook(const char *order, char **dish_out) * { * check_expected(order); * } * @endcode * * For a complete example please at a look at * here * * @{ */ /* * Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event * parameter is provided it must be allocated on the heap and doesn't need to * be deallocated by the caller. */ #ifdef DOXYGEN /** * @brief Add a custom parameter checking function. * * If the event parameter is NULL the event structure is allocated internally * by this function. If the parameter is provided it must be allocated on the * heap and doesn't need to be deallocated by the caller. * * @param[in] #function The function to add a custom parameter checking * function for. * * @param[in] #parameter The parameters passed to the function. * * @param[in] #check_function The check function to call. * * @param[in] check_data The data to pass to the check function. */ void expect_check(#function, #parameter, #check_function, const void *check_data); #else #define expect_check(function, parameter, check_function, check_data) \ _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ cast_to_largest_integral_type(check_data), NULL, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value is part of the provided * array. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value_array[] The array to check for the value. * * @see check_expected(). */ void expect_in_set(#function, #parameter, LargestIntegralType value_array[]); #else #define expect_in_set(function, parameter, value_array) \ expect_in_set_count(function, parameter, value_array, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value is part of the provided * array. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value_array[] The array to check for the value. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); #else #define expect_in_set_count(function, parameter, value_array, count) \ _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ sizeof(value_array) / sizeof((value_array)[0]), count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value is not part of the * provided array. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value_array[] The array to check for the value. * * @see check_expected(). */ void expect_not_in_set(#function, #parameter, LargestIntegralType value_array[]); #else #define expect_not_in_set(function, parameter, value_array) \ expect_not_in_set_count(function, parameter, value_array, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value is not part of the * provided array. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value_array[] The array to check for the value. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_not_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); #else #define expect_not_in_set_count(function, parameter, value_array, count) \ _expect_not_in_set( \ #function, #parameter, __FILE__, __LINE__, value_array, \ sizeof(value_array) / sizeof((value_array)[0]), count) #endif #ifdef DOXYGEN /** * @brief Add an event to check a parameter is inside a numerical range. * The check would succeed if minimum <= value <= maximum. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] minimum The lower boundary of the interval to check against. * * @param[in] maximum The upper boundary of the interval to check against. * * @see check_expected(). */ void expect_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); #else #define expect_in_range(function, parameter, minimum, maximum) \ expect_in_range_count(function, parameter, minimum, maximum, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to repeatedly check a parameter is inside a * numerical range. The check would succeed if minimum <= value <= maximum. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] minimum The lower boundary of the interval to check against. * * @param[in] maximum The upper boundary of the interval to check against. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); #else #define expect_in_range_count(function, parameter, minimum, maximum, count) \ _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ maximum, count) #endif #ifdef DOXYGEN /** * @brief Add an event to check a parameter is outside a numerical range. * The check would succeed if minimum > value > maximum. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] minimum The lower boundary of the interval to check against. * * @param[in] maximum The upper boundary of the interval to check against. * * @see check_expected(). */ void expect_not_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); #else #define expect_not_in_range(function, parameter, minimum, maximum) \ expect_not_in_range_count(function, parameter, minimum, maximum, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to repeatedly check a parameter is outside a * numerical range. The check would succeed if minimum > value > maximum. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] minimum The lower boundary of the interval to check against. * * @param[in] maximum The upper boundary of the interval to check against. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); #else #define expect_not_in_range_count(function, parameter, minimum, maximum, \ count) \ _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ minimum, maximum, count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if a parameter is the given value. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value The value to check. * * @see check_expected(). */ void expect_value(#function, #parameter, LargestIntegralType value); #else #define expect_value(function, parameter, value) \ expect_value_count(function, parameter, value, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to repeatedly check if a parameter is the given value. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value The value to check. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count); #else #define expect_value_count(function, parameter, value, count) \ _expect_value(#function, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if a parameter isn't the given value. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value The value to check. * * @see check_expected(). */ void expect_not_value(#function, #parameter, LargestIntegralType value); #else #define expect_not_value(function, parameter, value) \ expect_not_value_count(function, parameter, value, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to repeatedly check if a parameter isn't the given value. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] value The value to check. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_not_value_count(#function, #parameter, LargestIntegralType value, size_t count); #else #define expect_not_value_count(function, parameter, value, count) \ _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value is equal to the * provided string. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] string The string value to compare. * * @see check_expected(). */ void expect_string(#function, #parameter, const char *string); #else #define expect_string(function, parameter, string) \ expect_string_count(function, parameter, string, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value is equal to the * provided string. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] string The string value to compare. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_string_count(#function, #parameter, const char *string, size_t count); #else #define expect_string_count(function, parameter, string, count) \ _expect_string(#function, #parameter, __FILE__, __LINE__, \ (const char*)(string), count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value isn't equal to the * provided string. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] string The string value to compare. * * @see check_expected(). */ void expect_not_string(#function, #parameter, const char *string); #else #define expect_not_string(function, parameter, string) \ expect_not_string_count(function, parameter, string, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter value isn't equal to the * provided string. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] string The string value to compare. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_not_string_count(#function, #parameter, const char *string, size_t count); #else #define expect_not_string_count(function, parameter, string, count) \ _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ (const char*)(string), count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter does match an area of memory. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] memory The memory to compare. * * @param[in] size The size of the memory to compare. * * @see check_expected(). */ void expect_memory(#function, #parameter, void *memory, size_t size); #else #define expect_memory(function, parameter, memory, size) \ expect_memory_count(function, parameter, memory, size, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to repeatedly check if the parameter does match an area * of memory. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] memory The memory to compare. * * @param[in] size The size of the memory to compare. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count); #else #define expect_memory_count(function, parameter, memory, size, count) \ _expect_memory(#function, #parameter, __FILE__, __LINE__, \ (const void*)(memory), size, count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if the parameter doesn't match an area of * memory. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] memory The memory to compare. * * @param[in] size The size of the memory to compare. * * @see check_expected(). */ void expect_not_memory(#function, #parameter, void *memory, size_t size); #else #define expect_not_memory(function, parameter, memory, size) \ expect_not_memory_count(function, parameter, memory, size, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to repeatedly check if the parameter doesn't match an * area of memory. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] memory The memory to compare. * * @param[in] size The size of the memory to compare. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count); #else #define expect_not_memory_count(function, parameter, memory, size, count) \ _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ (const void*)(memory), size, count) #endif #ifdef DOXYGEN /** * @brief Add an event to check if a parameter (of any value) has been passed. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @see check_expected(). */ void expect_any(#function, #parameter); #else #define expect_any(function, parameter) \ expect_any_count(function, parameter, 1) #endif #ifdef DOXYGEN /** * @brief Add an event to repeatedly check if a parameter (of any value) has * been passed. * * The event is triggered by calling check_expected() in the mocked function. * * @param[in] #function The function to add the check for. * * @param[in] #parameter The name of the parameter passed to the function. * * @param[in] count The count parameter returns the number of times the value * should be returned by check_expected(). If count is set * to -1 the value will always be returned. * * @see check_expected(). */ void expect_any_count(#function, #parameter, size_t count); #else #define expect_any_count(function, parameter, count) \ _expect_any(#function, #parameter, __FILE__, __LINE__, count) #endif #ifdef DOXYGEN /** * @brief Determine whether a function parameter is correct. * * This ensures the next value queued by one of the expect_*() macros matches * the specified variable. * * This function needs to be called in the mock object. * * @param[in] #parameter The parameter to check. */ void check_expected(#parameter); #else #define check_expected(parameter) \ _check_expected(__func__, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(parameter)) #endif #ifdef DOXYGEN /** * @brief Determine whether a function parameter is correct. * * This ensures the next value queued by one of the expect_*() macros matches * the specified variable. * * This function needs to be called in the mock object. * * @param[in] #parameter The pointer to check. */ void check_expected_ptr(#parameter); #else #define check_expected_ptr(parameter) \ _check_expected(__func__, #parameter, __FILE__, __LINE__, \ cast_ptr_to_largest_integral_type(parameter)) #endif /** @} */ /** * @defgroup cmocka_asserts Assert Macros * @ingroup cmocka * * This is a set of useful assert macros like the standard C libary's * assert(3) macro. * * On an assertion failure a cmocka assert macro will write the failure to the * standard error stream and signal a test failure. Due to limitations of the C * language the general C standard library assert() and cmocka's assert_true() * and assert_false() macros can only display the expression that caused the * assert failure. cmocka's type specific assert macros, assert_{type}_equal() * and assert_{type}_not_equal(), display the data that caused the assertion * failure which increases data visibility aiding debugging of failing test * cases. * * @{ */ #ifdef DOXYGEN /** * @brief Assert that the given expression is true. * * The function prints an error message to standard error and terminates the * test by calling fail() if expression is false (i.e., compares equal to * zero). * * @param[in] expression The expression to evaluate. * * @see assert_int_equal() * @see assert_string_equal() */ void assert_true(scalar expression); #else #define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the given expression is false. * * The function prints an error message to standard error and terminates the * test by calling fail() if expression is true. * * @param[in] expression The expression to evaluate. * * @see assert_int_equal() * @see assert_string_equal() */ void assert_false(scalar expression); #else #define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the return_code is greater than or equal to 0. * * The function prints an error message to standard error and terminates the * test by calling fail() if the return code is smaller than 0. If the function * you check sets an errno if it fails you can pass it to the function and * it will be printed as part of the error message. * * @param[in] rc The return code to evaluate. * * @param[in] error Pass errno here or 0. */ void assert_return_code(int rc, int error); #else #define assert_return_code(rc, error) \ _assert_return_code(cast_to_largest_integral_type(rc), \ sizeof(rc), \ cast_to_largest_integral_type(error), \ #rc, __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the given pointer is non-NULL. * * The function prints an error message to standard error and terminates the * test by calling fail() if the pointer is NULL. * * @param[in] pointer The pointer to evaluate. * * @see assert_null() */ void assert_non_null(void *pointer); #else #define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the given pointer is NULL. * * The function prints an error message to standard error and terminates the * test by calling fail() if the pointer is non-NULL. * * @param[in] pointer The pointer to evaluate. * * @see assert_non_null() */ void assert_null(void *pointer); #else #define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given pointers are equal. * * The function prints an error message and terminates the test by calling * fail() if the pointers are not equal. * * @param[in] a The first pointer to compare. * * @param[in] b The pointer to compare against the first one. */ void assert_ptr_equal(void *a, void *b); #else #define assert_ptr_equal(a, b) \ _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ cast_ptr_to_largest_integral_type(b), \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given pointers are not equal. * * The function prints an error message and terminates the test by calling * fail() if the pointers are equal. * * @param[in] a The first pointer to compare. * * @param[in] b The pointer to compare against the first one. */ void assert_ptr_not_equal(void *a, void *b); #else #define assert_ptr_not_equal(a, b) \ _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \ cast_ptr_to_largest_integral_type(b), \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given integers are equal. * * The function prints an error message to standard error and terminates the * test by calling fail() if the integers are not equal. * * @param[in] a The first integer to compare. * * @param[in] b The integer to compare against the first one. */ void assert_int_equal(int a, int b); #else #define assert_int_equal(a, b) \ _assert_int_equal(cast_to_largest_integral_type(a), \ cast_to_largest_integral_type(b), \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given integers are not equal. * * The function prints an error message to standard error and terminates the * test by calling fail() if the integers are equal. * * @param[in] a The first integer to compare. * * @param[in] b The integer to compare against the first one. * * @see assert_int_equal() */ void assert_int_not_equal(int a, int b); #else #define assert_int_not_equal(a, b) \ _assert_int_not_equal(cast_to_largest_integral_type(a), \ cast_to_largest_integral_type(b), \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given strings are equal. * * The function prints an error message to standard error and terminates the * test by calling fail() if the strings are not equal. * * @param[in] a The string to check. * * @param[in] b The other string to compare. */ void assert_string_equal(const char *a, const char *b); #else #define assert_string_equal(a, b) \ _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given strings are not equal. * * The function prints an error message to standard error and terminates the * test by calling fail() if the strings are equal. * * @param[in] a The string to check. * * @param[in] b The other string to compare. */ void assert_string_not_equal(const char *a, const char *b); #else #define assert_string_not_equal(a, b) \ _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given areas of memory are equal, otherwise fail. * * The function prints an error message to standard error and terminates the * test by calling fail() if the memory is not equal. * * @param[in] a The first memory area to compare * (interpreted as unsigned char). * * @param[in] b The second memory area to compare * (interpreted as unsigned char). * * @param[in] size The first n bytes of the memory areas to compare. */ void assert_memory_equal(const void *a, const void *b, size_t size); #else #define assert_memory_equal(a, b, size) \ _assert_memory_equal((const void*)(a), (const void*)(b), size, __FILE__, \ __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the two given areas of memory are not equal. * * The function prints an error message to standard error and terminates the * test by calling fail() if the memory is equal. * * @param[in] a The first memory area to compare * (interpreted as unsigned char). * * @param[in] b The second memory area to compare * (interpreted as unsigned char). * * @param[in] size The first n bytes of the memory areas to compare. */ void assert_memory_not_equal(const void *a, const void *b, size_t size); #else #define assert_memory_not_equal(a, b, size) \ _assert_memory_not_equal((const void*)(a), (const void*)(b), size, \ __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the specified value is not smaller than the minimum * and and not greater than the maximum. * * The function prints an error message to standard error and terminates the * test by calling fail() if value is not in range. * * @param[in] value The value to check. * * @param[in] minimum The minimum value allowed. * * @param[in] maximum The maximum value allowed. */ void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); #else #define assert_in_range(value, minimum, maximum) \ _assert_in_range( \ cast_to_largest_integral_type(value), \ cast_to_largest_integral_type(minimum), \ cast_to_largest_integral_type(maximum), __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the specified value is smaller than the minimum or * greater than the maximum. * * The function prints an error message to standard error and terminates the * test by calling fail() if value is in range. * * @param[in] value The value to check. * * @param[in] minimum The minimum value to compare. * * @param[in] maximum The maximum value to compare. */ void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); #else #define assert_not_in_range(value, minimum, maximum) \ _assert_not_in_range( \ cast_to_largest_integral_type(value), \ cast_to_largest_integral_type(minimum), \ cast_to_largest_integral_type(maximum), __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the specified value is within a set. * * The function prints an error message to standard error and terminates the * test by calling fail() if value is not within a set. * * @param[in] value The value to look up * * @param[in] values[] The array to check for the value. * * @param[in] count The size of the values array. */ void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); #else #define assert_in_set(value, values, number_of_values) \ _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Assert that the specified value is not within a set. * * The function prints an error message to standard error and terminates the * test by calling fail() if value is within a set. * * @param[in] value The value to look up * * @param[in] values[] The array to check for the value. * * @param[in] count The size of the values array. */ void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); #else #define assert_not_in_set(value, values, number_of_values) \ _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) #endif /** @} */ /** * @defgroup cmocka_call_order Call Ordering * @ingroup cmocka * * It is often beneficial to make sure that functions are called in an * order. This is independent of mock returns and parameter checking as both * of the aforementioned do not check the order in which they are called from * different functions. * *
    *
  • expect_function_call(function) - The * expect_function_call() macro pushes an expectation onto the stack of * expected calls.
  • * *
  • function_called() - pops a value from the stack of * expected calls. function_called() is invoked within the mock object * that uses it. *
* * expect_function_call() and function_called() are intended to be used in * pairs. Cmocka will fail a test if there are more or less expected calls * created (e.g. expect_function_call()) than consumed with function_called(). * There are provisions such as ignore_function_calls() which allow this * restriction to be circumvented in tests where mock calls for the code under * test are not the focus of the test. * * The following example illustrates how a unit test instructs cmocka * to expect a function_called() from a particular mock, * chef_sing(): * * @code * void chef_sing(void); * * void code_under_test() * { * chef_sing(); * } * * void some_test(void **state) * { * expect_function_call(chef_sing); * code_under_test(); * } * @endcode * * The implementation of the mock then must check whether it was meant to * be called by invoking function_called(): * * @code * void chef_sing() * { * function_called(); * } * @endcode * * @{ */ #ifdef DOXYGEN /** * @brief Check that current mocked function is being called in the expected * order * * @see expect_function_call() */ void function_called(void); #else #define function_called() _function_called(__func__, __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Store expected call(s) to a mock to be checked by function_called() * later. * * @param[in] #function The function which should should be called * * @param[in] times number of times this mock must be called * * @see function_called() */ void expect_function_calls(#function, const int times); #else #define expect_function_calls(function, times) \ _expect_function_call(#function, __FILE__, __LINE__, times) #endif #ifdef DOXYGEN /** * @brief Store expected single call to a mock to be checked by * function_called() later. * * @param[in] #function The function which should should be called * * @see function_called() */ void expect_function_call(#function); #else #define expect_function_call(function) \ _expect_function_call(#function, __FILE__, __LINE__, 1) #endif #ifdef DOXYGEN /** * @brief Expects function_called() from given mock at least once * * @param[in] #function The function which should should be called * * @see function_called() */ void expect_function_call_any(#function); #else #define expect_function_call_any(function) \ _expect_function_call(#function, __FILE__, __LINE__, -1) #endif #ifdef DOXYGEN /** * @brief Ignores function_called() invocations from given mock function. * * @param[in] #function The function which should should be called * * @see function_called() */ void ignore_function_calls(#function); #else #define ignore_function_calls(function) \ _expect_function_call(#function, __FILE__, __LINE__, -2) #endif /** @} */ /** * @defgroup cmocka_exec Running Tests * @ingroup cmocka * * This is the way tests are executed with CMocka. * * The following example illustrates this macro's use with the unit_test macro. * * @code * void Test0(void **state); * void Test1(void **state); * * int main(void) * { * const struct CMUnitTest tests[] = { * cmocka_unit_test(Test0), * cmocka_unit_test(Test1), * }; * * return cmocka_run_group_tests(tests, NULL, NULL); * } * @endcode * * @{ */ #ifdef DOXYGEN /** * @brief Forces the test to fail immediately and quit. */ void fail(void); #else #define fail() _fail(__FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Forces the test to not be executed, but marked as skipped */ void skip(void); #else #define skip() _skip(__FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Forces the test to fail immediately and quit, printing the reason. * * @code * fail_msg("This is some error message for test"); * @endcode * * or * * @code * char *error_msg = "This is some error message for test"; * fail_msg("%s", error_msg); * @endcode */ void fail_msg(const char *msg, ...); #else #define fail_msg(msg, ...) do { \ print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ fail(); \ } while (0) #endif #ifdef DOXYGEN /** * @brief Generic method to run a single test. * * @deprecated This function was deprecated in favor of cmocka_run_group_tests * * @param[in] #function The function to test. * * @return 0 on success, 1 if an error occured. * * @code * // A test case that does nothing and succeeds. * void null_test_success(void **state) { * } * * int main(void) { * return run_test(null_test_success); * } * @endcode */ int run_test(#function); #else #define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL) #endif static inline void _unit_test_dummy(void **state) { (void)state; } /** Initializes a UnitTest structure. * * @deprecated This function was deprecated in favor of cmocka_unit_test */ #define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST } #define _unit_test_setup(test, setup) \ { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } /** Initializes a UnitTest structure with a setup function. * * @deprecated This function was deprecated in favor of cmocka_unit_test_setup */ #define unit_test_setup(test, setup) \ _unit_test_setup(test, setup), \ unit_test(test), \ _unit_test_teardown(test, _unit_test_dummy) #define _unit_test_teardown(test, teardown) \ { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } /** Initializes a UnitTest structure with a teardown function. * * @deprecated This function was deprecated in favor of cmocka_unit_test_teardown */ #define unit_test_teardown(test, teardown) \ _unit_test_setup(test, _unit_test_dummy), \ unit_test(test), \ _unit_test_teardown(test, teardown) /** Initializes a UnitTest structure for a group setup function. * * @deprecated This function was deprecated in favor of cmocka_run_group_tests */ #define group_test_setup(setup) \ { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP } /** Initializes a UnitTest structure for a group teardown function. * * @deprecated This function was deprecated in favor of cmocka_run_group_tests */ #define group_test_teardown(teardown) \ { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN } /** * Initialize an array of UnitTest structures with a setup function for a test * and a teardown function. Either setup or teardown can be NULL. * * @deprecated This function was deprecated in favor of * cmocka_unit_test_setup_teardown */ #define unit_test_setup_teardown(test, setup, teardown) \ _unit_test_setup(test, setup), \ unit_test(test), \ _unit_test_teardown(test, teardown) /** Initializes a CMUnitTest structure. */ #define cmocka_unit_test(f) { #f, f, NULL, NULL, NULL } /** Initializes a CMUnitTest structure with a setup function. */ #define cmocka_unit_test_setup(f, setup) { #f, f, setup, NULL, NULL } /** Initializes a CMUnitTest structure with a teardown function. */ #define cmocka_unit_test_teardown(f, teardown) { #f, f, NULL, teardown, NULL } /** * Initialize an array of CMUnitTest structures with a setup function for a test * and a teardown function. Either setup or teardown can be NULL. */ #define cmocka_unit_test_setup_teardown(f, setup, teardown) { #f, f, setup, teardown, NULL } /** * Initialize a CMUnitTest structure with given initial state. It will be passed * to test function as an argument later. It can be used when test state does * not need special initialization or was initialized already. * @note If the group setup function initialized the state already, it won't be * overridden by the initial state defined here. */ #define cmocka_unit_test_prestate(f, state) { #f, f, NULL, NULL, state } /** * Initialize a CMUnitTest structure with given initial state, setup and * teardown function. Any of these values can be NULL. Initial state is passed * later to setup function, or directly to test if none was given. * @note If the group setup function initialized the state already, it won't be * overridden by the initial state defined here. */ #define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state } #define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof((tests)[0])) #define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0])) #ifdef DOXYGEN /** * @brief Run tests specified by an array of CMUnitTest structures. * * @param[in] group_tests[] The array of unit tests to execute. * * @param[in] group_setup The setup function which should be called before * all unit tests are executed. * * @param[in] group_teardown The teardown function to be called after all * tests have finished. * * @return 0 on success, or the number of failed tests. * * @code * static int setup(void **state) { * int *answer = malloc(sizeof(int)); * if (*answer == NULL) { * return -1; * } * *answer = 42; * * *state = answer; * * return 0; * } * * static int teardown(void **state) { * free(*state); * * return 0; * } * * static void null_test_success(void **state) { * (void) state; * } * * static void int_test_success(void **state) { * int *answer = *state; * assert_int_equal(*answer, 42); * } * * int main(void) { * const struct CMUnitTest tests[] = { * cmocka_unit_test(null_test_success), * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), * }; * * return cmocka_run_group_tests(tests, NULL, NULL); * } * @endcode * * @see cmocka_unit_test * @see cmocka_unit_test_setup * @see cmocka_unit_test_teardown * @see cmocka_unit_test_setup_teardown */ int cmocka_run_group_tests(const struct CMUnitTest group_tests[], CMFixtureFunction group_setup, CMFixtureFunction group_teardown); #else # define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \ _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) #endif #ifdef DOXYGEN /** * @brief Run tests specified by an array of CMUnitTest structures and specify * a name. * * @param[in] group_name The name of the group test. * * @param[in] group_tests[] The array of unit tests to execute. * * @param[in] group_setup The setup function which should be called before * all unit tests are executed. * * @param[in] group_teardown The teardown function to be called after all * tests have finished. * * @return 0 on success, or the number of failed tests. * * @code * static int setup(void **state) { * int *answer = malloc(sizeof(int)); * if (*answer == NULL) { * return -1; * } * *answer = 42; * * *state = answer; * * return 0; * } * * static int teardown(void **state) { * free(*state); * * return 0; * } * * static void null_test_success(void **state) { * (void) state; * } * * static void int_test_success(void **state) { * int *answer = *state; * assert_int_equal(*answer, 42); * } * * int main(void) { * const struct CMUnitTest tests[] = { * cmocka_unit_test(null_test_success), * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), * }; * * return cmocka_run_group_tests_name("success_test", tests, NULL, NULL); * } * @endcode * * @see cmocka_unit_test * @see cmocka_unit_test_setup * @see cmocka_unit_test_teardown * @see cmocka_unit_test_setup_teardown */ int cmocka_run_group_tests_name(const char *group_name, const struct CMUnitTest group_tests[], CMFixtureFunction group_setup, CMFixtureFunction group_teardown); #else # define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \ _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) #endif /** @} */ /** * @defgroup cmocka_alloc Dynamic Memory Allocation * @ingroup cmocka * * Memory leaks, buffer overflows and underflows can be checked using cmocka. * * To test for memory leaks, buffer overflows and underflows a module being * tested by cmocka should replace calls to malloc(), calloc() and free() to * test_malloc(), test_calloc() and test_free() respectively. Each time a block * is deallocated using test_free() it is checked for corruption, if a corrupt * block is found a test failure is signalled. All blocks allocated using the * test_*() allocation functions are tracked by the cmocka library. When a test * completes if any allocated blocks (memory leaks) remain they are reported * and a test failure is signalled. * * For simplicity cmocka currently executes all tests in one process. Therefore * all test cases in a test application share a single address space which * means memory corruption from a single test case could potentially cause the * test application to exit prematurely. * * @{ */ #ifdef DOXYGEN /** * @brief Test function overriding malloc. * * @param[in] size The bytes which should be allocated. * * @return A pointer to the allocated memory or NULL on error. * * @code * #ifdef UNIT_TESTING * extern void* _test_malloc(const size_t size, const char* file, const int line); * * #define malloc(size) _test_malloc(size, __FILE__, __LINE__) * #endif * * void leak_memory() { * int * const temporary = (int*)malloc(sizeof(int)); * *temporary = 0; * } * @endcode * * @see malloc(3) */ void *test_malloc(size_t size); #else #define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Test function overriding calloc. * * The memory is set to zero. * * @param[in] nmemb The number of elements for an array to be allocated. * * @param[in] size The size in bytes of each array element to allocate. * * @return A pointer to the allocated memory, NULL on error. * * @see calloc(3) */ void *test_calloc(size_t nmemb, size_t size); #else #define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Test function overriding realloc which detects buffer overruns * and memoery leaks. * * @param[in] ptr The memory block which should be changed. * * @param[in] size The bytes which should be allocated. * * @return The newly allocated memory block, NULL on error. */ void *test_realloc(void *ptr, size_t size); #else #define test_realloc(ptr, size) _test_realloc(ptr, size, __FILE__, __LINE__) #endif #ifdef DOXYGEN /** * @brief Test function overriding free(3). * * @param[in] ptr The pointer to the memory space to free. * * @see free(3). */ void test_free(void *ptr); #else #define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) #endif /* Redirect malloc, calloc and free to the unit test allocators. */ #ifdef UNIT_TESTING #define malloc test_malloc #define realloc test_realloc #define calloc test_calloc #define free test_free #endif /* UNIT_TESTING */ /** @} */ /** * @defgroup cmocka_mock_assert Standard Assertions * @ingroup cmocka * * How to handle assert(3) of the standard C library. * * Runtime assert macros like the standard C library's assert() should be * redefined in modules being tested to use cmocka's mock_assert() function. * Normally mock_assert() signals a test failure. If a function is called using * the expect_assert_failure() macro, any calls to mock_assert() within the * function will result in the execution of the test. If no calls to * mock_assert() occur during the function called via expect_assert_failure() a * test failure is signalled. * * @{ */ /** * @brief Function to replace assert(3) in tested code. * * In conjuction with check_assert() it's possible to determine whether an * assert condition has failed without stopping a test. * * @param[in] result The expression to assert. * * @param[in] expression The expression as string. * * @param[in] file The file mock_assert() is called. * * @param[in] line The line mock_assert() is called. * * @code * #ifdef UNIT_TESTING * extern void mock_assert(const int result, const char* const expression, * const char * const file, const int line); * * #undef assert * #define assert(expression) \ * mock_assert((int)(expression), #expression, __FILE__, __LINE__); * #endif * * void increment_value(int * const value) { * assert(value); * (*value) ++; * } * @endcode * * @see assert(3) * @see expect_assert_failure */ void mock_assert(const int result, const char* const expression, const char * const file, const int line); #ifdef DOXYGEN /** * @brief Ensure that mock_assert() is called. * * If mock_assert() is called the assert expression string is returned. * * @param[in] fn_call The function will will call mock_assert(). * * @code * #define assert mock_assert * * void showmessage(const char *message) { * assert(message); * } * * int main(int argc, const char* argv[]) { * expect_assert_failure(show_message(NULL)); * printf("succeeded\n"); * return 0; * } * @endcode * */ void expect_assert_failure(function fn_call); #else #define expect_assert_failure(function_call) \ { \ const int result = setjmp(global_expect_assert_env); \ global_expecting_assert = 1; \ if (result) { \ print_message("Expected assertion %s occurred\n", \ global_last_failed_assert); \ global_expecting_assert = 0; \ } else { \ function_call ; \ global_expecting_assert = 0; \ print_error("Expected assert in %s\n", #function_call); \ _fail(__FILE__, __LINE__); \ } \ } #endif /** @} */ /* Function prototype for setup, test and teardown functions. */ typedef void (*UnitTestFunction)(void **state); /* Function that determines whether a function parameter value is correct. */ typedef int (*CheckParameterValue)(const LargestIntegralType value, const LargestIntegralType check_value_data); /* Type of the unit test function. */ typedef enum UnitTestFunctionType { UNIT_TEST_FUNCTION_TYPE_TEST = 0, UNIT_TEST_FUNCTION_TYPE_SETUP, UNIT_TEST_FUNCTION_TYPE_TEARDOWN, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, } UnitTestFunctionType; /* * Stores a unit test function with its name and type. * NOTE: Every setup function must be paired with a teardown function. It's * possible to specify NULL function pointers. */ typedef struct UnitTest { const char* name; UnitTestFunction function; UnitTestFunctionType function_type; } UnitTest; typedef struct GroupTest { UnitTestFunction setup; UnitTestFunction teardown; const UnitTest *tests; const size_t number_of_tests; } GroupTest; /* Function prototype for test functions. */ typedef void (*CMUnitTestFunction)(void **state); /* Function prototype for setup and teardown functions. */ typedef int (*CMFixtureFunction)(void **state); struct CMUnitTest { const char *name; CMUnitTestFunction test_func; CMFixtureFunction setup_func; CMFixtureFunction teardown_func; void *initial_state; }; /* Location within some source code. */ typedef struct SourceLocation { const char* file; int line; } SourceLocation; /* Event that's called to check a parameter value. */ typedef struct CheckParameterEvent { SourceLocation location; const char *parameter_name; CheckParameterValue check_value; LargestIntegralType check_value_data; } CheckParameterEvent; /* Used by expect_assert_failure() and mock_assert(). */ extern int global_expecting_assert; extern jmp_buf global_expect_assert_env; extern const char * global_last_failed_assert; /* Retrieves a value for the given function, as set by "will_return". */ LargestIntegralType _mock(const char * const function, const char* const file, const int line); void _expect_function_call( const char * const function_name, const char * const file, const int line, const int count); void _function_called(const char * const function, const char* const file, const int line); void _expect_check( const char* const function, const char* const parameter, const char* const file, const int line, const CheckParameterValue check_function, const LargestIntegralType check_data, CheckParameterEvent * const event, const int count); void _expect_in_set( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_not_in_set( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_in_range( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count); void _expect_not_in_range( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count); void _expect_value( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType value, const int count); void _expect_not_value( const char* const function, const char* const parameter, const char* const file, const int line, const LargestIntegralType value, const int count); void _expect_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, const int count); void _expect_not_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, const int count); void _expect_memory( const char* const function, const char* const parameter, const char* const file, const int line, const void* const memory, const size_t size, const int count); void _expect_not_memory( const char* const function, const char* const parameter, const char* const file, const int line, const void* const memory, const size_t size, const int count); void _expect_any( const char* const function, const char* const parameter, const char* const file, const int line, const int count); void _check_expected( const char * const function_name, const char * const parameter_name, const char* file, const int line, const LargestIntegralType value); void _will_return(const char * const function_name, const char * const file, const int line, const LargestIntegralType value, const int count); void _assert_true(const LargestIntegralType result, const char* const expression, const char * const file, const int line); void _assert_return_code(const LargestIntegralType result, size_t rlen, const LargestIntegralType error, const char * const expression, const char * const file, const int line); void _assert_int_equal( const LargestIntegralType a, const LargestIntegralType b, const char * const file, const int line); void _assert_int_not_equal( const LargestIntegralType a, const LargestIntegralType b, const char * const file, const int line); void _assert_string_equal(const char * const a, const char * const b, const char * const file, const int line); void _assert_string_not_equal(const char * const a, const char * const b, const char *file, const int line); void _assert_memory_equal(const void * const a, const void * const b, const size_t size, const char* const file, const int line); void _assert_memory_not_equal(const void * const a, const void * const b, const size_t size, const char* const file, const int line); void _assert_in_range( const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char* const file, const int line); void _assert_not_in_range( const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char* const file, const int line); void _assert_in_set( const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char* const file, const int line); void _assert_not_in_set( const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char* const file, const int line); void* _test_malloc(const size_t size, const char* file, const int line); void* _test_realloc(void *ptr, const size_t size, const char* file, const int line); void* _test_calloc(const size_t number_of_elements, const size_t size, const char* file, const int line); void _test_free(void* const ptr, const char* file, const int line); void _fail(const char * const file, const int line); void _skip(const char * const file, const int line); int _run_test( const char * const function_name, const UnitTestFunction Function, void ** const volatile state, const UnitTestFunctionType function_type, const void* const heap_check_point); CMOCKA_DEPRECATED int _run_tests(const UnitTest * const tests, const size_t number_of_tests); CMOCKA_DEPRECATED int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests); /* Test runner */ int _cmocka_run_group_tests(const char *group_name, const struct CMUnitTest * const tests, const size_t num_tests, CMFixtureFunction group_setup, CMFixtureFunction group_teardown); /* Standard output and error print methods. */ void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); enum cm_message_output { CM_OUTPUT_STDOUT, CM_OUTPUT_SUBUNIT, CM_OUTPUT_TAP, CM_OUTPUT_XML, }; /** * @brief Function to set the output format for a test. * * 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. * * @param[in] output The output format to use for the test. * */ void cmocka_set_message_output(enum cm_message_output output); /** * @brief Set a pattern to only run the test matching the pattern. * * This allows to filter tests and only run the ones matching the pattern. Thep * pattern can include two wildards. The first is '*', a wildcard that matches * zero or more characters, or ‘?’, a wildcard that matches exactly one * character. * * @param[in] pattern The pattern to match, e.g. "test_wurst*" */ void cmocka_set_test_filter(const char *pattern); /** @} */ #endif /* CMOCKA_H_ */ ldb-2.0.8/third_party/cmocka/cmocka_private.h0000660000000000000000000000760613100601766021155 0ustar rootroot00000000000000/* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CMOCKA_PRIVATE_H_ #define CMOCKA_PRIVATE_H_ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef _WIN32 #include # ifdef _MSC_VER # include /* _snprintf */ # undef inline # define inline __inline # ifndef va_copy # define va_copy(dest, src) (dest = src) # endif # define strcasecmp _stricmp # define strncasecmp _strnicmp # if defined(HAVE__SNPRINTF_S) # undef snprintf # define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__) # else /* HAVE__SNPRINTF_S */ # if defined(HAVE__SNPRINTF) # undef snprintf # define snprintf _snprintf # else /* HAVE__SNPRINTF */ # if !defined(HAVE_SNPRINTF) # error "no snprintf compatible function found" # endif /* HAVE_SNPRINTF */ # endif /* HAVE__SNPRINTF */ # endif /* HAVE__SNPRINTF_S */ # if defined(HAVE__VSNPRINTF_S) # undef vsnprintf # define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v)) # else /* HAVE__VSNPRINTF_S */ # if defined(HAVE__VSNPRINTF) # undef vsnprintf # define vsnprintf _vsnprintf # else # if !defined(HAVE_VSNPRINTF) # error "No vsnprintf compatible function found" # endif /* HAVE_VSNPRINTF */ # endif /* HAVE__VSNPRINTF */ # endif /* HAVE__VSNPRINTF_S */ # endif /* _MSC_VER */ /* * Backwards compatibility with headers shipped with Visual Studio 2005 and * earlier. */ WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); #ifndef PRIdS # define PRIdS "Id" #endif #ifndef PRIu64 # define PRIu64 "I64u" #endif #ifndef PRIuMAX # define PRIuMAX PRIu64 #endif #ifndef PRIxMAX #define PRIxMAX "I64x" #endif #ifndef PRIXMAX #define PRIXMAX "I64X" #endif #else /* _WIN32 */ #ifndef __PRI64_PREFIX # if __WORDSIZE == 64 # define __PRI64_PREFIX "l" # else # define __PRI64_PREFIX "ll" # endif #endif #ifndef PRIdS # define PRIdS "zd" #endif #ifndef PRIu64 # define PRIu64 __PRI64_PREFIX "u" #endif #ifndef PRIuMAX # define PRIuMAX __PRI64_PREFIX "u" #endif #ifndef PRIxMAX #define PRIxMAX __PRI64_PREFIX "x" #endif #ifndef PRIXMAX #define PRIXMAX __PRI64_PREFIX "X" #endif #endif /* _WIN32 */ /** Free memory space */ #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) /** Zero a structure */ #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) /** Zero a structure given a pointer to the structure */ #define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) /** Get the size of an array */ #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) /** Overwrite the complete string with 'X' */ #define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0) /** * This is a hack to fix warnings. The idea is to use this everywhere that we * get the "discarding const" warning by the compiler. That doesn't actually * fix the real issue, but marks the place and you can search the code for * discard_const. * * Please use this macro only when there is no other way to fix the warning. * We should use this function in only in a very few places. * * Also, please call this via the discard_const_p() macro interface, as that * makes the return type safe. */ #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) /** * Type-safe version of discard_const */ #define discard_const_p(type, ptr) ((type *)discard_const(ptr)) #endif /* CMOCKA_PRIVATE_H_ */ ldb-2.0.8/third_party/cmocka/wscript0000660000000000000000000000112313573675414017436 0ustar rootroot00000000000000#!/usr/bin/env python from waflib import Options def configure(conf): conf.CHECK_FUNCS('longjmp siglongjmp') if conf.CHECK_CMOCKA(): conf.define('USING_SYSTEM_CMOCKA', 1) def build(bld): if bld.CONFIG_SET('USING_SYSTEM_CMOCKA'): return extra_libs='' # Link to librt if needed for clock_gettime() if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' bld.SAMBA_LIBRARY('cmocka', source='cmocka.c', deps=extra_libs, allow_warnings=True, private_library=True) ldb-2.0.8/buildtools/README0000660000000000000000000000056212406075657015275 0ustar rootroot00000000000000See http://code.google.com/p/waf/ for more information on waf You can get a svn copy of the upstream source with: svn checkout http://waf.googlecode.com/svn/trunk/ waf-read-only Samba currently uses waf 1.5, which can be found at: http://waf.googlecode.com/svn/branches/waf-1.5 To update the current copy of waf, use the update-waf.sh script in this directory. ldb-2.0.8/buildtools/bin/waf0000770000000000000000000001037413573675413015673 0ustar rootroot00000000000000#!/usr/bin/env python3 # encoding: latin-1 # Thomas Nagy, 2005-2018 # """ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ import os, sys, inspect VERSION="2.0.18" REVISION="x" GIT="x" INSTALL="x" C1='x' C2='x' C3='x' cwd = os.getcwd() join = os.path.join if sys.hexversion<0x206000f: raise ImportError('Python >= 2.6 is required to create the waf file') WAF='waf' def b(x): return x if sys.hexversion>0x300000f: WAF='waf3' def b(x): return x.encode() def err(m): print(('\033[91mError: %s\033[0m' % m)) sys.exit(1) def unpack_wafdir(dir, src): f = open(src,'rb') c = 'corrupt archive (%d)' while 1: line = f.readline() if not line: err('run waf-light from a folder containing waflib') if line == b('#==>\n'): txt = f.readline() if not txt: err(c % 1) if f.readline() != b('#<==\n'): err(c % 2) break if not txt: err(c % 3) txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) import shutil, tarfile try: shutil.rmtree(dir) except OSError: pass try: for x in ('Tools', 'extras'): os.makedirs(join(dir, 'waflib', x)) except OSError: err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) os.chdir(dir) tmp = 't.bz2' t = open(tmp,'wb') try: t.write(txt) finally: t.close() try: t = tarfile.open(tmp) except: try: os.system('bunzip2 t.bz2') t = tarfile.open('t') tmp = 't' except: os.chdir(cwd) try: shutil.rmtree(dir) except OSError: pass err("Waf cannot be unpacked, check that bzip2 support is present") try: for x in t: t.extract(x) finally: t.close() for x in ('Tools', 'extras'): os.chmod(join('waflib',x), 493) if sys.hexversion<0x300000f: sys.path = [join(dir, 'waflib')] + sys.path import fixpy2 fixpy2.fixdir(dir) os.remove(tmp) os.chdir(cwd) try: dir = unicode(dir, 'mbcs') except: pass try: from ctypes import windll windll.kernel32.SetFileAttributesW(dir, 2) except: pass def test(dir): try: os.stat(join(dir, 'waflib')) return os.path.abspath(dir) except OSError: pass def find_lib(): path = '../../third_party/waf' paths = [path, path+'/waflib'] return [os.path.abspath(os.path.join(os.path.dirname(__file__), x)) for x in paths] wafdir = find_lib() for p in wafdir: sys.path.insert(0, p) if __name__ == '__main__': #import extras.compat15#PRELUDE import sys from waflib.Tools import ccroot, c, ar, compiler_c, gcc sys.modules['cc'] = c sys.modules['ccroot'] = ccroot sys.modules['ar'] = ar sys.modules['compiler_cc'] = compiler_c sys.modules['gcc'] = gcc from waflib import Options Options.lockfile = os.environ.get('WAFLOCK', '.lock-wscript') if os.path.isfile(Options.lockfile) and os.stat(Options.lockfile).st_size == 0: os.environ['NOCLIMB'] = "1" # there is a single top-level, but libraries must build independently os.environ['NO_LOCK_IN_TOP'] = "1" from waflib import Task class o(object): display = None Task.classes['cc_link'] = o from waflib import Scripting Scripting.waf_entry_point(cwd, VERSION, wafdir[0]) ldb-2.0.8/buildtools/compare_config_h4.sh0000770000000000000000000000050212406075657020313 0ustar rootroot00000000000000#!/bin/sh # compare the generated config.h from a waf build with existing samba # build grep "^.define" bin/default/source4/include/config.h | sort > waf-config.h grep "^.define" $HOME/samba_old/source4/include/config.h | sort > old-config.h comm -23 old-config.h waf-config.h #echo #diff -u old-config.h waf-config.h ldb-2.0.8/buildtools/compare_generated.sh0000770000000000000000000000251212406075657020414 0ustar rootroot00000000000000#!/bin/sh # compare the generated files from a waf old_build=$HOME/samba_old gen_files=$(cd bin/default && find . -type f -name '*.[ch]') 2>&1 strip_file() { in_file=$1 out_file=$2 cat $in_file | grep -v 'The following definitions come from' | grep -v 'Automatically generated at' | grep -v 'Generated from' | sed 's|/home/tnagy/samba/source4||g' | sed 's|/home/tnagy/samba/|../|g' | sed 's|bin/default/source4/||g' | sed 's|bin/default/|../|g' | sed 's/define _____/define ___/g' | sed 's/define __*/define _/g' | sed 's/define _DEFAULT_/define _/g' | sed 's/define _SOURCE4_/define ___/g' | sed 's/define ___/define _/g' | sed 's/ifndef ___/ifndef _/g' | sed 's|endif /* ____|endif /* __|g' | sed s/__DEFAULT_SOURCE4/__/ | sed s/__DEFAULT_SOURCE4/__/ | sed s/__DEFAULT/____/ > $out_file } compare_file() { f=$f bname=$(basename $f) t1=/tmp/$bname.old.$$ t2=/tmp/$bname.new.$$ strip_file $old_build/$f $t1 strip_file bin/default/$f $t2 diff -u -b $t1 $t2 2>&1 rm -f $t1 $t2 } for f in $gen_files; do compare_file $f done ldb-2.0.8/buildtools/compare_install.sh0000770000000000000000000000021212406075657020117 0ustar rootroot00000000000000#!/bin/sh prefix1="$1" prefix2="$2" (cd $prefix1 && find . ) | sort > p1.txt (cd $prefix2 && find . ) | sort > p2.txt diff -u p[12].txt ldb-2.0.8/buildtools/examples/run_on_target.py0000770000000000000000000001162113573675413021455 0ustar rootroot00000000000000#!/usr/bin/env python3 # # Sample run-on-target script # This is a script that can be used as cross-execute parameter to samba # configuration process, running the command on a remote target for which # the cross-compiled configure test was compiled. # # To use: # ./configure \ # --cross-compile \ # '--cross-execute=./buildtools/example/run_on_target.py --host=' # # A more elaborate example: # ./configure \ # --cross-compile \ # '--cross-execute=./buildtools/example/run_on_target.py --host= --user= "--ssh=ssh -i " --destdir=/path/to/dir' # # Typically this is to be used also with --cross-answers, so that the # cross answers file gets built and further builds can be made without # the help of a remote target. # # The following assumptions are made: # 1. rsync is available on build machine and target machine # 2. A running ssh service on target machine with password-less shell login # 3. A directory writable by the password-less login user # 4. The tests on the target can run and provide reliable results # from the login account's home directory. This is significant # for example in locking tests which # create files in the current directory. As a workaround to this # assumption, the TESTDIR environment variable can be set on the target # (using ssh command line or server config) and the tests shall # chdir to that directory. # import sys import os import subprocess from optparse import OptionParser # those are defaults, but can be overidden using command line SSH = 'ssh' USER = None HOST = 'localhost' def xfer_files(ssh, srcdir, host, user, targ_destdir): """Transfer executable files to target Use rsync to copy the directory containing program to run INTO a destination directory on the target. An exact copy of the source directory is created on the target machine, possibly deleting files on the target machine which do not exist on the source directory. The idea is that the test may include files in addition to the compiled binary, and all of those files reside alongside the binary in a source directory. For example, if the test to run is /foo/bar/test and the destination directory on the target is /tbaz, then /tbaz/bar on the target shall be an exact copy of /foo/bar on the source, including deletion of files inside /tbaz/bar which do not exist on the source. """ userhost = host if user: userhost = '%s@%s' % (user, host) cmd = 'rsync --verbose -rl --ignore-times --delete -e "%s" %s %s:%s/' % \ (ssh, srcdir, userhost, targ_destdir) p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = p.communicate() if p.returncode != 0: raise Exception('failed syncing files\n stdout:\n%s\nstderr:%s\n' % (out, err)) def exec_remote(ssh, host, user, destdir, targdir, prog, args): """Run a test on the target Using password-less ssh, run the compiled binary on the target. An assumption is that there's no need to cd into the target dir, same as there's no need to do it on a native build. """ userhost = host if user: userhost = '%s@%s' % (user, host) cmd = '%s %s %s/%s/%s' % (ssh, userhost, destdir, targdir, prog) if args: cmd = cmd + ' ' + ' '.join(args) p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = p.communicate() return (p.returncode, out) def main(argv): usage = "usage: %prog [options] [args]" parser = OptionParser(usage) parser.add_option('--ssh', help="SSH client and additional flags", default=SSH) parser.add_option('--host', help="target host name or IP address", default=HOST) parser.add_option('--user', help="login user on target", default=USER) parser.add_option('--destdir', help="work directory on target", default='~') (options, args) = parser.parse_args(argv) if len(args) < 1: parser.error("please supply test program to run") progpath = args[0] # assume that a test that was not compiled fails (e.g. getconf) if progpath[0] != '/': return (1, "") progdir = os.path.dirname(progpath) prog = os.path.basename(progpath) targ_progdir = os.path.basename(progdir) xfer_files( options.ssh, progdir, options.host, options.user, options.destdir) (rc, out) = exec_remote(options.ssh, options.host, options.user, options.destdir, targ_progdir, prog, args[1:]) return (rc, out) if __name__ == '__main__': (rc, out) = main(sys.argv[1:]) sys.stdout.write(out) sys.exit(rc) ldb-2.0.8/buildtools/scripts/Makefile.waf0000660000000000000000000000176712406075657020330 0ustar rootroot00000000000000# simple makefile wrapper to run waf WAF_BINARY=BUILDTOOLS/bin/waf WAF=WAF_MAKE=1 $(WAF_BINARY) all: $(WAF) build install: $(WAF) install uninstall: $(WAF) uninstall test: $(WAF) test $(TEST_OPTIONS) help: @echo NOTE: to run extended waf options use $(WAF_BINARY) or modify your PATH $(WAF) --help testenv: $(WAF) test --testenv $(TEST_OPTIONS) quicktest: $(WAF) test --quick $(TEST_OPTIONS) dist: $(WAF) dist distcheck: $(WAF) distcheck clean: $(WAF) clean distclean: $(WAF) distclean reconfigure: configure $(WAF) reconfigure show_waf_options: $(WAF) --help # some compatibility make targets everything: all testsuite: all check: test torture: all # this should do an install as well, once install is finished installcheck: test etags: $(WAF) etags ctags: $(WAF) ctags bin/%:: FORCE $(WAF) --targets=$@ FORCE: configure: autogen-waf.sh BUILDTOOLS/scripts/configure.waf ./autogen-waf.sh Makefile: autogen-waf.sh configure BUILDTOOLS/scripts/Makefile.waf ./autogen-waf.sh ldb-2.0.8/buildtools/scripts/abi_gen.sh0000770000000000000000000000075613573675413020035 0ustar rootroot00000000000000#!/bin/sh # generate a set of ABI signatures from a shared library SHAREDLIB="$1" GDBSCRIPT="gdb_syms.$$" ( cat < $GDBSCRIPT # forcing the terminal avoids a problem on Fedora12 TERM=none gdb -n -batch -x $GDBSCRIPT "$SHAREDLIB" < /dev/null rm -f $GDBSCRIPT ldb-2.0.8/buildtools/scripts/autogen-waf.sh0000770000000000000000000000135212406075657020655 0ustar rootroot00000000000000#!/bin/sh p=`dirname $0` echo "Setting up for waf build" echo "Looking for the buildtools directory" d="buildtools" while test \! -d "$p/$d"; do d="../$d"; done echo "Found buildtools in $p/$d" echo "Setting up configure" rm -f $p/configure $p/include/config*.h* sed "s|BUILDTOOLS|$d|g;s|BUILDPATH|$p|g" < "$p/$d/scripts/configure.waf" > $p/configure chmod +x $p/configure echo "Setting up Makefile" rm -f $p/makefile $p/Makefile sed "s|BUILDTOOLS|$d|g" < "$p/$d/scripts/Makefile.waf" > $p/Makefile echo "done. Now run $p/configure or $p/configure.developer then make." if [ $p != "." ]; then echo "Notice: The build invoke path is not 'source4'! Use make with the parameter" echo "-C <'source4' path>. Example: make -C source4 all" fi ldb-2.0.8/buildtools/scripts/configure.waf0000770000000000000000000000037112406075657020564 0ustar rootroot00000000000000#!/bin/sh PREVPATH=`dirname $0` WAF=BUILDTOOLS/bin/waf # using JOBS=1 gives maximum compatibility with # systems like AIX which have broken threading in python JOBS=1 export JOBS cd BUILDPATH || exit 1 $WAF configure "$@" || exit 1 cd $PREVPATH ldb-2.0.8/buildtools/testwaf.sh0000770000000000000000000000260012406075657016423 0ustar rootroot00000000000000#!/bin/bash set -e set -x d=$(dirname $0) cd $d/.. PREFIX=$HOME/testprefix if [ $# -gt 0 ]; then tests="$*" else tests="lib/replace lib/talloc lib/tevent lib/tdb lib/ldb" fi echo "testing in dirs $tests" for d in $tests; do echo "`date`: testing $d" pushd $d rm -rf bin type waf waf dist ./configure -C --enable-developer --prefix=$PREFIX time make make install make distcheck case $d in "lib/ldb") ldd bin/ldbadd ;; "lib/replace") ldd bin/replace_testsuite ;; "lib/talloc") ldd bin/talloc_testsuite ;; "lib/tdb") ldd bin/tdbtool ;; esac popd done echo "testing python portability" pushd lib/talloc versions="python2.4 python2.5 python2.6 python3.0 python3.1" for p in $versions; do ret=$(which $p || echo "failed") if [ $ret = "failed" ]; then echo "$p not found, skipping" continue fi echo "Testing $p" $p ../../buildtools/bin/waf configure -C --enable-developer --prefix=$PREFIX $p ../../buildtools/bin/waf build install done popd echo "testing cross compiling" pushd lib/talloc ret=$(which arm-linux-gnueabi-gcc || echo "failed") if [ $ret != "failed" ]; then CC=arm-linux-gnueabi-gcc ./configure -C --prefix=$PREFIX --cross-compile --cross-execute='runarm' make && make install else echo "Cross-compiler not installed, skipping test" fi popd ldb-2.0.8/buildtools/wafsamba/README0000660000000000000000000000037712406075657017062 0ustar rootroot00000000000000This is a set of waf 'tools' to help make building the Samba components easier, by having common functions in one place. This gives us a more consistent build, and ensures that our project rules are obeyed TODO: see http://wiki.samba.org/index.php/Waf ldb-2.0.8/buildtools/wafsamba/__init__.py0000660000000000000000000000000012406075657020272 0ustar rootroot00000000000000ldb-2.0.8/buildtools/wafsamba/configure_file.py0000660000000000000000000000233113573675413021526 0ustar rootroot00000000000000# handle substitution of variables in .in files import sys import re import os from waflib import Build, Logs from samba_utils import SUBST_VARS_RECURSIVE def subst_at_vars(task): '''substiture @VAR@ style variables in a file''' env = task.env s = task.inputs[0].read() # split on the vars a = re.split('(@\w+@)', s) out = [] for v in a: if re.match('@\w+@', v): vname = v[1:-1] if not vname in task.env and vname.upper() in task.env: vname = vname.upper() if not vname in task.env: Logs.error("Unknown substitution %s in %s" % (v, task.name)) sys.exit(1) v = SUBST_VARS_RECURSIVE(task.env[vname], task.env) out.append(v) contents = ''.join(out) task.outputs[0].write(contents) return 0 def CONFIGURE_FILE(bld, in_file, **kwargs): '''configure file''' base=os.path.basename(in_file) t = bld.SAMBA_GENERATOR('INFILE_%s' % base, rule = subst_at_vars, source = in_file + '.in', target = in_file, vars = kwargs) Build.BuildContext.CONFIGURE_FILE = CONFIGURE_FILE ldb-2.0.8/buildtools/wafsamba/generic_cc.py0000660000000000000000000000324413573675413020633 0ustar rootroot00000000000000 # compiler definition for a generic C compiler # based on suncc.py from waf import os, optparse from waflib import Errors from waflib.Tools import ccroot, ar from waflib.Configure import conf # # Let waflib provide useful defaults, but # provide generic_cc as last resort fallback on # all platforms # from waflib.Tools.compiler_c import c_compiler for key in c_compiler.keys(): c_compiler[key].append('generic_cc') @conf def find_generic_cc(conf): v = conf.env cc = None if v.CC: cc = v.CC elif 'CC' in conf.environ: cc = conf.environ['CC'] if not cc: cc = conf.find_program('cc', var='CC') if not cc: conf.fatal('generic_cc was not found') try: conf.cmd_and_log(cc + ['--version']) except Errors.WafError: conf.fatal('%r --version could not be executed' % cc) v.CC = cc v.CC_NAME = 'generic_cc' @conf def generic_cc_common_flags(conf): v = conf.env v.CC_SRC_F = '' v.CC_TGT_F = ['-c', '-o'] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' if not v.LINK_CC: v.LINK_CC = v.CC v.CCLNK_SRC_F = '' v.CCLNK_TGT_F = ['-o'] v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.cprogram_PATTERN = '%s' v.cshlib_PATTERN = 'lib%s.so' v.cstlib_PATTERN = 'lib%s.a' def configure(conf): conf.find_generic_cc() conf.find_ar() conf.generic_cc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/buildtools/wafsamba/pkgconfig.py0000660000000000000000000000457613573675413020532 0ustar rootroot00000000000000# handle substitution of variables in pc files import os, re, sys from waflib import Build, Logs from samba_utils import SUBST_VARS_RECURSIVE, TO_LIST def subst_at_vars(task): '''substiture @VAR@ style variables in a file''' s = task.inputs[0].read() # split on the vars a = re.split('(@\w+@)', s) out = [] done_var = {} back_sub = [ ('PREFIX', '${prefix}'), ('EXEC_PREFIX', '${exec_prefix}')] for v in a: if re.match('@\w+@', v): vname = v[1:-1] if not vname in task.env and vname.upper() in task.env: vname = vname.upper() if not vname in task.env: Logs.error("Unknown substitution %s in %s" % (v, task.name)) sys.exit(1) v = SUBST_VARS_RECURSIVE(task.env[vname], task.env) # now we back substitute the allowed pc vars for (b, m) in back_sub: s = task.env[b] if s == v[0:len(s)]: if not b in done_var: # we don't want to substitute the first usage done_var[b] = True else: v = m + v[len(s):] break out.append(v) contents = ''.join(out) task.outputs[0].write(contents) return 0 def PKG_CONFIG_FILES(bld, pc_files, vnum=None, extra_name=None): '''install some pkg_config pc files''' dest = '${PKGCONFIGDIR}' dest = bld.EXPAND_VARIABLES(dest) for f in TO_LIST(pc_files): if extra_name: target = f.split('.pc')[0] + extra_name + ".pc" else: target = f base=os.path.basename(target) t = bld.SAMBA_GENERATOR('PKGCONFIG_%s' % base, rule=subst_at_vars, source=f+'.in', target=target) bld.add_manual_dependency(bld.path.find_or_declare(f), bld.env['PREFIX'].encode('utf8')) t.vars = [] if t.env.RPATH_ON_INSTALL: t.env.LIB_RPATH = t.env.RPATH_ST % t.env.LIBDIR else: t.env.LIB_RPATH = '' if vnum: t.env.PACKAGE_VERSION = vnum for v in [ 'PREFIX', 'EXEC_PREFIX', 'LIB_RPATH' ]: t.vars.append(t.env[v]) bld.INSTALL_FILES(dest, target, flat=True, destname=base) Build.BuildContext.PKG_CONFIG_FILES = PKG_CONFIG_FILES ldb-2.0.8/buildtools/wafsamba/samba3.py0000660000000000000000000000772013573675413017723 0ustar rootroot00000000000000# a waf tool to add autoconf-like macros to the configure section # and for SAMBA_ macros for building libraries, binaries etc import os from waflib import Build from samba_utils import os_path_relpath, TO_LIST from samba_autoconf import library_flags def SAMBA3_IS_STATIC_MODULE(bld, module): '''Check whether module is in static list''' if module in bld.env['static_modules']: return True return False Build.BuildContext.SAMBA3_IS_STATIC_MODULE = SAMBA3_IS_STATIC_MODULE def SAMBA3_IS_SHARED_MODULE(bld, module): '''Check whether module is in shared list''' if module in bld.env['shared_modules']: return True return False Build.BuildContext.SAMBA3_IS_SHARED_MODULE = SAMBA3_IS_SHARED_MODULE def SAMBA3_IS_ENABLED_MODULE(bld, module): '''Check whether module is in either shared or static list ''' return SAMBA3_IS_STATIC_MODULE(bld, module) or SAMBA3_IS_SHARED_MODULE(bld, module) Build.BuildContext.SAMBA3_IS_ENABLED_MODULE = SAMBA3_IS_ENABLED_MODULE def s3_fix_kwargs(bld, kwargs): '''fix the build arguments for s3 build rules to include the necessary includes, subdir and cflags options ''' s3dir = os.path.join(bld.env.srcdir, 'source3') s3reldir = os_path_relpath(s3dir, bld.path.abspath()) # the extra_includes list is relative to the source3 directory extra_includes = [ '.', 'include', 'lib' ] # local heimdal paths only included when USING_SYSTEM_KRB5 is not set if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): extra_includes += [ '../source4/heimdal/lib/com_err', '../source4/heimdal/lib/krb5', '../source4/heimdal/lib/gssapi', '../source4/heimdal_build', '../bin/default/source4/heimdal/lib/asn1' ] if bld.CONFIG_SET('USING_SYSTEM_TDB'): (tdb_includes, tdb_ldflags, tdb_cpppath) = library_flags(bld, 'tdb') extra_includes += tdb_cpppath else: extra_includes += [ '../lib/tdb/include' ] if bld.CONFIG_SET('USING_SYSTEM_TEVENT'): (tevent_includes, tevent_ldflags, tevent_cpppath) = library_flags(bld, 'tevent') extra_includes += tevent_cpppath else: extra_includes += [ '../lib/tevent' ] if bld.CONFIG_SET('USING_SYSTEM_TALLOC'): (talloc_includes, talloc_ldflags, talloc_cpppath) = library_flags(bld, 'talloc') extra_includes += talloc_cpppath else: extra_includes += [ '../lib/talloc' ] if bld.CONFIG_SET('USING_SYSTEM_POPT'): (popt_includes, popt_ldflags, popt_cpppath) = library_flags(bld, 'popt') extra_includes += popt_cpppath else: extra_includes += [ '../lib/popt' ] # s3 builds assume that they will have a bunch of extra include paths includes = [] for d in extra_includes: includes += [ os.path.join(s3reldir, d) ] # the rule may already have some includes listed if 'includes' in kwargs: includes += TO_LIST(kwargs['includes']) kwargs['includes'] = includes # these wrappers allow for mixing of S3 and S4 build rules in the one build def SAMBA3_LIBRARY(bld, name, *args, **kwargs): s3_fix_kwargs(bld, kwargs) return bld.SAMBA_LIBRARY(name, *args, **kwargs) Build.BuildContext.SAMBA3_LIBRARY = SAMBA3_LIBRARY def SAMBA3_MODULE(bld, name, *args, **kwargs): s3_fix_kwargs(bld, kwargs) return bld.SAMBA_MODULE(name, *args, **kwargs) Build.BuildContext.SAMBA3_MODULE = SAMBA3_MODULE def SAMBA3_SUBSYSTEM(bld, name, *args, **kwargs): s3_fix_kwargs(bld, kwargs) return bld.SAMBA_SUBSYSTEM(name, *args, **kwargs) Build.BuildContext.SAMBA3_SUBSYSTEM = SAMBA3_SUBSYSTEM def SAMBA3_BINARY(bld, name, *args, **kwargs): s3_fix_kwargs(bld, kwargs) return bld.SAMBA_BINARY(name, *args, **kwargs) Build.BuildContext.SAMBA3_BINARY = SAMBA3_BINARY def SAMBA3_PYTHON(bld, name, *args, **kwargs): s3_fix_kwargs(bld, kwargs) return bld.SAMBA_PYTHON(name, *args, **kwargs) Build.BuildContext.SAMBA3_PYTHON = SAMBA3_PYTHON ldb-2.0.8/buildtools/wafsamba/samba_abi.py0000660000000000000000000002153613573675413020454 0ustar rootroot00000000000000# functions for handling ABI checking of libraries import os import sys import re import fnmatch from waflib import Options, Utils, Logs, Task, Build, Errors from waflib.TaskGen import feature, before, after from wafsamba import samba_utils # these type maps cope with platform specific names for common types # please add new type mappings into the list below abi_type_maps = { '_Bool' : 'bool', 'struct __va_list_tag *' : 'va_list' } version_key = lambda x: list(map(int, x.split("."))) def normalise_signature(sig): '''normalise a signature from gdb''' sig = sig.strip() sig = re.sub('^\$[0-9]+\s=\s\{(.+)\}$', r'\1', sig) sig = re.sub('^\$[0-9]+\s=\s\{(.+)\}(\s0x[0-9a-f]+\s<\w+>)+$', r'\1', sig) sig = re.sub('^\$[0-9]+\s=\s(0x[0-9a-f]+)\s?(<\w+>)?$', r'\1', sig) sig = re.sub('0x[0-9a-f]+', '0xXXXX', sig) sig = re.sub('", ', r'\1"', sig) for t in abi_type_maps: # we need to cope with non-word characters in mapped types m = t m = m.replace('*', '\*') if m[-1].isalnum() or m[-1] == '_': m += '\\b' if m[0].isalnum() or m[0] == '_': m = '\\b' + m sig = re.sub(m, abi_type_maps[t], sig) return sig def normalise_varargs(sig): '''cope with older versions of gdb''' sig = re.sub(',\s\.\.\.', '', sig) return sig def parse_sigs(sigs, abi_match): '''parse ABI signatures file''' abi_match = samba_utils.TO_LIST(abi_match) ret = {} a = sigs.split('\n') for s in a: if s.find(':') == -1: continue sa = s.split(':') if abi_match: matched = False negative = False for p in abi_match: if p[0] == '!' and fnmatch.fnmatch(sa[0], p[1:]): negative = True break elif fnmatch.fnmatch(sa[0], p): matched = True break if (not matched) and negative: continue Logs.debug("%s -> %s" % (sa[1], normalise_signature(sa[1]))) ret[sa[0]] = normalise_signature(sa[1]) return ret def save_sigs(sig_file, parsed_sigs): '''save ABI signatures to a file''' sigs = '' for s in sorted(parsed_sigs.keys()): sigs += '%s: %s\n' % (s, parsed_sigs[s]) return samba_utils.save_file(sig_file, sigs, create_dir=True) def abi_check_task(self): '''check if the ABI has changed''' abi_gen = self.ABI_GEN libpath = self.inputs[0].abspath(self.env) libname = os.path.basename(libpath) sigs = samba_utils.get_string(Utils.cmd_output([abi_gen, libpath])) parsed_sigs = parse_sigs(sigs, self.ABI_MATCH) sig_file = self.ABI_FILE old_sigs = samba_utils.load_file(sig_file) if old_sigs is None or Options.options.ABI_UPDATE: if not save_sigs(sig_file, parsed_sigs): raise Errors.WafError('Failed to save ABI file "%s"' % sig_file) Logs.warn('Generated ABI signatures %s' % sig_file) return parsed_old_sigs = parse_sigs(old_sigs, self.ABI_MATCH) # check all old sigs got_error = False for s in parsed_old_sigs: if not s in parsed_sigs: Logs.error('%s: symbol %s has been removed - please update major version\n\tsignature: %s' % ( libname, s, parsed_old_sigs[s])) got_error = True elif normalise_varargs(parsed_old_sigs[s]) != normalise_varargs(parsed_sigs[s]): Logs.error('%s: symbol %s has changed - please update major version\n\told_signature: %s\n\tnew_signature: %s' % ( libname, s, parsed_old_sigs[s], parsed_sigs[s])) got_error = True for s in parsed_sigs: if not s in parsed_old_sigs: Logs.error('%s: symbol %s has been added - please mark it _PRIVATE_ or update minor version\n\tsignature: %s' % ( libname, s, parsed_sigs[s])) got_error = True if got_error: raise Errors.WafError('ABI for %s has changed - please fix library version then build with --abi-update\nSee http://wiki.samba.org/index.php/Waf#ABI_Checking for more information\nIf you have not changed any ABI, and your platform always gives this error, please configure with --abi-check-disable to skip this check' % libname) t = Task.task_factory('abi_check', abi_check_task, color='BLUE', ext_in='.bin') t.quiet = True # allow "waf --abi-check" to force re-checking the ABI if '--abi-check' in sys.argv: t.always_run = True @after('apply_link') @feature('abi_check') def abi_check(self): '''check that ABI matches saved signatures''' env = self.bld.env if not env.ABI_CHECK or self.abi_directory is None: return # if the platform doesn't support -fvisibility=hidden then the ABI # checks become fairly meaningless if not env.HAVE_VISIBILITY_ATTR: return topsrc = self.bld.srcnode.abspath() abi_gen = os.path.join(topsrc, 'buildtools/scripts/abi_gen.sh') abi_file = "%s/%s-%s.sigs" % (self.abi_directory, self.version_libname, self.vnum) tsk = self.create_task('abi_check', self.link_task.outputs[0]) tsk.ABI_FILE = abi_file tsk.ABI_MATCH = self.abi_match tsk.ABI_GEN = abi_gen def abi_process_file(fname, version, symmap): '''process one ABI file, adding new symbols to the symmap''' for line in Utils.readf(fname).splitlines(): symname = line.split(":")[0] if not symname in symmap: symmap[symname] = version def abi_write_vscript(f, libname, current_version, versions, symmap, abi_match): """Write a vscript file for a library in --version-script format. :param f: File-like object to write to :param libname: Name of the library, uppercased :param current_version: Current version :param versions: Versions to consider :param symmap: Dictionary mapping symbols -> version :param abi_match: List of symbols considered to be public in the current version """ invmap = {} for s in symmap: invmap.setdefault(symmap[s], []).append(s) last_key = "" versions = sorted(versions, key=version_key) for k in versions: symver = "%s_%s" % (libname, k) if symver == current_version: break f.write("%s {\n" % symver) if k in sorted(invmap.keys()): f.write("\tglobal:\n") for s in invmap.get(k, []): f.write("\t\t%s;\n" % s); f.write("}%s;\n\n" % last_key) last_key = " %s" % symver f.write("%s {\n" % current_version) local_abi = list(filter(lambda x: x[0] == '!', abi_match)) global_abi = list(filter(lambda x: x[0] != '!', abi_match)) f.write("\tglobal:\n") if len(global_abi) > 0: for x in global_abi: f.write("\t\t%s;\n" % x) else: f.write("\t\t*;\n") # Always hide symbols that must be local if exist local_abi.extend(["!_end", "!__bss_start", "!_edata"]) f.write("\tlocal:\n") for x in local_abi: f.write("\t\t%s;\n" % x[1:]) if global_abi != ["*"]: if len(global_abi) > 0: f.write("\t\t*;\n") f.write("};\n") def abi_build_vscript(task): '''generate a vscript file for our public libraries''' tgt = task.outputs[0].bldpath(task.env) symmap = {} versions = [] for f in task.inputs: fname = f.abspath(task.env) basename = os.path.basename(fname) version = basename[len(task.env.LIBNAME)+1:-len(".sigs")] versions.append(version) abi_process_file(fname, version, symmap) f = open(tgt, mode='w') try: abi_write_vscript(f, task.env.LIBNAME, task.env.VERSION, versions, symmap, task.env.ABI_MATCH) finally: f.close() def ABI_VSCRIPT(bld, libname, abi_directory, version, vscript, abi_match=None): '''generate a vscript file for our public libraries''' if abi_directory: source = bld.path.ant_glob('%s/%s-[0-9]*.sigs' % (abi_directory, libname), flat=True) def abi_file_key(path): return version_key(path[:-len(".sigs")].rsplit("-")[-1]) source = sorted(source.split(), key=abi_file_key) else: source = '' libname = os.path.basename(libname) version = os.path.basename(version) libname = libname.replace("-", "_").replace("+","_").upper() version = version.replace("-", "_").replace("+","_").upper() t = bld.SAMBA_GENERATOR(vscript, rule=abi_build_vscript, source=source, group='vscripts', target=vscript) if abi_match is None: abi_match = ["*"] else: abi_match = samba_utils.TO_LIST(abi_match) t.env.ABI_MATCH = abi_match t.env.VERSION = version t.env.LIBNAME = libname t.vars = ['LIBNAME', 'VERSION', 'ABI_MATCH'] Build.BuildContext.ABI_VSCRIPT = ABI_VSCRIPT ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py0000660000000000000000000007761613573675413021551 0ustar rootroot00000000000000# a waf tool to add autoconf-like macros to the configure section import os, sys from waflib import Build, Options, Logs, Context from waflib.Configure import conf from waflib.TaskGen import feature from waflib.Tools import c_preproc as preproc from samba_utils import TO_LIST, GET_TARGET_TYPE, SET_TARGET_TYPE, unique_list, mkdir_p missing_headers = set() #################################################### # some autoconf like helpers, to make the transition # to waf a bit easier for those used to autoconf # m4 files @conf def DEFINE(conf, d, v, add_to_cflags=False, quote=False): '''define a config option''' conf.define(d, v, quote=quote) if add_to_cflags: conf.env.append_value('CFLAGS', '-D%s=%s' % (d, str(v))) def hlist_to_string(conf, headers=None): '''convert a headers list to a set of #include lines''' hdrs='' hlist = conf.env.hlist if headers: hlist = hlist[:] hlist.extend(TO_LIST(headers)) for h in hlist: hdrs += '#include <%s>\n' % h return hdrs @conf def COMPOUND_START(conf, msg): '''start a compound test''' def null_check_message_1(self,*k,**kw): return def null_check_message_2(self,*k,**kw): return v = getattr(conf.env, 'in_compound', []) if v != [] and v != 0: conf.env.in_compound = v + 1 return conf.start_msg(msg) conf.saved_check_message_1 = conf.start_msg conf.start_msg = null_check_message_1 conf.saved_check_message_2 = conf.end_msg conf.end_msg = null_check_message_2 conf.env.in_compound = 1 @conf def COMPOUND_END(conf, result): '''start a compound test''' conf.env.in_compound -= 1 if conf.env.in_compound != 0: return conf.start_msg = conf.saved_check_message_1 conf.end_msg = conf.saved_check_message_2 p = conf.end_msg if result is True: p('ok') elif not result: p('not found', 'YELLOW') else: p(result) @feature('nolink') def nolink(self): '''using the nolink type in conf.check() allows us to avoid the link stage of a test, thus speeding it up for tests that where linking is not needed''' pass def CHECK_HEADER(conf, h, add_headers=False, lib=None): '''check for a header''' if h in missing_headers and lib is None: return False d = h.upper().replace('/', '_') d = d.replace('.', '_') d = d.replace('-', '_') d = 'HAVE_%s' % d if CONFIG_SET(conf, d): if add_headers: if not h in conf.env.hlist: conf.env.hlist.append(h) return True (ccflags, ldflags, cpppath) = library_flags(conf, lib) hdrs = hlist_to_string(conf, headers=h) if lib is None: lib = "" ret = conf.check(fragment='%s\nint main(void) { return 0; }\n' % hdrs, type='nolink', execute=0, cflags=ccflags, mandatory=False, includes=cpppath, uselib=lib.upper(), msg="Checking for header %s" % h) if not ret: missing_headers.add(h) return False conf.DEFINE(d, 1) if add_headers and not h in conf.env.hlist: conf.env.hlist.append(h) return ret @conf def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None): '''check for a list of headers when together==True, then the headers accumulate within this test. This is useful for interdependent headers ''' ret = True if not add_headers and together: saved_hlist = conf.env.hlist[:] set_add_headers = True else: set_add_headers = add_headers for hdr in TO_LIST(headers): if not CHECK_HEADER(conf, hdr, set_add_headers, lib=lib): ret = False if not add_headers and together: conf.env.hlist = saved_hlist return ret def header_list(conf, headers=None, lib=None): '''form a list of headers which exist, as a string''' hlist=[] if headers is not None: for h in TO_LIST(headers): if CHECK_HEADER(conf, h, add_headers=False, lib=lib): hlist.append(h) return hlist_to_string(conf, headers=hlist) @conf def CHECK_TYPE(conf, t, alternate=None, headers=None, define=None, lib=None, msg=None): '''check for a single type''' if define is None: define = 'HAVE_' + t.upper().replace(' ', '_') if msg is None: msg='Checking for %s' % t ret = CHECK_CODE(conf, '%s _x' % t, define, execute=False, headers=headers, local_include=False, msg=msg, lib=lib, link=False) if not ret and alternate: conf.DEFINE(t, alternate) return ret @conf def CHECK_TYPES(conf, list, headers=None, define=None, alternate=None, lib=None): '''check for a list of types''' ret = True for t in TO_LIST(list): if not CHECK_TYPE(conf, t, headers=headers, define=define, alternate=alternate, lib=lib): ret = False return ret @conf def CHECK_TYPE_IN(conf, t, headers=None, alternate=None, define=None): '''check for a single type with a header''' return CHECK_TYPE(conf, t, headers=headers, alternate=alternate, define=define) @conf def CHECK_VARIABLE(conf, v, define=None, always=False, headers=None, msg=None, lib=None): '''check for a variable declaration (or define)''' if define is None: define = 'HAVE_%s' % v.upper() if msg is None: msg="Checking for variable %s" % v return CHECK_CODE(conf, # we need to make sure the compiler doesn't # optimize it out... ''' #ifndef %s void *_x; _x=(void *)&%s; return (int)_x; #endif return 0 ''' % (v, v), execute=False, link=False, msg=msg, local_include=False, lib=lib, headers=headers, define=define, always=always) @conf def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False): '''check a list of variable declarations, using the HAVE_DECL_xxx form of define When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx ''' ret = True for v in TO_LIST(vars): if not reverse: define='HAVE_DECL_%s' % v.upper() else: define='HAVE_%s_DECL' % v.upper() if not CHECK_VARIABLE(conf, v, define=define, headers=headers, msg='Checking for declaration of %s' % v, always=always): if not CHECK_CODE(conf, ''' return (int)%s; ''' % (v), execute=False, link=False, msg='Checking for declaration of %s (as enum)' % v, local_include=False, headers=headers, define=define, always=always): ret = False return ret def CHECK_FUNC(conf, f, link=True, lib=None, headers=None): '''check for a function''' define='HAVE_%s' % f.upper() ret = False in_lib_str = "" if lib: in_lib_str = " in %s" % lib conf.COMPOUND_START('Checking for %s%s' % (f, in_lib_str)) if link is None or link: ret = CHECK_CODE(conf, # this is based on the autoconf strategy ''' #define %s __fake__%s #ifdef HAVE_LIMITS_H # include #else # include #endif #undef %s #if defined __stub_%s || defined __stub___%s #error "bad glibc stub" #endif extern char %s(); int main() { return %s(); } ''' % (f, f, f, f, f, f, f), execute=False, link=True, addmain=False, add_headers=False, define=define, local_include=False, lib=lib, headers=headers, msg='Checking for %s' % f) if not ret: ret = CHECK_CODE(conf, # it might be a macro # we need to make sure the compiler doesn't # optimize it out... 'void *__x = (void *)%s; return (int)__x' % f, execute=False, link=True, addmain=True, add_headers=True, define=define, local_include=False, lib=lib, headers=headers, msg='Checking for macro %s' % f) if not ret and (link is None or not link): ret = CHECK_VARIABLE(conf, f, define=define, headers=headers, msg='Checking for declaration of %s' % f) conf.COMPOUND_END(ret) return ret @conf def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None): '''check for a list of functions''' ret = True for f in TO_LIST(list): if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers): ret = False return ret @conf def CHECK_SIZEOF(conf, vars, headers=None, define=None, critical=True): '''check the size of a type''' for v in TO_LIST(vars): v_define = define ret = False if v_define is None: v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_') for size in list((1, 2, 4, 8, 16, 32, 64)): if CHECK_CODE(conf, 'static int test_array[1 - 2 * !(((long int)(sizeof(%s))) <= %d)];' % (v, size), define=v_define, quote=False, headers=headers, local_include=False, msg="Checking if size of %s == %d" % (v, size)): conf.DEFINE(v_define, size) ret = True break if not ret and critical: Logs.error("Couldn't determine size of '%s'" % v) sys.exit(1) return ret @conf def CHECK_VALUEOF(conf, v, headers=None, define=None): '''check the value of a variable/define''' ret = True v_define = define if v_define is None: v_define = 'VALUEOF_%s' % v.upper().replace(' ', '_') if CHECK_CODE(conf, 'printf("%%u", (unsigned)(%s))' % v, define=v_define, execute=True, define_ret=True, quote=False, headers=headers, local_include=False, msg="Checking value of %s" % v): return int(conf.env[v_define]) return None @conf def CHECK_CODE(conf, code, define, always=False, execute=False, addmain=True, add_headers=True, mandatory=False, headers=None, msg=None, cflags='', includes='# .', local_include=True, lib=None, link=True, define_ret=False, quote=False, on_target=True, strict=False): '''check if some code compiles and/or runs''' if CONFIG_SET(conf, define): return True if headers is not None: CHECK_HEADERS(conf, headers=headers, lib=lib) if add_headers: hdrs = header_list(conf, headers=headers, lib=lib) else: hdrs = '' if execute: execute = 1 else: execute = 0 if addmain: fragment='%s\n int main(void) { %s; return 0; }\n' % (hdrs, code) else: fragment='%s\n%s\n' % (hdrs, code) if msg is None: msg="Checking for %s" % define cflags = TO_LIST(cflags) # Be strict when relying on a compiler check # Some compilers (e.g. xlc) ignore non-supported features as warnings if strict: if 'WERROR_CFLAGS' in conf.env: cflags.extend(conf.env['WERROR_CFLAGS']) if local_include: cflags.append('-I%s' % conf.path.abspath()) if not link: type='nolink' else: type='cprogram' uselib = TO_LIST(lib) (ccflags, ldflags, cpppath) = library_flags(conf, uselib) includes = TO_LIST(includes) includes.extend(cpppath) uselib = [l.upper() for l in uselib] cflags.extend(ccflags) if on_target: test_args = conf.SAMBA_CROSS_ARGS(msg=msg) else: test_args = [] conf.COMPOUND_START(msg) try: ret = conf.check(fragment=fragment, execute=execute, define_name = define, cflags=cflags, ldflags=ldflags, includes=includes, uselib=uselib, type=type, msg=msg, quote=quote, test_args=test_args, define_ret=define_ret) except Exception: if always: conf.DEFINE(define, 0) else: conf.undefine(define) conf.COMPOUND_END(False) if mandatory: raise return False else: # Success is indicated by ret but we should unset # defines set by WAF's c_config.check() because it # defines it to int(ret) and we want to undefine it if not ret: conf.undefine(define) conf.COMPOUND_END(False) return False if not define_ret: conf.DEFINE(define, 1) conf.COMPOUND_END(True) else: conf.DEFINE(define, ret, quote=quote) conf.COMPOUND_END(ret) return True @conf def CHECK_STRUCTURE_MEMBER(conf, structname, member, always=False, define=None, headers=None, lib=None): '''check for a structure member''' if define is None: define = 'HAVE_%s' % member.upper() return CHECK_CODE(conf, '%s s; void *_x; _x=(void *)&s.%s' % (structname, member), define, execute=False, link=False, lib=lib, always=always, headers=headers, local_include=False, msg="Checking for member %s in %s" % (member, structname)) @conf def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'): '''check if the given cflags are accepted by the compiler ''' check_cflags = TO_LIST(cflags) if 'WERROR_CFLAGS' in conf.env: check_cflags.extend(conf.env['WERROR_CFLAGS']) return conf.check(fragment=fragment, execute=0, mandatory=False, type='nolink', cflags=check_cflags, msg="Checking compiler accepts %s" % cflags) @conf def CHECK_LDFLAGS(conf, ldflags): '''check if the given ldflags are accepted by the linker ''' return conf.check(fragment='int main(void) { return 0; }\n', execute=0, ldflags=ldflags, mandatory=False, msg="Checking linker accepts %s" % ldflags) @conf def CONFIG_GET(conf, option): '''return True if a configuration option was found''' if (option in conf.env): return conf.env[option] else: return None @conf def CONFIG_SET(conf, option): '''return True if a configuration option was found''' if option not in conf.env: return False v = conf.env[option] if v is None: return False if v == []: return False if v == (): return False return True @conf def CONFIG_RESET(conf, option): if option not in conf.env: return del conf.env[option] Build.BuildContext.CONFIG_RESET = CONFIG_RESET Build.BuildContext.CONFIG_SET = CONFIG_SET Build.BuildContext.CONFIG_GET = CONFIG_GET def library_flags(self, libs): '''work out flags from pkg_config''' ccflags = [] ldflags = [] cpppath = [] for lib in TO_LIST(libs): # note that we do not add the -I and -L in here, as that is added by the waf # core. Adding it here would just change the order that it is put on the link line # which can cause system paths to be added before internal libraries extra_ccflags = TO_LIST(getattr(self.env, 'CFLAGS_%s' % lib.upper(), [])) extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), [])) extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), [])) ccflags.extend(extra_ccflags) ldflags.extend(extra_ldflags) cpppath.extend(extra_cpppath) extra_cpppath = TO_LIST(getattr(self.env, 'INCLUDES_%s' % lib.upper(), [])) cpppath.extend(extra_cpppath) if 'EXTRA_LDFLAGS' in self.env: ldflags.extend(self.env['EXTRA_LDFLAGS']) ccflags = unique_list(ccflags) ldflags = unique_list(ldflags) cpppath = unique_list(cpppath) return (ccflags, ldflags, cpppath) @conf def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False): '''check if a set of libraries exist as system libraries returns the sublist of libs that do exist as a syslib or [] ''' fragment= ''' int foo() { int v = 2; return v*2; } ''' ret = [] liblist = TO_LIST(libs) for lib in liblist[:]: if GET_TARGET_TYPE(conf, lib) == 'SYSLIB': ret.append(lib) continue (ccflags, ldflags, cpppath) = library_flags(conf, lib) if shlib: res = conf.check(features='c cshlib', fragment=fragment, lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False) else: res = conf.check(lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False) if not res: if mandatory: Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list)) sys.exit(1) if empty_decl: # if it isn't a mandatory library, then remove it from dependency lists if set_target: SET_TARGET_TYPE(conf, lib, 'EMPTY') else: conf.define('HAVE_LIB%s' % lib.upper().replace('-','_').replace('.','_'), 1) conf.env['LIB_' + lib.upper()] = lib if set_target: conf.SET_TARGET_TYPE(lib, 'SYSLIB') ret.append(lib) return ret @conf def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False, headers=None, link=True, empty_decl=True, set_target=True): """ check that the functions in 'list' are available in 'library' if they are, then make that library available as a dependency if the library is not available and mandatory==True, then raise an error. If the library is not available and mandatory==False, then add the library to the list of dependencies to remove from build rules optionally check for the functions first in libc """ remaining = TO_LIST(list) liblist = TO_LIST(library) # check if some already found for f in remaining[:]: if CONFIG_SET(conf, 'HAVE_%s' % f.upper()): remaining.remove(f) # see if the functions are in libc if checklibc: for f in remaining[:]: if CHECK_FUNC(conf, f, link=True, headers=headers): remaining.remove(f) if remaining == []: for lib in liblist: if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl: SET_TARGET_TYPE(conf, lib, 'EMPTY') return True checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target) for lib in liblist[:]: if not lib in checklist and mandatory: Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list)) sys.exit(1) ret = True for f in remaining: if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link): ret = False return ret @conf def IN_LAUNCH_DIR(conf): '''return True if this rule is being run from the launch directory''' return os.path.realpath(conf.path.abspath()) == os.path.realpath(Context.launch_dir) Options.OptionsContext.IN_LAUNCH_DIR = IN_LAUNCH_DIR @conf def SAMBA_CONFIG_H(conf, path=None): '''write out config.h in the right directory''' # we don't want to produce a config.h in places like lib/replace # when we are building projects that depend on lib/replace if not IN_LAUNCH_DIR(conf): return # we need to build real code that can't be optimized away to test stack_protect_list = ['-fstack-protector-strong', '-fstack-protector'] for stack_protect_flag in stack_protect_list: flag_supported = conf.check(fragment=''' #include int main(void) { char t[100000]; while (fgets(t, sizeof(t), stdin)); return 0; } ''', execute=0, cflags=[ '-Werror', '-Wp,-D_FORTIFY_SOURCE=2', stack_protect_flag], mandatory=False, msg='Checking if compiler accepts %s' % (stack_protect_flag)) if flag_supported: conf.ADD_CFLAGS('%s' % (stack_protect_flag)) break flag_supported = conf.check(fragment=''' #include int main(void) { char t[100000]; while (fgets(t, sizeof(t), stdin)); return 0; } ''', execute=0, cflags=[ '-Werror', '-fstack-clash-protection'], mandatory=False, msg='Checking if compiler accepts -fstack-clash-protection') if flag_supported: conf.ADD_CFLAGS('-fstack-clash-protection') if Options.options.debug: conf.ADD_CFLAGS('-g', testflags=True) if Options.options.developer: conf.env.DEVELOPER_MODE = True conf.ADD_CFLAGS('-g', testflags=True) conf.ADD_CFLAGS('-Wall', testflags=True) conf.ADD_CFLAGS('-Wshadow', testflags=True) conf.ADD_CFLAGS('-Wmissing-prototypes', testflags=True) if CHECK_CODE(conf, 'struct a { int b; }; struct c { struct a d; } e = { };', 'CHECK_C99_INIT', link=False, cflags='-Wmissing-field-initializers -Werror=missing-field-initializers', msg="Checking C99 init of nested structs."): conf.ADD_CFLAGS('-Wmissing-field-initializers', testflags=True) conf.ADD_CFLAGS('-Wformat-overflow=2', testflags=True) conf.ADD_CFLAGS('-Wformat-zero-length', testflags=True) conf.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags=True) conf.ADD_CFLAGS('-fno-common', testflags=True) conf.ADD_CFLAGS('-Werror=address', testflags=True) # we add these here to ensure that -Wstrict-prototypes is not set during configure conf.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes', testflags=True) conf.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings', testflags=True) conf.ADD_CFLAGS('-Werror-implicit-function-declaration', testflags=True) conf.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith', testflags=True) conf.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement', testflags=True) conf.ADD_CFLAGS('-Werror=return-type -Wreturn-type', 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) conf.ADD_CFLAGS('-Werror=format-security -Wformat-security', testflags=True, prereq_flags='-Wformat') # This check is because for ldb_search(), a NULL format string # is not an error, but some compilers complain about that. if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], ''' int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2))); int main(void) { testformat(0); return 0; } '''): if not 'EXTRA_CFLAGS' in conf.env: conf.env['EXTRA_CFLAGS'] = [] conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format")) if Options.options.picky_developer: conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror -Wno-error=deprecated-declarations', testflags=True) conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Wno-error=tautological-compare', testflags=True) if Options.options.fatal_errors: conf.ADD_CFLAGS('-Wfatal-errors', testflags=True) if Options.options.pedantic: conf.ADD_CFLAGS('-W', testflags=True) if (Options.options.address_sanitizer or Options.options.undefined_sanitizer): conf.ADD_CFLAGS('-g -O1', testflags=True) if Options.options.address_sanitizer: conf.ADD_CFLAGS('-fno-omit-frame-pointer', testflags=True) conf.ADD_CFLAGS('-fsanitize=address', testflags=True) conf.ADD_LDFLAGS('-fsanitize=address', testflags=True) conf.env['ADDRESS_SANITIZER'] = True if Options.options.undefined_sanitizer: conf.ADD_CFLAGS('-fsanitize=undefined', testflags=True) conf.ADD_CFLAGS('-fsanitize=null', testflags=True) conf.ADD_CFLAGS('-fsanitize=alignment', testflags=True) conf.ADD_LDFLAGS('-fsanitize=undefined', testflags=True) conf.env['UNDEFINED_SANITIZER'] = True # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS} # environment variables which are only used the for final build. # # The CFLAGS and LDFLAGS environment variables are also # used for the configure checks which might impact their results. conf.add_os_flags('ADDITIONAL_CFLAGS') if conf.env.ADDITIONAL_CFLAGS and conf.CHECK_CFLAGS(conf.env['ADDITIONAL_CFLAGS']): conf.env['EXTRA_CFLAGS'].extend(conf.env['ADDITIONAL_CFLAGS']) conf.add_os_flags('ADDITIONAL_LDFLAGS') if conf.env.ADDITIONAL_LDFLAGS and conf.CHECK_LDFLAGS(conf.env['ADDITIONAL_LDFLAGS']): conf.env['EXTRA_LDFLAGS'].extend(conf.env['ADDITIONAL_LDFLAGS']) if path is None: conf.write_config_header('default/config.h', top=True, remove=False) else: conf.write_config_header(os.path.join(conf.variant, path), remove=False) for key in conf.env.define_key: conf.undefine(key, from_env=False) conf.env.define_key = [] conf.SAMBA_CROSS_CHECK_COMPLETE() @conf def CONFIG_PATH(conf, name, default): '''setup a configurable path''' if not name in conf.env: if default[0] == '/': conf.env[name] = default else: conf.env[name] = conf.env['PREFIX'] + default @conf def ADD_NAMED_CFLAGS(conf, name, flags, testflags=False, prereq_flags=[]): '''add some CFLAGS to the command line optionally set testflags to ensure all the flags work ''' prereq_flags = TO_LIST(prereq_flags) if testflags: ok_flags=[] for f in flags.split(): if CHECK_CFLAGS(conf, [f] + prereq_flags): ok_flags.append(f) flags = ok_flags if not name in conf.env: conf.env[name] = [] conf.env[name].extend(TO_LIST(flags)) @conf def ADD_CFLAGS(conf, flags, testflags=False, prereq_flags=[]): '''add some CFLAGS to the command line optionally set testflags to ensure all the flags work ''' ADD_NAMED_CFLAGS(conf, 'EXTRA_CFLAGS', flags, testflags=testflags, prereq_flags=prereq_flags) @conf def ADD_LDFLAGS(conf, flags, testflags=False): '''add some LDFLAGS to the command line optionally set testflags to ensure all the flags work this will return the flags that are added, if any ''' if testflags: ok_flags=[] for f in flags.split(): if CHECK_LDFLAGS(conf, f): ok_flags.append(f) flags = ok_flags if not 'EXTRA_LDFLAGS' in conf.env: conf.env['EXTRA_LDFLAGS'] = [] conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags)) return flags @conf def ADD_EXTRA_INCLUDES(conf, includes): '''add some extra include directories to all builds''' if not 'EXTRA_INCLUDES' in conf.env: conf.env['EXTRA_INCLUDES'] = [] conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes)) def CURRENT_CFLAGS(bld, target, cflags, allow_warnings=False, hide_symbols=False): '''work out the current flags. local flags are added first''' ret = TO_LIST(cflags) if not 'EXTRA_CFLAGS' in bld.env: list = [] else: list = bld.env['EXTRA_CFLAGS']; ret.extend(list) if not allow_warnings and 'PICKY_CFLAGS' in bld.env: list = bld.env['PICKY_CFLAGS']; ret.extend(list) if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR: ret.append(bld.env.VISIBILITY_CFLAGS) return ret @conf def CHECK_CC_ENV(conf): """trim whitespaces from 'CC'. The build farm sometimes puts a space at the start""" if os.environ.get('CC'): conf.env.CC = TO_LIST(os.environ.get('CC')) @conf def SETUP_CONFIGURE_CACHE(conf, enable): '''enable/disable cache of configure results''' if enable: # when -C is chosen, we will use a private cache and will # not look into system includes. This roughtly matches what # autoconf does with -C cache_path = os.path.join(conf.bldnode.abspath(), '.confcache') mkdir_p(cache_path) Options.cache_global = os.environ['WAFCACHE'] = cache_path else: # when -C is not chosen we will not cache configure checks # We set the recursion limit low to prevent waf from spending # a lot of time on the signatures of the files. Options.cache_global = os.environ['WAFCACHE'] = '' preproc.recursion_limit = 1 # in either case we don't need to scan system includes preproc.go_absolute = False @conf def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf): if not sys.platform.startswith("openbsd"): # we don't want any libraries or modules to rely on runtime # resolution of symbols conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True) if (conf.env.undefined_ignore_ldflags == [] and conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup'])): conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup'] ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py0000660000000000000000000000152613573675413021752 0ustar rootroot00000000000000# waf build tool for building automatic prototypes from C source import os from waflib import Build from samba_utils import SET_TARGET_TYPE, os_path_relpath def SAMBA_AUTOPROTO(bld, header, source): '''rule for samba prototype generation''' bld.SET_BUILD_GROUP('prototypes') relpath = os_path_relpath(bld.path.abspath(), bld.srcnode.abspath()) name = os.path.join(relpath, header) SET_TARGET_TYPE(bld, name, 'PROTOTYPE') t = bld( name = name, source = source, target = header, update_outputs=True, ext_out='.c', before ='c', rule = '${PERL} "${SCRIPT}/mkproto.pl" --srcdir=.. --builddir=. --public=/dev/null --private="${TGT}" ${SRC}' ) t.env.SCRIPT = os.path.join(bld.srcnode.abspath(), 'source4/script') Build.BuildContext.SAMBA_AUTOPROTO = SAMBA_AUTOPROTO ldb-2.0.8/buildtools/wafsamba/samba_bundled.py0000660000000000000000000002257213573675413021337 0ustar rootroot00000000000000# functions to support bundled libraries import sys from waflib import Build, Options, Logs from waflib.Configure import conf from wafsamba import samba_utils def PRIVATE_NAME(bld, name, private_extension, private_library): '''possibly rename a library to include a bundled extension''' if not private_library: return name # we now use the same private name for libraries as the public name. # see http://git.samba.org/?p=tridge/junkcode.git;a=tree;f=shlib for a # demonstration that this is the right thing to do # also see http://lists.samba.org/archive/samba-technical/2011-January/075816.html if private_extension: return name extension = bld.env.PRIVATE_EXTENSION if extension and name.startswith('%s' % extension): return name if extension and name.endswith('%s' % extension): return name return "%s-%s" % (name, extension) def target_in_list(target, lst, default): for l in lst: if target == l: return True if '!' + target == l: return False if l == 'ALL': return True if l == 'NONE': return False return default def BUILTIN_LIBRARY(bld, name): '''return True if a library should be builtin instead of being built as a shared lib''' return target_in_list(name, bld.env.BUILTIN_LIBRARIES, False) Build.BuildContext.BUILTIN_LIBRARY = BUILTIN_LIBRARY def BUILTIN_DEFAULT(opt, builtins): '''set a comma separated default list of builtin libraries for this package''' if 'BUILTIN_LIBRARIES_DEFAULT' in Options.options.__dict__: return Options.options.__dict__['BUILTIN_LIBRARIES_DEFAULT'] = builtins Options.OptionsContext.BUILTIN_DEFAULT = BUILTIN_DEFAULT def PRIVATE_EXTENSION_DEFAULT(opt, extension, noextension=''): '''set a default private library extension''' if 'PRIVATE_EXTENSION_DEFAULT' in Options.options.__dict__: return Options.options.__dict__['PRIVATE_EXTENSION_DEFAULT'] = extension Options.options.__dict__['PRIVATE_EXTENSION_EXCEPTION'] = noextension Options.OptionsContext.PRIVATE_EXTENSION_DEFAULT = PRIVATE_EXTENSION_DEFAULT def minimum_library_version(conf, libname, default): '''allow override of mininum system library version''' minlist = Options.options.MINIMUM_LIBRARY_VERSION if not minlist: return default for m in minlist.split(','): a = m.split(':') if len(a) != 2: Logs.error("Bad syntax for --minimum-library-version of %s" % m) sys.exit(1) if a[0] == libname: return a[1] return default @conf def LIB_MAY_BE_BUNDLED(conf, libname): if libname in conf.env.SYSTEM_LIBS: return False if libname in conf.env.BUNDLED_LIBS: return True if '!%s' % libname in conf.env.BUNDLED_LIBS: return False if 'NONE' in conf.env.BUNDLED_LIBS: return False return True @conf def LIB_MUST_BE_BUNDLED(conf, libname): if libname in conf.env.BUNDLED_LIBS: return True if '!%s' % libname in conf.env.BUNDLED_LIBS: return False if 'ALL' in conf.env.BUNDLED_LIBS: return True return False @conf def LIB_MUST_BE_PRIVATE(conf, libname): return ('ALL' in conf.env.PRIVATE_LIBS or libname in conf.env.PRIVATE_LIBS) @conf def CHECK_BUNDLED_SYSTEM_PKG(conf, libname, minversion='0.0.0', maxversion=None, version_blacklist=[], onlyif=None, implied_deps=None, pkg=None): '''check if a library is available as a system library. This only tries using pkg-config ''' return conf.CHECK_BUNDLED_SYSTEM(libname, minversion=minversion, maxversion=maxversion, version_blacklist=version_blacklist, onlyif=onlyif, implied_deps=implied_deps, pkg=pkg) @conf def CHECK_BUNDLED_SYSTEM(conf, libname, minversion='0.0.0', maxversion=None, version_blacklist=[], checkfunctions=None, headers=None, checkcode=None, onlyif=None, implied_deps=None, require_headers=True, pkg=None, set_target=True): '''check if a library is available as a system library. this first tries via pkg-config, then if that fails tries by testing for a specified function in the specified lib ''' # We always do a logic validation of 'onlyif' first missing = [] if onlyif: for l in samba_utils.TO_LIST(onlyif): f = 'FOUND_SYSTEMLIB_%s' % l if not f in conf.env: Logs.error('ERROR: CHECK_BUNDLED_SYSTEM(%s) - ' % (libname) + 'missing prerequisite check for ' + 'system library %s, onlyif=%r' % (l, onlyif)) sys.exit(1) if not conf.env[f]: missing.append(l) found = 'FOUND_SYSTEMLIB_%s' % libname if found in conf.env: return conf.env[found] if conf.LIB_MUST_BE_BUNDLED(libname): conf.env[found] = False return False # see if the library should only use a system version if another dependent # system version is found. That prevents possible use of mixed library # versions if missing: if not conf.LIB_MAY_BE_BUNDLED(libname): Logs.error('ERROR: Use of system library %s depends on missing system library/libraries %r' % (libname, missing)) sys.exit(1) conf.env[found] = False return False def check_functions_headers_code(): '''helper function for CHECK_BUNDLED_SYSTEM''' if require_headers and headers and not conf.CHECK_HEADERS(headers, lib=libname): return False if checkfunctions is not None: ok = conf.CHECK_FUNCS_IN(checkfunctions, libname, headers=headers, empty_decl=False, set_target=False) if not ok: return False if checkcode is not None: define='CHECK_BUNDLED_SYSTEM_%s' % libname.upper() ok = conf.CHECK_CODE(checkcode, lib=libname, headers=headers, local_include=False, msg=msg, define=define) conf.CONFIG_RESET(define) if not ok: return False return True minversion = minimum_library_version(conf, libname, minversion) msg = 'Checking for system %s' % libname msg_ver = [] if minversion != '0.0.0': msg_ver.append('>=%s' % minversion) if maxversion is not None: msg_ver.append('<=%s' % maxversion) for v in version_blacklist: msg_ver.append('!=%s' % v) if msg_ver != []: msg += " (%s)" % (" ".join(msg_ver)) uselib_store=libname.upper() if pkg is None: pkg = libname version_checks = '%s >= %s' % (pkg, minversion) if maxversion is not None: version_checks += ' %s <= %s' % (pkg, maxversion) for v in version_blacklist: version_checks += ' %s != %s' % (pkg, v) # try pkgconfig first if (conf.CHECK_CFG(package=pkg, args='"%s" --cflags --libs' % (version_checks), msg=msg, uselib_store=uselib_store) and check_functions_headers_code()): if set_target: conf.SET_TARGET_TYPE(libname, 'SYSLIB') conf.env[found] = True if implied_deps: conf.SET_SYSLIB_DEPS(libname, implied_deps) return True if checkfunctions is not None: if check_functions_headers_code(): conf.env[found] = True if implied_deps: conf.SET_SYSLIB_DEPS(libname, implied_deps) if set_target: conf.SET_TARGET_TYPE(libname, 'SYSLIB') return True conf.env[found] = False if not conf.LIB_MAY_BE_BUNDLED(libname): Logs.error('ERROR: System library %s of version %s not found, and bundling disabled' % (libname, minversion)) sys.exit(1) return False def tuplize_version(version): return tuple([int(x) for x in version.split(".")]) @conf def CHECK_BUNDLED_SYSTEM_PYTHON(conf, libname, modulename, minversion='0.0.0'): '''check if a python module is available on the system and has the specified minimum version. ''' if conf.LIB_MUST_BE_BUNDLED(libname): return False # see if the library should only use a system version if another dependent # system version is found. That prevents possible use of mixed library # versions minversion = minimum_library_version(conf, libname, minversion) try: m = __import__(modulename) except ImportError: found = False else: try: version = m.__version__ except AttributeError: found = False else: found = tuplize_version(version) >= tuplize_version(minversion) if not found and not conf.LIB_MAY_BE_BUNDLED(libname): Logs.error('ERROR: Python module %s of version %s not found, and bundling disabled' % (libname, minversion)) sys.exit(1) return found def NONSHARED_BINARY(bld, name): '''return True if a binary should be built without non-system shared libs''' return target_in_list(name, bld.env.NONSHARED_BINARIES, False) Build.BuildContext.NONSHARED_BINARY = NONSHARED_BINARY ldb-2.0.8/buildtools/wafsamba/samba_conftests.py0000660000000000000000000004025213573675413021725 0ustar rootroot00000000000000# a set of config tests that use the samba_autoconf functions # to test for commonly needed configuration options import os, shutil, re from waflib import Build, Configure, Utils, Options, Logs, Errors from waflib.Configure import conf from samba_utils import TO_LIST, ADD_LD_LIBRARY_PATH, get_string def add_option(self, *k, **kw): '''syntax help: provide the "match" attribute to opt.add_option() so that folders can be added to specific config tests''' Options.OptionsContext.parser = self match = kw.get('match', []) if match: del kw['match'] opt = self.parser.add_option(*k, **kw) opt.match = match return opt Options.OptionsContext.add_option = add_option @conf def check(self, *k, **kw): '''Override the waf defaults to inject --with-directory options''' if not 'env' in kw: kw['env'] = self.env.derive() # match the configuration test with specific options, for example: # --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv" additional_dirs = [] if 'msg' in kw: msg = kw['msg'] for x in Options.OptionsContext.parser.parser.option_list: if getattr(x, 'match', None) and msg in x.match: d = getattr(Options.options, x.dest, '') if d: additional_dirs.append(d) # we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below def add_options_dir(dirs, env): for x in dirs: if not x in env.CPPPATH: env.CPPPATH = [os.path.join(x, 'include')] + env.CPPPATH if not x in env.LIBPATH: env.LIBPATH = [os.path.join(x, 'lib')] + env.LIBPATH add_options_dir(additional_dirs, kw['env']) self.validate_c(kw) self.start_msg(kw['msg']) ret = None try: ret = self.run_c_code(*k, **kw) except Configure.ConfigurationError as e: self.end_msg(kw['errmsg'], 'YELLOW') if 'mandatory' in kw and kw['mandatory']: if Logs.verbose > 1: raise else: self.fatal('the configuration failed (see %r)' % self.log.name) else: kw['success'] = ret self.end_msg(self.ret_msg(kw['okmsg'], kw)) # success! keep the CPPPATH/LIBPATH add_options_dir(additional_dirs, self.env) self.post_check(*k, **kw) if not kw.get('execute', False): return ret == 0 return ret @conf def CHECK_ICONV(conf, define='HAVE_NATIVE_ICONV'): '''check if the iconv library is installed optionally pass a define''' if conf.CHECK_FUNCS_IN('iconv_open', 'iconv', checklibc=True, headers='iconv.h'): conf.DEFINE(define, 1) return True return False @conf def CHECK_LARGEFILE(conf, define='HAVE_LARGEFILE'): '''see what we need for largefile support''' getconf_cflags = conf.CHECK_COMMAND(['getconf', 'LFS_CFLAGS']); if getconf_cflags is not False: if (conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', define='WORKING_GETCONF_LFS_CFLAGS', execute=True, cflags=getconf_cflags, msg='Checking getconf large file support flags work')): conf.ADD_CFLAGS(getconf_cflags) getconf_cflags_list=TO_LIST(getconf_cflags) for flag in getconf_cflags_list: if flag[:2] == "-D": flag_split = flag[2:].split('=') if len(flag_split) == 1: conf.DEFINE(flag_split[0], '1') else: conf.DEFINE(flag_split[0], flag_split[1]) if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', define, execute=True, msg='Checking for large file support without additional flags'): return True if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', define, execute=True, cflags='-D_FILE_OFFSET_BITS=64', msg='Checking for -D_FILE_OFFSET_BITS=64'): conf.DEFINE('_FILE_OFFSET_BITS', 64) return True if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', define, execute=True, cflags='-D_LARGE_FILES', msg='Checking for -D_LARGE_FILES'): conf.DEFINE('_LARGE_FILES', 1) return True return False @conf def CHECK_C_PROTOTYPE(conf, function, prototype, define, headers=None, msg=None): '''verify that a C prototype matches the one on the current system''' if not conf.CHECK_DECLS(function, headers=headers): return False if not msg: msg = 'Checking C prototype for %s' % function return conf.CHECK_CODE('%s; void *_x = (void *)%s' % (prototype, function), define=define, local_include=False, headers=headers, link=False, execute=False, msg=msg) @conf def CHECK_CHARSET_EXISTS(conf, charset, outcharset='UCS-2LE', headers=None, define=None): '''check that a named charset is able to be used with iconv_open() for conversion to a target charset ''' msg = 'Checking if can we convert from %s to %s' % (charset, outcharset) if define is None: define = 'HAVE_CHARSET_%s' % charset.upper().replace('-','_') return conf.CHECK_CODE(''' iconv_t cd = iconv_open("%s", "%s"); if (cd == 0 || cd == (iconv_t)-1) return -1; ''' % (charset, outcharset), define=define, execute=True, msg=msg, lib='iconv', headers=headers) def find_config_dir(conf): '''find a directory to run tests in''' k = 0 while k < 10000: dir = os.path.join(conf.bldnode.abspath(), '.conf_check_%d' % k) try: shutil.rmtree(dir) except OSError: pass try: os.stat(dir) except: break k += 1 try: os.makedirs(dir) except: conf.fatal('cannot create a configuration test folder %r' % dir) try: os.stat(dir) except: conf.fatal('cannot use the configuration test folder %r' % dir) return dir @conf def CHECK_SHLIB_INTRASINC_NAME_FLAGS(conf, msg): ''' check if the waf default flags for setting the name of lib are ok ''' snip = ''' int foo(int v) { return v * 2; } ''' return conf.check(features='c cshlib',vnum="1",fragment=snip,msg=msg, mandatory=False) @conf def CHECK_NEED_LC(conf, msg): '''check if we need -lc''' dir = find_config_dir(conf) env = conf.env bdir = os.path.join(dir, 'testbuild2') if not os.path.exists(bdir): os.makedirs(bdir) subdir = os.path.join(dir, "liblctest") os.makedirs(subdir) Utils.writef(os.path.join(subdir, 'liblc1.c'), '#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n') bld = Build.BuildContext() bld.log = conf.log bld.all_envs.update(conf.all_envs) bld.all_envs['default'] = env bld.lst_variants = bld.all_envs.keys() bld.load_dirs(dir, bdir) bld.rescan(bld.srcnode) bld(features='c cshlib', source='liblctest/liblc1.c', ldflags=conf.env['EXTRA_LDFLAGS'], target='liblc', name='liblc') try: bld.compile() conf.check_message(msg, '', True) return True except: conf.check_message(msg, '', False) return False @conf def CHECK_SHLIB_W_PYTHON(conf, msg): '''check if we need -undefined dynamic_lookup''' dir = find_config_dir(conf) snip = ''' #include #include #define environ (*_NSGetEnviron()) static PyObject *ldb_module = NULL; int foo(int v) { extern char **environ; environ[0] = 1; ldb_module = PyImport_ImportModule("ldb"); return v * 2; } ''' return conf.check(features='c cshlib',uselib='PYEMBED',fragment=snip,msg=msg, mandatory=False) # this one is quite complex, and should probably be broken up # into several parts. I'd quite like to create a set of CHECK_COMPOUND() # functions that make writing complex compound tests like this much easier @conf def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): '''see if the platform supports building libraries''' if msg is None: if rpath: msg = "rpath library support" else: msg = "building library support" dir = find_config_dir(conf) bdir = os.path.join(dir, 'testbuild') if not os.path.exists(bdir): os.makedirs(bdir) env = conf.env subdir = os.path.join(dir, "libdir") os.makedirs(subdir) Utils.writef(os.path.join(subdir, 'lib1.c'), 'int lib_func(void) { return 42; }\n') Utils.writef(os.path.join(dir, 'main.c'), 'int lib_func(void);\n' 'int main(void) {return !(lib_func() == 42);}\n') bld = Build.BuildContext() bld.log = conf.log bld.all_envs.update(conf.all_envs) bld.all_envs['default'] = env bld.lst_variants = bld.all_envs.keys() bld.load_dirs(dir, bdir) bld.rescan(bld.srcnode) ldflags = [] if version_script: ldflags.append("-Wl,--version-script=%s/vscript" % bld.path.abspath()) Utils.writef(os.path.join(dir,'vscript'), 'TEST_1.0A2 { global: *; };\n') bld(features='c cshlib', source='libdir/lib1.c', target='libdir/lib1', ldflags=ldflags, name='lib1') o = bld(features='c cprogram', source='main.c', target='prog1', uselib_local='lib1') if rpath: o.rpath=os.path.join(bdir, 'default/libdir') # compile the program try: bld.compile() except: conf.check_message(msg, '', False) return False # path for execution lastprog = o.link_task.outputs[0].abspath(env) if not rpath: if 'LD_LIBRARY_PATH' in os.environ: old_ld_library_path = os.environ['LD_LIBRARY_PATH'] else: old_ld_library_path = None ADD_LD_LIBRARY_PATH(os.path.join(bdir, 'default/libdir')) # we need to run the program, try to get its result args = conf.SAMBA_CROSS_ARGS(msg=msg) proc = Utils.subprocess.Popen([lastprog] + args, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE) (out, err) = proc.communicate() w = conf.log.write w(str(out)) w('\n') w(str(err)) w('\nreturncode %r\n' % proc.returncode) ret = (proc.returncode == 0) if not rpath: os.environ['LD_LIBRARY_PATH'] = old_ld_library_path or '' conf.check_message(msg, '', ret) return ret @conf def CHECK_PERL_MANPAGE(conf, msg=None, section=None): '''work out what extension perl uses for manpages''' if msg is None: if section: msg = "perl man%s extension" % section else: msg = "perl manpage generation" conf.start_msg(msg) dir = find_config_dir(conf) bdir = os.path.join(dir, 'testbuild') if not os.path.exists(bdir): os.makedirs(bdir) Utils.writef(os.path.join(bdir, 'Makefile.PL'), """ use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'WafTest', 'EXE_FILES' => [ 'WafTest' ] ); """) back = os.path.abspath('.') os.chdir(bdir) proc = Utils.subprocess.Popen(['perl', 'Makefile.PL'], stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE) (out, err) = proc.communicate() os.chdir(back) ret = (proc.returncode == 0) if not ret: conf.end_msg('not found', color='YELLOW') return if section: man = Utils.readf(os.path.join(bdir,'Makefile')) m = re.search('MAN%sEXT\s+=\s+(\w+)' % section, man) if not m: conf.end_msg('not found', color='YELLOW') return ext = m.group(1) conf.end_msg(ext) return ext conf.end_msg('ok') return True @conf def CHECK_COMMAND(conf, cmd, msg=None, define=None, on_target=True, boolean=False): '''run a command and return result''' if msg is None: msg = 'Checking %s' % ' '.join(cmd) conf.COMPOUND_START(msg) cmd = cmd[:] if on_target: cmd.extend(conf.SAMBA_CROSS_ARGS(msg=msg)) try: ret = get_string(Utils.cmd_output(cmd)) except: conf.COMPOUND_END(False) return False if boolean: conf.COMPOUND_END('ok') if define: conf.DEFINE(define, '1') else: ret = ret.strip() conf.COMPOUND_END(ret) if define: conf.DEFINE(define, ret, quote=True) return ret @conf def CHECK_UNAME(conf): '''setup SYSTEM_UNAME_* defines''' ret = True for v in "sysname machine release version".split(): if not conf.CHECK_CODE(''' int printf(const char *format, ...); struct utsname n; if (uname(&n) == -1) return -1; printf("%%s", n.%s); ''' % v, define='SYSTEM_UNAME_%s' % v.upper(), execute=True, define_ret=True, quote=True, headers='sys/utsname.h', local_include=False, msg="Checking uname %s type" % v): ret = False return ret @conf def CHECK_INLINE(conf): '''check for the right value for inline''' conf.COMPOUND_START('Checking for inline') for i in ['inline', '__inline__', '__inline']: ret = conf.CHECK_CODE(''' typedef int foo_t; static %s foo_t static_foo () {return 0; } %s foo_t foo () {return 0; }\n''' % (i, i), define='INLINE_MACRO', addmain=False, link=False) if ret: if i != 'inline': conf.DEFINE('inline', i, quote=False) break if not ret: conf.COMPOUND_END(ret) else: conf.COMPOUND_END(i) return ret @conf def CHECK_XSLTPROC_MANPAGES(conf): '''check if xsltproc can run with the given stylesheets''' if not conf.CONFIG_SET('XSLTPROC'): conf.find_program('xsltproc', var='XSLTPROC') if not conf.CONFIG_SET('XSLTPROC'): return False s='http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' conf.CHECK_COMMAND('%s --nonet %s 2> /dev/null' % (conf.env.get_flat('XSLTPROC'), s), msg='Checking for stylesheet %s' % s, define='XSLTPROC_MANPAGES', on_target=False, boolean=True) if not conf.CONFIG_SET('XSLTPROC_MANPAGES'): print("A local copy of the docbook.xsl wasn't found on your system" \ " consider installing package like docbook-xsl") # # Determine the standard libpath for the used compiler, # so we can later use that to filter out these standard # library paths when some tools like cups-config or # python-config report standard lib paths with their # ldflags (-L...) # @conf def CHECK_STANDARD_LIBPATH(conf): # at least gcc and clang support this: try: cmd = conf.env.CC + ['-print-search-dirs'] out = get_string(Utils.cmd_output(cmd)).split('\n') except ValueError: # option not supported by compiler - use a standard list of directories dirlist = [ '/usr/lib', '/usr/lib64' ] except: raise Errors.WafError('Unexpected error running "%s"' % (cmd)) else: dirlist = [] for line in out: line = line.strip() if line.startswith("libraries: ="): dirliststr = line[len("libraries: ="):] dirlist = [ os.path.normpath(x) for x in dirliststr.split(':') ] break conf.env.STANDARD_LIBPATH = dirlist ldb-2.0.8/buildtools/wafsamba/samba_cross.py0000660000000000000000000001362213573675413021047 0ustar rootroot00000000000000# functions for handling cross-compilation import os, sys, re, shlex from waflib import Utils, Logs, Options, Errors, Context from waflib.Configure import conf from wafsamba import samba_utils real_Popen = None ANSWER_UNKNOWN = (254, "") ANSWER_NO = (1, "") ANSWER_OK = (0, "") cross_answers_incomplete = False def add_answer(ca_file, msg, answer): '''add an answer to a set of cross answers''' try: f = open(ca_file, 'a') except: Logs.error("Unable to open cross-answers file %s" % ca_file) sys.exit(1) (retcode, retstring) = answer # if retstring is more than one line then we probably # don't care about its actual content (the tests should # yield one-line output in order to comply with the cross-answer # format) retstring = retstring.strip() if len(retstring.split('\n')) > 1: retstring = '' answer = (retcode, retstring) if answer == ANSWER_OK: f.write('%s: OK\n' % msg) elif answer == ANSWER_UNKNOWN: f.write('%s: UNKNOWN\n' % msg) elif answer == ANSWER_NO: f.write('%s: NO\n' % msg) else: if retcode == 0: f.write('%s: "%s"\n' % (msg, retstring)) else: f.write('%s: (%d, "%s")\n' % (msg, retcode, retstring)) f.close() def cross_answer(ca_file, msg): '''return a (retcode,retstring) tuple from a answers file''' try: f = open(ca_file, 'r') except: return ANSWER_UNKNOWN for line in f: line = line.strip() if line == '' or line[0] == '#': continue if line.find(':') != -1: a = line.split(':', 1) thismsg = a[0].strip() if thismsg != msg: continue ans = a[1].strip() if ans == "OK" or ans == "YES": f.close() return ANSWER_OK elif ans == "UNKNOWN": f.close() return ANSWER_UNKNOWN elif ans == "FAIL" or ans == "NO": f.close() return ANSWER_NO elif ans[0] == '"': f.close() return (0, ans.strip('"')) elif ans[0] == "'": f.close() return (0, ans.strip("'")) else: m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans) if m: f.close() return (int(m.group(1)), m.group(2)) else: raise Errors.WafError("Bad answer format '%s' in %s" % (line, ca_file)) f.close() return ANSWER_UNKNOWN class cross_Popen(Utils.subprocess.Popen): '''cross-compilation wrapper for Popen''' def __init__(*k, **kw): (obj, args) = k use_answers = False ans = ANSWER_UNKNOWN # Three possibilities: # 1. Only cross-answers - try the cross-answers file, and if # there's no corresponding answer, add to the file and mark # the configure process as unfinished. # 2. Only cross-execute - get the answer from cross-execute # 3. Both - try the cross-answers file, and if there is no # corresponding answer - use cross-execute to get an answer, # and add that answer to the file. if '--cross-answers' in args: # when --cross-answers is set, then change the arguments # to use the cross answers if available use_answers = True i = args.index('--cross-answers') ca_file = args[i+1] msg = args[i+2] ans = cross_answer(ca_file, msg) if '--cross-execute' in args and ans == ANSWER_UNKNOWN: # when --cross-execute is set, then change the arguments # to use the cross emulator i = args.index('--cross-execute') newargs = shlex.split(args[i+1]) newargs.extend(args[0:i]) if use_answers: p = real_Popen(newargs, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=kw.get('env', {})) ce_out, ce_err = p.communicate() ans = (p.returncode, samba_utils.get_string(ce_out)) add_answer(ca_file, msg, ans) else: args = newargs if use_answers: if ans == ANSWER_UNKNOWN: global cross_answers_incomplete cross_answers_incomplete = True add_answer(ca_file, msg, ans) (retcode, retstring) = ans args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)] real_Popen.__init__(*(obj, args), **kw) @conf def SAMBA_CROSS_ARGS(conf, msg=None): '''get test_args to pass when running cross compiled binaries''' if not conf.env.CROSS_COMPILE: return [] global real_Popen if real_Popen is None: real_Popen = Utils.subprocess.Popen Utils.subprocess.Popen = cross_Popen Utils.run_process = Utils.run_regular_process Utils.get_process = Utils.alloc_process_pool = Utils.nada ret = [] if conf.env.CROSS_EXECUTE: ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE]) if conf.env.CROSS_ANSWERS: if msg is None: raise Errors.WafError("Cannot have NULL msg in cross-answers") ret.extend(['--cross-answers', os.path.join(Context.launch_dir, conf.env.CROSS_ANSWERS), msg]) if ret == []: raise Errors.WafError("Cannot cross-compile without either --cross-execute or --cross-answers") return ret @conf def SAMBA_CROSS_CHECK_COMPLETE(conf): '''check if we have some unanswered questions''' global cross_answers_incomplete if conf.env.CROSS_COMPILE and cross_answers_incomplete: raise Errors.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS) return True ldb-2.0.8/buildtools/wafsamba/samba_deps.py0000660000000000000000000012176313573675413020657 0ustar rootroot00000000000000# Samba automatic dependency handling and project rules import os, sys, re from waflib import Build, Options, Logs, Utils, Errors from waflib.Logs import debug from waflib.Configure import conf from waflib import ConfigSet from samba_bundled import BUILTIN_LIBRARY from samba_utils import LOCAL_CACHE, TO_LIST, get_tgt_list, unique_list, os_path_relpath from samba_autoconf import library_flags @conf def ADD_GLOBAL_DEPENDENCY(ctx, dep): '''add a dependency for all binaries and libraries''' if not 'GLOBAL_DEPENDENCIES' in ctx.env: ctx.env.GLOBAL_DEPENDENCIES = [] ctx.env.GLOBAL_DEPENDENCIES.append(dep) @conf def BREAK_CIRCULAR_LIBRARY_DEPENDENCIES(ctx): '''indicate that circular dependencies between libraries should be broken.''' ctx.env.ALLOW_CIRCULAR_LIB_DEPENDENCIES = True @conf def SET_SYSLIB_DEPS(conf, target, deps): '''setup some implied dependencies for a SYSLIB''' cache = LOCAL_CACHE(conf, 'SYSLIB_DEPS') cache[target] = deps def expand_subsystem_deps(bld): '''expand the reverse dependencies resulting from subsystem attributes of modules. This is walking over the complete list of declared subsystems, and expands the samba_deps_extended list for any module<->subsystem dependencies''' subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') targets = LOCAL_CACHE(bld, 'TARGET_TYPE') for subsystem_name in subsystem_list: bld.ASSERT(subsystem_name in targets, "Subsystem target %s not declared" % subsystem_name) type = targets[subsystem_name] if type == 'DISABLED' or type == 'EMPTY': continue # for example, # subsystem_name = dcerpc_server (a subsystem) # subsystem = dcerpc_server (a subsystem object) # module_name = rpc_epmapper (a module within the dcerpc_server subsystem) # module = rpc_epmapper (a module object within the dcerpc_server subsystem) subsystem = bld.get_tgen_by_name(subsystem_name) bld.ASSERT(subsystem is not None, "Unable to find subsystem %s" % subsystem_name) for d in subsystem_list[subsystem_name]: module_name = d['TARGET'] module_type = targets[module_name] if module_type in ['DISABLED', 'EMPTY']: continue bld.ASSERT(subsystem is not None, "Subsystem target %s for %s (%s) not found" % (subsystem_name, module_name, module_type)) if module_type in ['SUBSYSTEM']: # if a module is a plain object type (not a library) then the # subsystem it is part of needs to have it as a dependency, so targets # that depend on this subsystem get the modules of that subsystem subsystem.samba_deps_extended.append(module_name) subsystem.samba_deps_extended = unique_list(subsystem.samba_deps_extended) def build_dependencies(self): '''This builds the dependency list for a target. It runs after all the targets are declared The reason this is not just done in the SAMBA_*() rules is that we have no way of knowing the full dependency list for a target until we have all of the targets declared. ''' if self.samba_type in ['LIBRARY', 'BINARY', 'PYTHON']: self.uselib = list(self.final_syslibs) self.uselib_local = list(self.final_libs) self.add_objects = list(self.final_objects) # extra link flags from pkg_config libs = self.final_syslibs.copy() (cflags, ldflags, cpppath) = library_flags(self, list(libs)) new_ldflags = getattr(self, 'samba_ldflags', [])[:] new_ldflags.extend(ldflags) self.ldflags = new_ldflags if getattr(self, 'allow_undefined_symbols', False) and self.env.undefined_ldflags: for f in self.env.undefined_ldflags: self.ldflags.remove(f) if getattr(self, 'allow_undefined_symbols', False) and self.env.undefined_ignore_ldflags: for f in self.env.undefined_ignore_ldflags: self.ldflags.append(f) debug('deps: computed dependencies for target %s: uselib=%s uselib_local=%s add_objects=%s', self.sname, self.uselib, self.uselib_local, self.add_objects) if self.samba_type in ['SUBSYSTEM']: # this is needed for the cflags of libs that come from pkg_config self.uselib = list(self.final_syslibs) self.uselib.extend(list(self.direct_syslibs)) for lib in self.final_libs: t = self.bld.get_tgen_by_name(lib) self.uselib.extend(list(t.final_syslibs)) self.uselib = unique_list(self.uselib) if getattr(self, 'uselib', None): up_list = [] for l in self.uselib: up_list.append(l.upper()) self.uselib = up_list def build_includes(self): '''This builds the right set of includes for a target. One tricky part of this is that the includes= attribute for a target needs to use paths which are relative to that targets declaration directory (which we can get at via t.path). The way this works is the includes list gets added as samba_includes in the main build task declaration. Then this function runs after all of the tasks are declared, and it processes the samba_includes attribute to produce a includes= attribute ''' if getattr(self, 'samba_includes', None) is None: return bld = self.bld inc_deps = includes_objects(bld, self, set(), {}) includes = [] # maybe add local includes if getattr(self, 'local_include', True) and getattr(self, 'local_include_first', True): includes.append('.') includes.extend(self.samba_includes_extended) if 'EXTRA_INCLUDES' in bld.env and getattr(self, 'global_include', True): includes.extend(bld.env['EXTRA_INCLUDES']) includes.append('#') inc_set = set() inc_abs = [] for d in inc_deps: t = bld.get_tgen_by_name(d) bld.ASSERT(t is not None, "Unable to find dependency %s for %s" % (d, self.sname)) inclist = getattr(t, 'samba_includes_extended', [])[:] if getattr(t, 'local_include', True): inclist.append('.') if inclist == []: continue tpath = t.samba_abspath for inc in inclist: npath = tpath + '/' + inc if not npath in inc_set: inc_abs.append(npath) inc_set.add(npath) mypath = self.path.abspath(bld.env) for inc in inc_abs: relpath = os_path_relpath(inc, mypath) includes.append(relpath) if getattr(self, 'local_include', True) and not getattr(self, 'local_include_first', True): includes.append('.') # now transform the includes list to be relative to the top directory # which is represented by '#' in waf. This allows waf to cache the # includes lists more efficiently includes_top = [] for i in includes: if i[0] == '#': # some are already top based includes_top.append(i) continue absinc = os.path.join(self.path.abspath(), i) relinc = os_path_relpath(absinc, self.bld.srcnode.abspath()) includes_top.append('#' + relinc) self.includes = unique_list(includes_top) debug('deps: includes for target %s: includes=%s', self.sname, self.includes) def add_init_functions(self): '''This builds the right set of init functions''' bld = self.bld subsystems = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') # cope with the separated object lists from BINARY and LIBRARY targets sname = self.sname if sname.endswith('.objlist'): sname = sname[0:-8] modules = [] if sname in subsystems: modules.append(sname) m = getattr(self, 'samba_modules', None) if m is not None: modules.extend(TO_LIST(m)) m = getattr(self, 'samba_subsystem', None) if m is not None: modules.append(m) if 'pyembed' in self.features: return sentinel = getattr(self, 'init_function_sentinel', 'NULL') targets = LOCAL_CACHE(bld, 'TARGET_TYPE') cflags = getattr(self, 'samba_cflags', [])[:] if modules == []: sname = sname.replace('-','_') sname = sname.replace('.','_') sname = sname.replace('/','_') cflags.append('-DSTATIC_%s_MODULES=%s' % (sname, sentinel)) if sentinel == 'NULL': proto = "extern void __%s_dummy_module_proto(void)" % (sname) cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (sname, proto)) self.cflags = cflags return for m in modules: bld.ASSERT(m in subsystems, "No init_function defined for module '%s' in target '%s'" % (m, self.sname)) init_fn_list = [] for d in subsystems[m]: if targets[d['TARGET']] != 'DISABLED': init_fn_list.append(d['INIT_FUNCTION']) if init_fn_list == []: cflags.append('-DSTATIC_%s_MODULES=%s' % (m, sentinel)) if sentinel == 'NULL': proto = "extern void __%s_dummy_module_proto(void)" % (m) cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto)) else: cflags.append('-DSTATIC_%s_MODULES=%s' % (m, ','.join(init_fn_list) + ',' + sentinel)) proto='' for f in init_fn_list: proto += '_MODULE_PROTO(%s)' % f proto += "extern void __%s_dummy_module_proto(void)" % (m) cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto)) self.cflags = cflags def check_duplicate_sources(bld, tgt_list): '''see if we are compiling the same source file more than once''' debug('deps: checking for duplicate sources') targets = LOCAL_CACHE(bld, 'TARGET_TYPE') for t in tgt_list: source_list = TO_LIST(getattr(t, 'source', '')) tpath = os.path.normpath(os_path_relpath(t.path.abspath(bld.env), t.env.BUILD_DIRECTORY + '/default')) obj_sources = set() for s in source_list: if not isinstance(s, str): print('strange path in check_duplicate_sources %r' % s) s = s.abspath() p = os.path.normpath(os.path.join(tpath, s)) if p in obj_sources: Logs.error("ERROR: source %s appears twice in target '%s'" % (p, t.sname)) sys.exit(1) obj_sources.add(p) t.samba_source_set = obj_sources subsystems = {} # build a list of targets that each source file is part of for t in tgt_list: if not targets[t.sname] in [ 'LIBRARY', 'BINARY', 'PYTHON' ]: continue for obj in t.add_objects: t2 = t.bld.get_tgen_by_name(obj) source_set = getattr(t2, 'samba_source_set', set()) for s in source_set: if not s in subsystems: subsystems[s] = {} if not t.sname in subsystems[s]: subsystems[s][t.sname] = [] subsystems[s][t.sname].append(t2.sname) for s in subsystems: if len(subsystems[s]) > 1 and Options.options.SHOW_DUPLICATES: Logs.warn("WARNING: source %s is in more than one target: %s" % (s, subsystems[s].keys())) for tname in subsystems[s]: if len(subsystems[s][tname]) > 1: raise Errors.WafError("ERROR: source %s is in more than one subsystem of target '%s': %s" % (s, tname, subsystems[s][tname])) return True def check_group_ordering(bld, tgt_list): '''see if we have any dependencies that violate the group ordering It is an error for a target to depend on a target from a later build group ''' def group_name(g): tm = bld.task_manager return [x for x in tm.groups_names if id(tm.groups_names[x]) == id(g)][0] for g in bld.task_manager.groups: gname = group_name(g) for t in g.tasks_gen: t.samba_group = gname grp_map = {} idx = 0 for g in bld.task_manager.groups: name = group_name(g) grp_map[name] = idx idx += 1 targets = LOCAL_CACHE(bld, 'TARGET_TYPE') ret = True for t in tgt_list: tdeps = getattr(t, 'add_objects', []) + getattr(t, 'uselib_local', []) for d in tdeps: t2 = bld.get_tgen_by_name(d) if t2 is None: continue map1 = grp_map[t.samba_group] map2 = grp_map[t2.samba_group] if map2 > map1: Logs.error("Target %r in build group %r depends on target %r from later build group %r" % ( t.sname, t.samba_group, t2.sname, t2.samba_group)) ret = False return ret Build.BuildContext.check_group_ordering = check_group_ordering def show_final_deps(bld, tgt_list): '''show the final dependencies for all targets''' targets = LOCAL_CACHE(bld, 'TARGET_TYPE') for t in tgt_list: if not targets[t.sname] in ['LIBRARY', 'BINARY', 'PYTHON', 'SUBSYSTEM']: continue debug('deps: final dependencies for target %s: uselib=%s uselib_local=%s add_objects=%s', t.sname, t.uselib, getattr(t, 'uselib_local', []), getattr(t, 'add_objects', [])) def add_samba_attributes(bld, tgt_list): '''ensure a target has a the required samba attributes''' targets = LOCAL_CACHE(bld, 'TARGET_TYPE') for t in tgt_list: if t.name != '': t.sname = t.name else: t.sname = t.target t.samba_type = targets[t.sname] t.samba_abspath = t.path.abspath(bld.env) t.samba_deps_extended = t.samba_deps[:] t.samba_includes_extended = TO_LIST(t.samba_includes)[:] t.cflags = getattr(t, 'samba_cflags', '') def replace_grouping_libraries(bld, tgt_list): '''replace dependencies based on grouping libraries If a library is marked as a grouping library, then any target that depends on a subsystem that is part of that grouping library gets that dependency replaced with a dependency on the grouping library ''' targets = LOCAL_CACHE(bld, 'TARGET_TYPE') grouping = {} # find our list of grouping libraries, mapped from the subsystems they depend on for t in tgt_list: if not getattr(t, 'grouping_library', False): continue for dep in t.samba_deps_extended: bld.ASSERT(dep in targets, "grouping library target %s not declared in %s" % (dep, t.sname)) if targets[dep] == 'SUBSYSTEM': grouping[dep] = t.sname # now replace any dependencies on elements of grouping libraries for t in tgt_list: for i in range(len(t.samba_deps_extended)): dep = t.samba_deps_extended[i] if dep in grouping: if t.sname != grouping[dep]: debug("deps: target %s: replacing dependency %s with grouping library %s" % (t.sname, dep, grouping[dep])) t.samba_deps_extended[i] = grouping[dep] def build_direct_deps(bld, tgt_list): '''build the direct_objects and direct_libs sets for each target''' targets = LOCAL_CACHE(bld, 'TARGET_TYPE') syslib_deps = LOCAL_CACHE(bld, 'SYSLIB_DEPS') global_deps = bld.env.GLOBAL_DEPENDENCIES global_deps_exclude = set() for dep in global_deps: t = bld.get_tgen_by_name(dep) for d in t.samba_deps: # prevent loops from the global dependencies list global_deps_exclude.add(d) global_deps_exclude.add(d + '.objlist') for t in tgt_list: t.direct_objects = set() t.direct_libs = set() t.direct_syslibs = set() deps = t.samba_deps_extended[:] if getattr(t, 'samba_use_global_deps', False) and not t.sname in global_deps_exclude: deps.extend(global_deps) for d in deps: if d == t.sname: continue if not d in targets: Logs.error("Unknown dependency '%s' in '%s'" % (d, t.sname)) sys.exit(1) if targets[d] in [ 'EMPTY', 'DISABLED' ]: continue if targets[d] == 'PYTHON' and targets[t.sname] != 'PYTHON' and t.sname.find('.objlist') == -1: # this check should be more restrictive, but for now we have pidl-generated python # code that directly depends on other python modules Logs.error('ERROR: Target %s has dependency on python module %s' % (t.sname, d)) sys.exit(1) if targets[d] == 'SYSLIB': t.direct_syslibs.add(d) if d in syslib_deps: for implied in TO_LIST(syslib_deps[d]): if BUILTIN_LIBRARY(bld, implied): t.direct_objects.add(implied) elif targets[implied] == 'SYSLIB': t.direct_syslibs.add(implied) elif targets[implied] in ['LIBRARY', 'MODULE']: t.direct_libs.add(implied) else: Logs.error('Implied dependency %s in %s is of type %s' % ( implied, t.sname, targets[implied])) sys.exit(1) continue t2 = bld.get_tgen_by_name(d) if t2 is None: Logs.error("no task %s of type %s in %s" % (d, targets[d], t.sname)) sys.exit(1) if t2.samba_type in [ 'LIBRARY', 'MODULE' ]: t.direct_libs.add(d) elif t2.samba_type in [ 'SUBSYSTEM', 'ASN1', 'PYTHON' ]: t.direct_objects.add(d) debug('deps: built direct dependencies') def dependency_loop(loops, t, target): '''add a dependency loop to the loops dictionary''' if t.sname == target: return if not target in loops: loops[target] = set() if not t.sname in loops[target]: loops[target].add(t.sname) def indirect_libs(bld, t, chain, loops): '''recursively calculate the indirect library dependencies for a target An indirect library is a library that results from a dependency on a subsystem ''' ret = getattr(t, 'indirect_libs', None) if ret is not None: return ret ret = set() for obj in t.direct_objects: if obj in chain: dependency_loop(loops, t, obj) continue chain.add(obj) t2 = bld.get_tgen_by_name(obj) r2 = indirect_libs(bld, t2, chain, loops) chain.remove(obj) ret = ret.union(t2.direct_libs) ret = ret.union(r2) for obj in indirect_objects(bld, t, set(), loops): if obj in chain: dependency_loop(loops, t, obj) continue chain.add(obj) t2 = bld.get_tgen_by_name(obj) r2 = indirect_libs(bld, t2, chain, loops) chain.remove(obj) ret = ret.union(t2.direct_libs) ret = ret.union(r2) t.indirect_libs = ret return ret def indirect_objects(bld, t, chain, loops): '''recursively calculate the indirect object dependencies for a target indirect objects are the set of objects from expanding the subsystem dependencies ''' ret = getattr(t, 'indirect_objects', None) if ret is not None: return ret ret = set() for lib in t.direct_objects: if lib in chain: dependency_loop(loops, t, lib) continue chain.add(lib) t2 = bld.get_tgen_by_name(lib) r2 = indirect_objects(bld, t2, chain, loops) chain.remove(lib) ret = ret.union(t2.direct_objects) ret = ret.union(r2) t.indirect_objects = ret return ret def extended_objects(bld, t, chain): '''recursively calculate the extended object dependencies for a target extended objects are the union of: - direct objects - indirect objects - direct and indirect objects of all direct and indirect libraries ''' ret = getattr(t, 'extended_objects', None) if ret is not None: return ret ret = set() ret = ret.union(t.final_objects) for lib in t.final_libs: if lib in chain: continue t2 = bld.get_tgen_by_name(lib) chain.add(lib) r2 = extended_objects(bld, t2, chain) chain.remove(lib) ret = ret.union(t2.final_objects) ret = ret.union(r2) t.extended_objects = ret return ret def includes_objects(bld, t, chain, inc_loops): '''recursively calculate the includes object dependencies for a target includes dependencies come from either library or object dependencies ''' ret = getattr(t, 'includes_objects', None) if ret is not None: return ret ret = t.direct_objects.copy() ret = ret.union(t.direct_libs) for obj in t.direct_objects: if obj in chain: dependency_loop(inc_loops, t, obj) continue chain.add(obj) t2 = bld.get_tgen_by_name(obj) r2 = includes_objects(bld, t2, chain, inc_loops) chain.remove(obj) ret = ret.union(t2.direct_objects) ret = ret.union(r2) for lib in t.direct_libs: if lib in chain: dependency_loop(inc_loops, t, lib) continue chain.add(lib) t2 = bld.get_tgen_by_name(lib) if t2 is None: targets = LOCAL_CACHE(bld, 'TARGET_TYPE') Logs.error('Target %s of type %s not found in direct_libs for %s' % ( lib, targets[lib], t.sname)) sys.exit(1) r2 = includes_objects(bld, t2, chain, inc_loops) chain.remove(lib) ret = ret.union(t2.direct_objects) ret = ret.union(r2) t.includes_objects = ret return ret def break_dependency_loops(bld, tgt_list): '''find and break dependency loops''' loops = {} inc_loops = {} # build up the list of loops for t in tgt_list: indirect_objects(bld, t, set(), loops) indirect_libs(bld, t, set(), loops) includes_objects(bld, t, set(), inc_loops) # break the loops for t in tgt_list: if t.sname in loops: for attr in ['direct_objects', 'indirect_objects', 'direct_libs', 'indirect_libs']: objs = getattr(t, attr, set()) setattr(t, attr, objs.difference(loops[t.sname])) for loop in loops: debug('deps: Found dependency loops for target %s : %s', loop, loops[loop]) for loop in inc_loops: debug('deps: Found include loops for target %s : %s', loop, inc_loops[loop]) # expand the loops mapping by one level for loop in loops.copy(): for tgt in loops[loop]: if tgt in loops: loops[loop] = loops[loop].union(loops[tgt]) for loop in inc_loops.copy(): for tgt in inc_loops[loop]: if tgt in inc_loops: inc_loops[loop] = inc_loops[loop].union(inc_loops[tgt]) # expand indirect subsystem and library loops for loop in loops.copy(): t = bld.get_tgen_by_name(loop) if t.samba_type in ['SUBSYSTEM']: loops[loop] = loops[loop].union(t.indirect_objects) loops[loop] = loops[loop].union(t.direct_objects) if t.samba_type in ['LIBRARY','PYTHON']: loops[loop] = loops[loop].union(t.indirect_libs) loops[loop] = loops[loop].union(t.direct_libs) if loop in loops[loop]: loops[loop].remove(loop) # expand indirect includes loops for loop in inc_loops.copy(): t = bld.get_tgen_by_name(loop) inc_loops[loop] = inc_loops[loop].union(t.includes_objects) if loop in inc_loops[loop]: inc_loops[loop].remove(loop) # add in the replacement dependencies for t in tgt_list: for loop in loops: for attr in ['indirect_objects', 'indirect_libs']: objs = getattr(t, attr, set()) if loop in objs: diff = loops[loop].difference(objs) if t.sname in diff: diff.remove(t.sname) if diff: debug('deps: Expanded target %s of type %s from loop %s by %s', t.sname, t.samba_type, loop, diff) objs = objs.union(diff) setattr(t, attr, objs) for loop in inc_loops: objs = getattr(t, 'includes_objects', set()) if loop in objs: diff = inc_loops[loop].difference(objs) if t.sname in diff: diff.remove(t.sname) if diff: debug('deps: Expanded target %s includes of type %s from loop %s by %s', t.sname, t.samba_type, loop, diff) objs = objs.union(diff) setattr(t, 'includes_objects', objs) def reduce_objects(bld, tgt_list): '''reduce objects by looking for indirect object dependencies''' rely_on = {} for t in tgt_list: t.extended_objects = None changed = False for type in ['BINARY', 'PYTHON', 'LIBRARY']: for t in tgt_list: if t.samba_type != type: continue # if we will indirectly link to a target then we don't need it new = t.final_objects.copy() for l in t.final_libs: t2 = bld.get_tgen_by_name(l) t2_obj = extended_objects(bld, t2, set()) dup = new.intersection(t2_obj) if t.sname in rely_on: dup = dup.difference(rely_on[t.sname]) if dup: # Do not remove duplicates of BUILTINS d = next(iter(dup)) if BUILTIN_LIBRARY(bld, d): continue debug('deps: removing dups from %s of type %s: %s also in %s %s', t.sname, t.samba_type, dup, t2.samba_type, l) new = new.difference(dup) changed = True if not l in rely_on: rely_on[l] = set() rely_on[l] = rely_on[l].union(dup) t.final_objects = new if not changed: return False # add back in any objects that were relied upon by the reduction rules for r in rely_on: t = bld.get_tgen_by_name(r) t.final_objects = t.final_objects.union(rely_on[r]) return True def show_library_loop(bld, lib1, lib2, path, seen): '''show the detailed path of a library loop between lib1 and lib2''' t = bld.get_tgen_by_name(lib1) if not lib2 in getattr(t, 'final_libs', set()): return for d in t.samba_deps_extended: if d in seen: continue seen.add(d) path2 = path + '=>' + d if d == lib2: Logs.warn('library loop path: ' + path2) return show_library_loop(bld, d, lib2, path2, seen) seen.remove(d) def calculate_final_deps(bld, tgt_list, loops): '''calculate the final library and object dependencies''' for t in tgt_list: # start with the maximum possible list t.final_libs = t.direct_libs.union(indirect_libs(bld, t, set(), loops)) t.final_objects = t.direct_objects.union(indirect_objects(bld, t, set(), loops)) for t in tgt_list: # don't depend on ourselves if t.sname in t.final_libs: t.final_libs.remove(t.sname) if t.sname in t.final_objects: t.final_objects.remove(t.sname) # handle any non-shared binaries for t in tgt_list: if t.samba_type == 'BINARY' and bld.NONSHARED_BINARY(t.sname): subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') targets = LOCAL_CACHE(bld, 'TARGET_TYPE') # replace lib deps with objlist deps for l in t.final_libs: objname = l + '.objlist' t2 = bld.get_tgen_by_name(objname) if t2 is None: Logs.error('ERROR: subsystem %s not found' % objname) sys.exit(1) t.final_objects.add(objname) t.final_objects = t.final_objects.union(extended_objects(bld, t2, set())) if l in subsystem_list: # its a subsystem - we also need the contents of any modules for d in subsystem_list[l]: module_name = d['TARGET'] if targets[module_name] == 'LIBRARY': objname = module_name + '.objlist' elif targets[module_name] == 'SUBSYSTEM': objname = module_name else: continue t2 = bld.get_tgen_by_name(objname) if t2 is None: Logs.error('ERROR: subsystem %s not found' % objname) sys.exit(1) t.final_objects.add(objname) t.final_objects = t.final_objects.union(extended_objects(bld, t2, set())) t.final_libs = set() # find any library loops for t in tgt_list: if t.samba_type in ['LIBRARY', 'PYTHON']: for l in t.final_libs.copy(): t2 = bld.get_tgen_by_name(l) if t.sname in t2.final_libs: if getattr(bld.env, "ALLOW_CIRCULAR_LIB_DEPENDENCIES", False): # we could break this in either direction. If one of the libraries # has a version number, and will this be distributed publicly, then # we should make it the lower level library in the DAG Logs.warn('deps: removing library loop %s from %s' % (t.sname, t2.sname)) dependency_loop(loops, t, t2.sname) t2.final_libs.remove(t.sname) else: Logs.error('ERROR: circular library dependency between %s and %s' % (t.sname, t2.sname)) show_library_loop(bld, t.sname, t2.sname, t.sname, set()) show_library_loop(bld, t2.sname, t.sname, t2.sname, set()) sys.exit(1) for loop in loops: debug('deps: Found dependency loops for target %s : %s', loop, loops[loop]) # we now need to make corrections for any library loops we broke up # any target that depended on the target of the loop and doesn't # depend on the source of the loop needs to get the loop source added for type in ['BINARY','PYTHON','LIBRARY','BINARY']: for t in tgt_list: if t.samba_type != type: continue for loop in loops: if loop in t.final_libs: diff = loops[loop].difference(t.final_libs) if t.sname in diff: diff.remove(t.sname) if t.sname in diff: diff.remove(t.sname) # make sure we don't recreate the loop again! for d in diff.copy(): t2 = bld.get_tgen_by_name(d) if t2.samba_type == 'LIBRARY': if t.sname in t2.final_libs: debug('deps: removing expansion %s from %s', d, t.sname) diff.remove(d) if diff: debug('deps: Expanded target %s by loop %s libraries (loop %s) %s', t.sname, loop, loops[loop], diff) t.final_libs = t.final_libs.union(diff) # remove objects that are also available in linked libs count = 0 while reduce_objects(bld, tgt_list): count += 1 if count > 100: Logs.warn("WARNING: Unable to remove all inter-target object duplicates") break debug('deps: Object reduction took %u iterations', count) # add in any syslib dependencies for t in tgt_list: if not t.samba_type in ['BINARY','PYTHON','LIBRARY','SUBSYSTEM']: continue syslibs = set() for d in t.final_objects: t2 = bld.get_tgen_by_name(d) syslibs = syslibs.union(t2.direct_syslibs) # this adds the indirect syslibs as well, which may not be needed # depending on the linker flags for d in t.final_libs: t2 = bld.get_tgen_by_name(d) syslibs = syslibs.union(t2.direct_syslibs) t.final_syslibs = syslibs # find any unresolved library loops lib_loop_error = False for t in tgt_list: if t.samba_type in ['LIBRARY', 'PYTHON']: for l in t.final_libs.copy(): t2 = bld.get_tgen_by_name(l) if t.sname in t2.final_libs: Logs.error('ERROR: Unresolved library loop %s from %s' % (t.sname, t2.sname)) lib_loop_error = True if lib_loop_error: sys.exit(1) debug('deps: removed duplicate dependencies') def show_dependencies(bld, target, seen): '''recursively show the dependencies of target''' if target in seen: return t = bld.get_tgen_by_name(target) if t is None: Logs.error("ERROR: Unable to find target '%s'" % target) sys.exit(1) Logs.info('%s(OBJECTS): %s' % (target, t.direct_objects)) Logs.info('%s(LIBS): %s' % (target, t.direct_libs)) Logs.info('%s(SYSLIBS): %s' % (target, t.direct_syslibs)) seen.add(target) for t2 in t.direct_objects: show_dependencies(bld, t2, seen) def show_object_duplicates(bld, tgt_list): '''show a list of object files that are included in more than one library or binary''' targets = LOCAL_CACHE(bld, 'TARGET_TYPE') used_by = {} Logs.info("showing duplicate objects") for t in tgt_list: if not targets[t.sname] in [ 'LIBRARY', 'PYTHON' ]: continue for n in getattr(t, 'final_objects', set()): t2 = bld.get_tgen_by_name(n) if not n in used_by: used_by[n] = set() used_by[n].add(t.sname) for n in used_by: if len(used_by[n]) > 1: Logs.info("target '%s' is used by %s" % (n, used_by[n])) Logs.info("showing indirect dependency counts (sorted by count)") def indirect_count(t1, t2): return len(t2.indirect_objects) - len(t1.indirect_objects) sorted_list = sorted(tgt_list, cmp=indirect_count) for t in sorted_list: if len(t.indirect_objects) > 1: Logs.info("%s depends on %u indirect objects" % (t.sname, len(t.indirect_objects))) ###################################################################### # this provides a way to save our dependency calculations between runs savedeps_version = 3 savedeps_inputs = ['samba_deps', 'samba_includes', 'local_include', 'local_include_first', 'samba_cflags', 'source', 'grouping_library', 'samba_ldflags', 'allow_undefined_symbols', 'use_global_deps', 'global_include' ] savedeps_outputs = ['uselib', 'uselib_local', 'add_objects', 'includes', 'cflags', 'ldflags', 'samba_deps_extended', 'final_libs'] savedeps_outenv = ['INC_PATHS'] savedeps_envvars = ['NONSHARED_BINARIES', 'GLOBAL_DEPENDENCIES', 'EXTRA_CFLAGS', 'EXTRA_LDFLAGS', 'EXTRA_INCLUDES' ] savedeps_caches = ['GLOBAL_DEPENDENCIES', 'TARGET_TYPE', 'INIT_FUNCTIONS', 'SYSLIB_DEPS'] savedeps_files = ['buildtools/wafsamba/samba_deps.py'] def save_samba_deps(bld, tgt_list): '''save the dependency calculations between builds, to make further builds faster''' denv = ConfigSet.ConfigSet() denv.version = savedeps_version denv.savedeps_inputs = savedeps_inputs denv.savedeps_outputs = savedeps_outputs denv.input = {} denv.output = {} denv.outenv = {} denv.caches = {} denv.envvar = {} denv.files = {} for f in savedeps_files: denv.files[f] = os.stat(os.path.join(bld.srcnode.abspath(), f)).st_mtime for c in savedeps_caches: denv.caches[c] = LOCAL_CACHE(bld, c) for e in savedeps_envvars: denv.envvar[e] = bld.env[e] for t in tgt_list: # save all the input attributes for each target tdeps = {} for attr in savedeps_inputs: v = getattr(t, attr, None) if v is not None: tdeps[attr] = v if tdeps != {}: denv.input[t.sname] = tdeps # save all the output attributes for each target tdeps = {} for attr in savedeps_outputs: v = getattr(t, attr, None) if v is not None: tdeps[attr] = v if tdeps != {}: denv.output[t.sname] = tdeps tdeps = {} for attr in savedeps_outenv: if attr in t.env: tdeps[attr] = t.env[attr] if tdeps != {}: denv.outenv[t.sname] = tdeps depsfile = os.path.join(bld.cache_dir, "sambadeps") denv.store_fast(depsfile) def load_samba_deps(bld, tgt_list): '''load a previous set of build dependencies if possible''' depsfile = os.path.join(bld.cache_dir, "sambadeps") denv = ConfigSet.ConfigSet() try: debug('deps: checking saved dependencies') denv.load_fast(depsfile) if (denv.version != savedeps_version or denv.savedeps_inputs != savedeps_inputs or denv.savedeps_outputs != savedeps_outputs): return False except Exception: return False # check if critical files have changed for f in savedeps_files: if f not in denv.files: return False if denv.files[f] != os.stat(os.path.join(bld.srcnode.abspath(), f)).st_mtime: return False # check if caches are the same for c in savedeps_caches: if c not in denv.caches or denv.caches[c] != LOCAL_CACHE(bld, c): return False # check if caches are the same for e in savedeps_envvars: if e not in denv.envvar or denv.envvar[e] != bld.env[e]: return False # check inputs are the same for t in tgt_list: tdeps = {} for attr in savedeps_inputs: v = getattr(t, attr, None) if v is not None: tdeps[attr] = v if t.sname in denv.input: olddeps = denv.input[t.sname] else: olddeps = {} if tdeps != olddeps: #print '%s: \ntdeps=%s \nodeps=%s' % (t.sname, tdeps, olddeps) return False # put outputs in place for t in tgt_list: if not t.sname in denv.output: continue tdeps = denv.output[t.sname] for a in tdeps: setattr(t, a, tdeps[a]) # put output env vars in place for t in tgt_list: if not t.sname in denv.outenv: continue tdeps = denv.outenv[t.sname] for a in tdeps: t.env[a] = tdeps[a] debug('deps: loaded saved dependencies') return True def check_project_rules(bld): '''check the project rules - ensuring the targets are sane''' loops = {} inc_loops = {} tgt_list = get_tgt_list(bld) add_samba_attributes(bld, tgt_list) force_project_rules = (Options.options.SHOWDEPS or Options.options.SHOW_DUPLICATES) if not force_project_rules and load_samba_deps(bld, tgt_list): return timer = Utils.Timer() bld.new_rules = True Logs.info("Checking project rules ...") debug('deps: project rules checking started') expand_subsystem_deps(bld) debug("deps: expand_subsystem_deps: %s" % str(timer)) replace_grouping_libraries(bld, tgt_list) debug("deps: replace_grouping_libraries: %s" % str(timer)) build_direct_deps(bld, tgt_list) debug("deps: build_direct_deps: %s" % str(timer)) break_dependency_loops(bld, tgt_list) debug("deps: break_dependency_loops: %s" % str(timer)) if Options.options.SHOWDEPS: show_dependencies(bld, Options.options.SHOWDEPS, set()) calculate_final_deps(bld, tgt_list, loops) debug("deps: calculate_final_deps: %s" % str(timer)) if Options.options.SHOW_DUPLICATES: show_object_duplicates(bld, tgt_list) # run the various attribute generators for f in [ build_dependencies, build_includes, add_init_functions ]: debug('deps: project rules checking %s', f) for t in tgt_list: f(t) debug("deps: %s: %s" % (f, str(timer))) debug('deps: project rules stage1 completed') if not check_duplicate_sources(bld, tgt_list): Logs.error("Duplicate sources present - aborting") sys.exit(1) debug("deps: check_duplicate_sources: %s" % str(timer)) if not bld.check_group_ordering(tgt_list): Logs.error("Bad group ordering - aborting") sys.exit(1) debug("deps: check_group_ordering: %s" % str(timer)) show_final_deps(bld, tgt_list) debug("deps: show_final_deps: %s" % str(timer)) debug('deps: project rules checking completed - %u targets checked', len(tgt_list)) if not bld.is_install: save_samba_deps(bld, tgt_list) debug("deps: save_samba_deps: %s" % str(timer)) Logs.info("Project rules pass") def CHECK_PROJECT_RULES(bld): '''enable checking of project targets for sanity''' if bld.env.added_project_rules: return bld.env.added_project_rules = True bld.add_pre_fun(check_project_rules) Build.BuildContext.CHECK_PROJECT_RULES = CHECK_PROJECT_RULES ldb-2.0.8/buildtools/wafsamba/samba_dist.py0000660000000000000000000002124313573675413020657 0ustar rootroot00000000000000# customised version of 'waf dist' for Samba tools # uses git ls-files to get file lists import os, sys, tarfile from waflib import Utils, Scripting, Logs, Options from waflib.Configure import conf from samba_utils import os_path_relpath, get_string from waflib import Context dist_dirs = None dist_files = None dist_blacklist = "" dist_archive = None class Dist(Context.Context): # TODO remove cmd = 'dist' fun = 'dist' def execute(self): Context.g_module.dist() class DistCheck(Scripting.DistCheck): fun = 'distcheck' cmd = 'distcheck' def execute(self): Options.options.distcheck_args = '' if Context.g_module.distcheck is Scripting.distcheck: # default Context.g_module.distcheck(self) else: Context.g_module.distcheck() Context.g_module.dist() self.check() def get_arch_name(self): global dist_archive return dist_archive def make_distcheck_cmd(self, tmpdir): waf = os.path.abspath(sys.argv[0]) return [sys.executable, waf, 'configure', 'build', 'install', 'uninstall', '--destdir=' + tmpdir] def add_symlink(tar, fname, abspath, basedir): '''handle symlinks to directories that may move during packaging''' if not os.path.islink(abspath): return False tinfo = tar.gettarinfo(name=abspath, arcname=fname) tgt = os.readlink(abspath) if dist_dirs: # we need to find the target relative to the main directory # this is here to cope with symlinks into the buildtools # directory from within the standalone libraries in Samba. For example, # a symlink to ../../builtools/scripts/autogen-waf.sh needs # to be rewritten as a symlink to buildtools/scripts/autogen-waf.sh # when the tarball for talloc is built # the filename without the appname-version rel_fname = '/'.join(fname.split('/')[1:]) # join this with the symlink target tgt_full = os.path.join(os.path.dirname(rel_fname), tgt) # join with the base directory tgt_base = os.path.normpath(os.path.join(basedir, tgt_full)) # see if this is inside one of our dist_dirs for dir in dist_dirs.split(): if dir.find(':') != -1: destdir=dir.split(':')[1] dir=dir.split(':')[0] else: destdir = '.' if dir == basedir: # internal links don't get rewritten continue if dir == tgt_base[0:len(dir)] and tgt_base[len(dir)] == '/': new_tgt = destdir + tgt_base[len(dir):] tinfo.linkname = new_tgt break tinfo.uid = 0 tinfo.gid = 0 tinfo.uname = 'root' tinfo.gname = 'root' tar.addfile(tinfo) return True def add_tarfile(tar, fname, abspath, basedir): '''add a file to the tarball''' if add_symlink(tar, fname, abspath, basedir): return try: tinfo = tar.gettarinfo(name=abspath, arcname=fname) except OSError: Logs.error('Unable to find file %s - missing from git checkout?' % abspath) sys.exit(1) tinfo.uid = 0 tinfo.gid = 0 tinfo.uname = 'root' tinfo.gname = 'root' fh = open(abspath, "rb") tar.addfile(tinfo, fileobj=fh) fh.close() def vcs_dir_contents(path): """Return the versioned files under a path. :return: List of paths relative to path """ repo = path while repo != "/": if os.path.isdir(os.path.join(repo, ".git")): ls_files_cmd = [ 'git', 'ls-files', '--full-name', os_path_relpath(path, repo) ] cwd = None env = dict(os.environ) env["GIT_DIR"] = os.path.join(repo, ".git") break repo = os.path.dirname(repo) if repo == "/": raise Exception("unsupported or no vcs for %s" % path) return get_string(Utils.cmd_output(ls_files_cmd, cwd=cwd, env=env)).split('\n') def dist(appname='', version=''): def add_files_to_tarball(tar, srcdir, srcsubdir, dstdir, dstsubdir, blacklist, files): if blacklist is None: blacklist = [] for f in files: abspath = os.path.join(srcdir, f) if srcsubdir != '.': f = f[len(srcsubdir)+1:] # Remove files in the blacklist if f in blacklist: continue blacklisted = False # Remove directories in the blacklist for d in blacklist: if f.startswith(d): blacklisted = True if blacklisted: continue if os.path.isdir(abspath) and not os.path.islink(abspath): continue if dstsubdir != '.': f = dstsubdir + '/' + f fname = dstdir + '/' + f add_tarfile(tar, fname, abspath, srcsubdir) def list_directory_files(path): curdir = os.getcwd() os.chdir(srcdir) out_files = [] for root, dirs, files in os.walk(path): for f in files: out_files.append(os.path.join(root, f)) os.chdir(curdir) return out_files if not isinstance(appname, str) or not appname: # this copes with a mismatch in the calling arguments for dist() appname = Context.g_module.APPNAME version = Context.g_module.VERSION if not version: version = Context.g_module.VERSION srcdir = os.path.normpath( os.path.join(os.path.dirname(Context.g_module.root_path), Context.g_module.top)) if not dist_dirs: Logs.error('You must use samba_dist.DIST_DIRS() to set which directories to package') sys.exit(1) dist_base = '%s-%s' % (appname, version) if Options.options.SIGN_RELEASE: dist_name = '%s.tar' % (dist_base) tar = tarfile.open(dist_name, 'w') else: dist_name = '%s.tar.gz' % (dist_base) tar = tarfile.open(dist_name, 'w:gz') blacklist = dist_blacklist.split() for dir in dist_dirs.split(): if dir.find(':') != -1: destdir=dir.split(':')[1] dir=dir.split(':')[0] else: destdir = '.' absdir = os.path.join(srcdir, dir) try: files = vcs_dir_contents(absdir) except Exception as 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) if dist_files: for file in dist_files.split(): if file.find(':') != -1: destfile = file.split(':')[1] file = file.split(':')[0] else: destfile = file absfile = os.path.join(srcdir, file) if os.path.isdir(absfile) and not os.path.islink(absfile): destdir = destfile dir = file files = list_directory_files(dir) add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files) else: fname = dist_base + '/' + destfile add_tarfile(tar, fname, absfile, destfile) tar.close() if Options.options.SIGN_RELEASE: import gzip try: os.unlink(dist_name + '.asc') except OSError: pass cmd = "gpg --detach-sign --armor " + dist_name os.system(cmd) uncompressed_tar = open(dist_name, 'rb') compressed_tar = gzip.open(dist_name + '.gz', 'wb') while 1: buffer = uncompressed_tar.read(1048576) if buffer: compressed_tar.write(buffer) else: break uncompressed_tar.close() compressed_tar.close() os.unlink(dist_name) Logs.info('Created %s.gz %s.asc' % (dist_name, dist_name)) dist_name = dist_name + '.gz' else: Logs.info('Created %s' % dist_name) # TODO use the ctx object instead global dist_archive dist_archive = dist_name return dist_name @conf def DIST_DIRS(dirs): '''set the directories to package, relative to top srcdir''' global dist_dirs if not dist_dirs: dist_dirs = dirs @conf def DIST_FILES(files, extend=False): '''set additional files for packaging, relative to top srcdir''' global dist_files if not dist_files: dist_files = files elif extend: dist_files = dist_files + " " + files @conf def DIST_BLACKLIST(blacklist): '''set the files to exclude from packaging, relative to top srcdir''' global dist_blacklist if not dist_blacklist: dist_blacklist = blacklist Scripting.dist = dist ldb-2.0.8/buildtools/wafsamba/samba_git.py0000660000000000000000000000342013573675413020474 0ustar rootroot00000000000000import os import subprocess def find_git(env=None): """Find the git binary.""" if env is not None and 'GIT' in env: return env.get_flat('GIT') # Get version from GIT if os.path.exists("/usr/bin/git"): # this is useful when doing make dist without configuring return "/usr/bin/git" return None def has_submodules(path): """Check whether a source directory is git-versioned and has submodules. :param path: Path to Samba source directory """ return (os.path.isdir(os.path.join(path, ".git")) and os.path.isfile(os.path.join(path, ".gitmodules"))) def read_submodule_status(path, env=None): """Check status of submodules. :param path: Path to git directory :param env: Optional waf environment :return: Yields tuples with submodule relpath and status (one of: 'out-of-date', 'not-checked-out', 'up-to-date') :raise RuntimeError: raised when parsing of 'git submodule status' output fails. """ if not has_submodules(path): # No point in running git. return git = find_git(env) if git is None: return p = subprocess.Popen([git, "submodule", "status"], stdout=subprocess.PIPE, cwd=path) (stdout, stderr) = p.communicate(None) for l in stdout.splitlines(): l = l.rstrip() status = l[0] l = l[1:] parts = l.split(" ") if len(parts) > 2 and status in ("-", "+"): yield (parts[1], "out-of-date") elif len(parts) == 2 and status == "-": yield (parts[1], "not-checked-out") elif len(parts) > 2 and status == " ": yield (parts[1], "up-to-date") else: raise RuntimeError("Unable to parse submodule status: %r, %r" % (status, parts)) ldb-2.0.8/buildtools/wafsamba/samba_headers.py0000660000000000000000000001475213573675413021336 0ustar rootroot00000000000000# specialist handling of header files for Samba import os, re, sys, fnmatch from waflib import Build, Logs, Utils, Errors from samba_utils import TO_LIST, os_path_relpath def header_install_path(header, header_path): '''find the installation path for a header, given a header_path option''' if not header_path: return '' if not isinstance(header_path, list): return header_path for (p1, dir) in header_path: for p2 in TO_LIST(p1): if fnmatch.fnmatch(header, p2): return dir # default to current path return '' re_header = re.compile('^\s*#\s*include[ \t]*"([^"]+)"', re.I | re.M) # a dictionary mapping source header paths to public header paths header_map = {} def find_suggested_header(hpath): '''find a suggested header path to use''' base = os.path.basename(hpath) ret = [] for h in header_map: if os.path.basename(h) == base: ret.append('<%s>' % header_map[h]) ret.append('"%s"' % h) return ret def create_public_header(task): '''create a public header from a private one, output within the build tree''' src = task.inputs[0].abspath(task.env) tgt = task.outputs[0].bldpath(task.env) if os.path.exists(tgt): os.unlink(tgt) relsrc = os_path_relpath(src, task.env.TOPDIR) infile = open(src, mode='r') outfile = open(tgt, mode='w') linenumber = 0 search_paths = [ '', task.env.RELPATH ] for i in task.env.EXTRA_INCLUDES: if i.startswith('#'): search_paths.append(i[1:]) for line in infile: linenumber += 1 # allow some straight substitutions if task.env.public_headers_replace and line.strip() in task.env.public_headers_replace: outfile.write(task.env.public_headers_replace[line.strip()] + '\n') continue # see if its an include line m = re_header.match(line) if m is None: outfile.write(line) continue # its an include, get the header path hpath = m.group(1) if hpath.startswith("bin/default/"): hpath = hpath[12:] # some are always allowed if task.env.public_headers_skip and hpath in task.env.public_headers_skip: outfile.write(line) continue # work out the header this refers to found = False for s in search_paths: p = os.path.normpath(os.path.join(s, hpath)) if p in header_map: outfile.write("#include <%s>\n" % header_map[p]) found = True break if found: continue if task.env.public_headers_allow_broken: Logs.warn("Broken public header include '%s' in '%s'" % (hpath, relsrc)) outfile.write(line) continue # try to be nice to the developer by suggesting an alternative suggested = find_suggested_header(hpath) outfile.close() os.unlink(tgt) sys.stderr.write("%s:%u:Error: unable to resolve public header %s (maybe try one of %s)\n" % ( os.path.relpath(src, os.getcwd()), linenumber, hpath, suggested)) raise Errors.WafError("Unable to resolve header path '%s' in public header '%s' in directory %s" % ( hpath, relsrc, task.env.RELPATH)) infile.close() outfile.close() def public_headers_simple(bld, public_headers, header_path=None, public_headers_install=True): '''install some headers - simple version, no munging needed ''' if not public_headers_install: return for h in TO_LIST(public_headers): inst_path = header_install_path(h, header_path) if h.find(':') != -1: s = h.split(":") h_name = s[0] inst_name = s[1] else: h_name = h inst_name = os.path.basename(h) bld.INSTALL_FILES('${INCLUDEDIR}', h_name, destname=inst_name) def PUBLIC_HEADERS(bld, public_headers, header_path=None, public_headers_install=True): '''install some headers header_path may either be a string that is added to the INCLUDEDIR, or it can be a dictionary of wildcard patterns which map to destination directories relative to INCLUDEDIR ''' bld.SET_BUILD_GROUP('final') if not bld.env.build_public_headers: # in this case no header munging neeeded. Used for tdb, talloc etc public_headers_simple(bld, public_headers, header_path=header_path, public_headers_install=public_headers_install) return # create the public header in the given path # in the build tree for h in TO_LIST(public_headers): inst_path = header_install_path(h, header_path) if h.find(':') != -1: s = h.split(":") h_name = s[0] inst_name = s[1] else: h_name = h inst_name = os.path.basename(h) curdir = bld.path.abspath() relpath1 = os_path_relpath(bld.srcnode.abspath(), curdir) relpath2 = os_path_relpath(curdir, bld.srcnode.abspath()) targetdir = os.path.normpath(os.path.join(relpath1, bld.env.build_public_headers, inst_path)) if not os.path.exists(os.path.join(curdir, targetdir)): raise Errors.WafError("missing source directory %s for public header %s" % (targetdir, inst_name)) target = os.path.join(targetdir, inst_name) # the source path of the header, relative to the top of the source tree src_path = os.path.normpath(os.path.join(relpath2, h_name)) # the install path of the header, relative to the public include directory target_path = os.path.normpath(os.path.join(inst_path, inst_name)) header_map[src_path] = target_path t = bld.SAMBA_GENERATOR('HEADER_%s/%s/%s' % (relpath2, inst_path, inst_name), group='headers', rule=create_public_header, source=h_name, target=target) t.env.RELPATH = relpath2 t.env.TOPDIR = bld.srcnode.abspath() if not bld.env.public_headers_list: bld.env.public_headers_list = [] bld.env.public_headers_list.append(os.path.join(inst_path, inst_name)) if public_headers_install: bld.INSTALL_FILES('${INCLUDEDIR}', target, destname=os.path.join(inst_path, inst_name), flat=True) Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS ldb-2.0.8/buildtools/wafsamba/samba_install.py0000660000000000000000000002037513573675413021367 0ustar rootroot00000000000000########################### # this handles the magic we need to do for installing # with all the configure options that affect rpath and shared # library use import os from waflib import Utils, Errors from waflib.TaskGen import feature, before, after from samba_utils import LIB_PATH, MODE_755, install_rpath, build_rpath @feature('install_bin') @after('apply_core') @before('apply_link', 'apply_obj_vars') def install_binary(self): '''install a binary, taking account of the different rpath varients''' bld = self.bld # get the ldflags we will use for install and build install_ldflags = install_rpath(self) build_ldflags = build_rpath(bld) if not self.bld.is_install: # just need to set rpath if we are not installing self.env.RPATH = build_ldflags return # work out the install path, expanding variables install_path = getattr(self, 'samba_inst_path', None) or '${BINDIR}' install_path = bld.EXPAND_VARIABLES(install_path) orig_target = os.path.basename(self.target) if install_ldflags != build_ldflags: # we will be creating a new target name, and using that for the # install link. That stops us from overwriting the existing build # target, which has different ldflags self.target += '.inst' # setup the right rpath link flags for the install self.env.RPATH = install_ldflags if not self.samba_install: # this binary is marked not to be installed return # tell waf to install the right binary bld.install_as(os.path.join(install_path, orig_target), self.path.find_or_declare(self.target), chmod=MODE_755) @feature('install_lib') @after('apply_core') @before('apply_link', 'apply_obj_vars') def install_library(self): '''install a library, taking account of the different rpath varients''' if getattr(self, 'done_install_library', False): return bld = self.bld default_env = bld.all_envs['default'] try: install_ldflags = install_rpath(self) build_ldflags = build_rpath(bld) if not self.bld.is_install or not getattr(self, 'samba_install', True): # just need to set the build rpath if we are not installing self.env.RPATH = build_ldflags return # setup the install path, expanding variables install_path = getattr(self, 'samba_inst_path', None) if install_path is None: if getattr(self, 'private_library', False): install_path = '${PRIVATELIBDIR}' else: install_path = '${LIBDIR}' install_path = bld.EXPAND_VARIABLES(install_path) target_name = self.target if install_ldflags != build_ldflags: # we will be creating a new target name, and using that for the # install link. That stops us from overwriting the existing build # target, which has different ldflags self.done_install_library = True t = self.clone(self.env) t.posted = False t.target += '.inst' t.name = self.name + '.inst' self.env.RPATH = build_ldflags else: t = self t.env.RPATH = install_ldflags dev_link = None # in the following the names are: # - inst_name is the name with .inst. in it, in the build # directory # - install_name is the name in the install directory # - install_link is a symlink in the install directory, to install_name if getattr(self, 'samba_realname', None): install_name = self.samba_realname install_link = None if getattr(self, 'soname', ''): install_link = self.soname if getattr(self, 'samba_type', None) == 'PYTHON': inst_name = bld.make_libname(t.target, nolibprefix=True, python=True) else: inst_name = bld.make_libname(t.target) elif self.vnum: vnum_base = self.vnum.split('.')[0] install_name = bld.make_libname(target_name, version=self.vnum) install_link = bld.make_libname(target_name, version=vnum_base) inst_name = bld.make_libname(t.target) if not self.private_library or not t.env.SONAME_ST: # only generate the dev link for non-bundled libs dev_link = bld.make_libname(target_name) elif getattr(self, 'soname', ''): install_name = bld.make_libname(target_name) install_link = self.soname inst_name = bld.make_libname(t.target) else: install_name = bld.make_libname(target_name) install_link = None inst_name = bld.make_libname(t.target) if t.env.SONAME_ST: # ensure we get the right names in the library if install_link: t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_link) else: t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_name) t.env.SONAME_ST = '' # tell waf to install the library bld.install_as(os.path.join(install_path, install_name), self.path.find_or_declare(inst_name), chmod=MODE_755) if install_link and install_link != install_name: # and the symlink if needed bld.symlink_as(os.path.join(install_path, install_link), os.path.basename(install_name)) if dev_link: bld.symlink_as(os.path.join(install_path, dev_link), os.path.basename(install_name)) finally: bld.all_envs['default'] = default_env @feature('cshlib') @after('apply_implib') @before('apply_vnum') def apply_soname(self): '''install a library, taking account of the different rpath varients''' if self.env.SONAME_ST and getattr(self, 'soname', ''): self.env.append_value('LINKFLAGS', self.env.SONAME_ST % self.soname) self.env.SONAME_ST = '' @feature('cshlib') @after('apply_implib') @before('apply_vnum') def apply_vscript(self): '''add version-script arguments to library build''' if self.env.HAVE_LD_VERSION_SCRIPT and getattr(self, 'version_script', ''): self.env.append_value('LINKFLAGS', "-Wl,--version-script=%s" % self.version_script) self.version_script = None ############################## # handle the creation of links for libraries and binaries in the build tree @feature('symlink_lib') @after('apply_link') def symlink_lib(self): '''symlink a shared lib''' if self.target.endswith('.inst'): return blddir = os.path.dirname(self.bld.srcnode.abspath(self.bld.env)) libpath = self.link_task.outputs[0].abspath(self.env) # calculat the link target and put it in the environment soext="" vnum = getattr(self, 'vnum', None) if vnum is not None: soext = '.' + vnum.split('.')[0] link_target = getattr(self, 'link_name', '') if link_target == '': basename = os.path.basename(self.bld.make_libname(self.target, version=soext)) if getattr(self, "private_library", False): link_target = '%s/private/%s' % (LIB_PATH, basename) else: link_target = '%s/%s' % (LIB_PATH, basename) link_target = os.path.join(blddir, link_target) if os.path.lexists(link_target): if os.path.islink(link_target) and os.readlink(link_target) == libpath: return os.unlink(link_target) link_container = os.path.dirname(link_target) if not os.path.isdir(link_container): os.makedirs(link_container) os.symlink(libpath, link_target) @feature('symlink_bin') @after('apply_link') def symlink_bin(self): '''symlink a binary into the build directory''' if self.target.endswith('.inst'): return if not self.link_task.outputs or not self.link_task.outputs[0]: raise Errors.WafError('no outputs found for %s in symlink_bin' % self.name) binpath = self.link_task.outputs[0].abspath(self.env) bldpath = os.path.join(self.bld.env.BUILD_DIRECTORY, self.link_task.outputs[0].name) if os.path.lexists(bldpath): if os.path.islink(bldpath) and os.readlink(bldpath) == binpath: return os.unlink(bldpath) os.symlink(binpath, bldpath) ldb-2.0.8/buildtools/wafsamba/samba_patterns.py0000660000000000000000000002307513573675413021561 0ustar rootroot00000000000000# a waf tool to add extension based build patterns for Samba import sys from waflib import Build from wafsamba import samba_version_file def write_version_header(task): '''print version.h contents''' src = task.inputs[0].srcpath(task.env) version = samba_version_file(src, task.env.srcdir, env=task.env, is_install=task.generator.bld.is_install) string = str(version) task.outputs[0].write(string) return 0 def SAMBA_MKVERSION(bld, target, source='VERSION'): '''generate the version.h header for Samba''' # We only force waf to re-generate this file if we are installing, # because only then is information not included in the deps (the # git revision) included in the version. t = bld.SAMBA_GENERATOR('VERSION', rule=write_version_header, source=source, target=target, always=bld.is_install) Build.BuildContext.SAMBA_MKVERSION = SAMBA_MKVERSION def write_build_options_header(fp): '''write preamble for build_options.c''' fp.write("/*\n") fp.write(" Unix SMB/CIFS implementation.\n") fp.write(" Build Options for Samba Suite\n") fp.write(" Copyright (C) Vance Lankhaar 2003\n") fp.write(" Copyright (C) Andrew Bartlett 2001\n") fp.write("\n") fp.write(" This program is free software; you can redistribute it and/or modify\n") fp.write(" it under the terms of the GNU General Public License as published by\n") fp.write(" the Free Software Foundation; either version 3 of the License, or\n") fp.write(" (at your option) any later version.\n") fp.write("\n") fp.write(" This program is distributed in the hope that it will be useful,\n") fp.write(" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") fp.write(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") fp.write(" GNU General Public License for more details.\n") fp.write("\n") fp.write(" You should have received a copy of the GNU General Public License\n") fp.write(" along with this program; if not, see .\n") fp.write("*/\n") fp.write("\n") fp.write("#include \"includes.h\"\n") fp.write("#include \"dynconfig/dynconfig.h\"\n") fp.write("#include \"lib/cluster_support.h\"\n") fp.write("\n") fp.write("static int output(bool screen, const char *format, ...) PRINTF_ATTRIBUTE(2,3);\n") fp.write("void build_options(bool screen);\n") fp.write("\n") fp.write("\n") fp.write("/****************************************************************************\n") fp.write("helper function for build_options\n") fp.write("****************************************************************************/\n") fp.write("static int output(bool screen, const char *format, ...)\n") fp.write("{\n") fp.write(" char *ptr = NULL;\n") fp.write(" int ret = 0;\n") fp.write(" va_list ap;\n") fp.write(" \n") fp.write(" va_start(ap, format);\n") fp.write(" ret = vasprintf(&ptr,format,ap);\n") fp.write(" va_end(ap);\n") fp.write("\n") fp.write(" if (screen) {\n") fp.write(" d_printf(\"%s\", ptr ? ptr : \"\");\n") fp.write(" } else {\n") fp.write(" DEBUG(4,(\"%s\", ptr ? ptr : \"\"));\n") fp.write(" }\n") fp.write(" \n") fp.write(" SAFE_FREE(ptr);\n") fp.write(" return ret;\n") fp.write("}\n") fp.write("\n") fp.write("/****************************************************************************\n") fp.write("options set at build time for the samba suite\n") fp.write("****************************************************************************/\n") fp.write("void build_options(bool screen)\n") fp.write("{\n") fp.write(" if ((DEBUGLEVEL < 4) && (!screen)) {\n") fp.write(" return;\n") fp.write(" }\n") fp.write("\n") fp.write("\n") fp.write(" /* Output various paths to files and directories */\n") fp.write(" output(screen,\"\\nPaths:\\n\");\n") fp.write(" output(screen,\" SBINDIR: %s\\n\", get_dyn_SBINDIR());\n") fp.write(" output(screen,\" BINDIR: %s\\n\", get_dyn_BINDIR());\n") fp.write(" output(screen,\" CONFIGFILE: %s\\n\", get_dyn_CONFIGFILE());\n") fp.write(" output(screen,\" LOGFILEBASE: %s\\n\", get_dyn_LOGFILEBASE());\n") fp.write(" output(screen,\" LMHOSTSFILE: %s\\n\",get_dyn_LMHOSTSFILE());\n") fp.write(" output(screen,\" LIBDIR: %s\\n\",get_dyn_LIBDIR());\n") fp.write(" output(screen,\" MODULESDIR: %s\\n\",get_dyn_MODULESDIR());\n") fp.write(" output(screen,\" SHLIBEXT: %s\\n\",get_dyn_SHLIBEXT());\n") fp.write(" output(screen,\" LOCKDIR: %s\\n\",get_dyn_LOCKDIR());\n") fp.write(" output(screen,\" STATEDIR: %s\\n\",get_dyn_STATEDIR());\n") fp.write(" output(screen,\" CACHEDIR: %s\\n\",get_dyn_CACHEDIR());\n") fp.write(" output(screen,\" PIDDIR: %s\\n\", get_dyn_PIDDIR());\n") fp.write(" output(screen,\" SMB_PASSWD_FILE: %s\\n\",get_dyn_SMB_PASSWD_FILE());\n") fp.write(" output(screen,\" PRIVATE_DIR: %s\\n\",get_dyn_PRIVATE_DIR());\n") fp.write(" output(screen,\" BINDDNS_DIR: %s\\n\",get_dyn_BINDDNS_DIR());\n") fp.write("\n") def write_build_options_footer(fp): fp.write(" /* Output the sizes of the various cluster features */\n") fp.write(" output(screen, \"\\n%s\", cluster_support_features());\n") fp.write("\n") fp.write(" /* Output the sizes of the various types */\n") fp.write(" output(screen, \"\\nType sizes:\\n\");\n") fp.write(" output(screen, \" sizeof(char): %lu\\n\",(unsigned long)sizeof(char));\n") fp.write(" output(screen, \" sizeof(int): %lu\\n\",(unsigned long)sizeof(int));\n") fp.write(" output(screen, \" sizeof(long): %lu\\n\",(unsigned long)sizeof(long));\n") fp.write(" output(screen, \" sizeof(long long): %lu\\n\",(unsigned long)sizeof(long long));\n") fp.write(" output(screen, \" sizeof(uint8_t): %lu\\n\",(unsigned long)sizeof(uint8_t));\n") fp.write(" output(screen, \" sizeof(uint16_t): %lu\\n\",(unsigned long)sizeof(uint16_t));\n") fp.write(" output(screen, \" sizeof(uint32_t): %lu\\n\",(unsigned long)sizeof(uint32_t));\n") fp.write(" output(screen, \" sizeof(short): %lu\\n\",(unsigned long)sizeof(short));\n") fp.write(" output(screen, \" sizeof(void*): %lu\\n\",(unsigned long)sizeof(void*));\n") fp.write(" output(screen, \" sizeof(size_t): %lu\\n\",(unsigned long)sizeof(size_t));\n") fp.write(" output(screen, \" sizeof(off_t): %lu\\n\",(unsigned long)sizeof(off_t));\n") fp.write(" output(screen, \" sizeof(ino_t): %lu\\n\",(unsigned long)sizeof(ino_t));\n") fp.write(" output(screen, \" sizeof(dev_t): %lu\\n\",(unsigned long)sizeof(dev_t));\n") fp.write("\n") fp.write(" output(screen, \"\\nBuiltin modules:\\n\");\n") fp.write(" output(screen, \" %s\\n\", STRING_STATIC_MODULES);\n") fp.write("}\n") def write_build_options_section(fp, keys, section): fp.write("\n\t/* Show %s */\n" % section) fp.write(" output(screen, \"\\n%s:\\n\");\n\n" % section) for k in sorted(keys): fp.write("#ifdef %s\n" % k) fp.write(" output(screen, \" %s\\n\");\n" % k) fp.write("#endif\n") fp.write("\n") def write_build_options(task): tbl = task.env keys_option_with = [] keys_option_utmp = [] keys_option_have = [] keys_header_sys = [] keys_header_other = [] keys_misc = [] if sys.hexversion>0x300000f: trans_table = bytes.maketrans(b'.-()', b'____') else: import string trans_table = string.maketrans('.-()', '____') for key in tbl: if key.startswith("HAVE_UT_UT_") or key.find("UTMP") >= 0: keys_option_utmp.append(key) elif key.startswith("WITH_"): keys_option_with.append(key) elif key.startswith("HAVE_SYS_"): keys_header_sys.append(key) elif key.startswith("HAVE_"): if key.endswith("_H"): keys_header_other.append(key) else: keys_option_have.append(key) elif key.startswith("static_init_"): l = key.split("(") keys_misc.append(l[0]) else: keys_misc.append(key.translate(trans_table)) tgt = task.outputs[0].bldpath(task.env) f = open(tgt, 'w') write_build_options_header(f) write_build_options_section(f, keys_header_sys, "System Headers") write_build_options_section(f, keys_header_other, "Headers") write_build_options_section(f, keys_option_utmp, "UTMP Options") write_build_options_section(f, keys_option_have, "HAVE_* Defines") write_build_options_section(f, keys_option_with, "--with Options") write_build_options_section(f, keys_misc, "Build Options") write_build_options_footer(f) f.close() return 0 def SAMBA_BLDOPTIONS(bld, target): '''generate the bld_options.c for Samba''' t = bld.SAMBA_GENERATOR(target, rule=write_build_options, dep_vars=['defines'], target=target) Build.BuildContext.SAMBA_BLDOPTIONS = SAMBA_BLDOPTIONS ldb-2.0.8/buildtools/wafsamba/samba_perl.py0000660000000000000000000000410313573675413020652 0ustar rootroot00000000000000from waflib import Utils from waflib.Configure import conf from samba_utils import get_string done = {} @conf def SAMBA_CHECK_PERL(conf, mandatory=True, version=(5,0,0)): if "done" in done: return done["done"] = True conf.find_program('perl', var='PERL', mandatory=mandatory) conf.load('perl') path_perl = conf.find_program('perl') conf.env.PERL_SPECIFIED = (conf.env.PERL != path_perl) conf.check_perl_version(version) def read_perl_config_var(cmd): output = Utils.cmd_output([conf.env.get_flat('PERL'), '-MConfig', '-e', cmd]) if not isinstance(output, str): output = get_string(output) return Utils.to_list(output) def check_perl_config_var(var): conf.start_msg("Checking for perl $Config{%s}:" % var) try: v = read_perl_config_var('print $Config{%s}' % var)[0] conf.end_msg("'%s'" % (v), 'GREEN') return v except IndexError: conf.end_msg(False, 'YELLOW') pass return None vendor_prefix = check_perl_config_var('vendorprefix') perl_arch_install_dir = None if vendor_prefix == conf.env.PREFIX: perl_arch_install_dir = check_perl_config_var('vendorarch'); if perl_arch_install_dir is None: perl_arch_install_dir = "${LIBDIR}/perl5"; conf.start_msg("PERL_ARCH_INSTALL_DIR: ") conf.end_msg("'%s'" % (perl_arch_install_dir), 'GREEN') conf.env.PERL_ARCH_INSTALL_DIR = perl_arch_install_dir perl_lib_install_dir = None if vendor_prefix == conf.env.PREFIX: perl_lib_install_dir = check_perl_config_var('vendorlib'); if perl_lib_install_dir is None: perl_lib_install_dir = "${DATADIR}/perl5"; conf.start_msg("PERL_LIB_INSTALL_DIR: ") conf.end_msg("'%s'" % (perl_lib_install_dir), 'GREEN') conf.env.PERL_LIB_INSTALL_DIR = perl_lib_install_dir perl_inc = read_perl_config_var('print "@INC"') if '.' in perl_inc: perl_inc.remove('.') conf.start_msg("PERL_INC: ") conf.end_msg("%s" % (perl_inc), 'GREEN') conf.env.PERL_INC = perl_inc ldb-2.0.8/buildtools/wafsamba/samba_pidl.py0000660000000000000000000001303413573675413020643 0ustar rootroot00000000000000# waf build tool for building IDL files with pidl import os from waflib import Build, Utils from waflib.TaskGen import feature, before from samba_utils import SET_TARGET_TYPE, TO_LIST, LOCAL_CACHE def SAMBA_PIDL(bld, pname, source, options='', output_dir='.', generate_tables=True): '''Build a IDL file using pidl. This will produce up to 13 output files depending on the options used''' bname = source[0:-4]; # strip off the .idl suffix bname = os.path.basename(bname) name = "%s_%s" % (pname, bname.upper()) if not SET_TARGET_TYPE(bld, name, 'PIDL'): return bld.SET_BUILD_GROUP('build_source') # the output files depend on the options used. Use this dictionary # to map between the options and the resulting file names options_map = { '--header' : '%s.h', '--ndr-parser' : 'ndr_%s.c ndr_%s.h', '--samba3-ndr-server' : 'srv_%s.c srv_%s.h', '--samba3-ndr-client' : 'cli_%s.c cli_%s.h', '--server' : 'ndr_%s_s.c', '--client' : 'ndr_%s_c.c ndr_%s_c.h', '--python' : 'py_%s.c', '--tdr-parser' : 'tdr_%s.c tdr_%s.h', '--dcom-proxy' : '%s_p.c', '--com-header' : 'com_%s.h' } table_header_idx = None out_files = [] options_list = TO_LIST(options) for o in options_list: if o in options_map: ofiles = TO_LIST(options_map[o]) for f in ofiles: out_files.append(os.path.join(output_dir, f % bname)) if f == 'ndr_%s.h': # remember this one for the tables generation table_header_idx = len(out_files) - 1 # depend on the full pidl sources source = TO_LIST(source) try: pidl_src_nodes = bld.pidl_files_cache except AttributeError: bld.pidl_files_cache = bld.srcnode.ant_glob('pidl/lib/Parse/**/*.pm', flat=False) bld.pidl_files_cache.extend(bld.srcnode.ant_glob('pidl', flat=False)) pidl_src_nodes = bld.pidl_files_cache # the cd .. is needed because pidl currently is sensitive to the directory it is run in cpp = "" cc = "" if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "": if isinstance(bld.CONFIG_GET("CPP"), list): cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP")) else: cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP") if cpp == "CPP=xlc_r": cpp = "" if bld.CONFIG_SET("CC"): if isinstance(bld.CONFIG_GET("CC"), list): cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC")) else: cc = 'CC="%s"' % bld.CONFIG_GET("CC") t = bld(rule='cd ${PIDL_LAUNCH_DIR} && %s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' % (cpp, cc), ext_out = '.c', before = 'c', update_outputs = True, shell = True, source = source, target = out_files, name = name, samba_type = 'PIDL') t.env.PIDL_LAUNCH_DIR = bld.srcnode.path_from(bld.bldnode) pnode = bld.srcnode.find_resource('pidl/pidl') t.env.PIDL = pnode.path_from(bld.srcnode) t.env.OPTIONS = TO_LIST(options) snode = t.path.find_resource(source[0]) t.env.IDLSRC = snode.path_from(bld.srcnode) t.env.OUTPUTDIR = bld.bldnode.path_from(bld.srcnode) + '/' + bld.path.find_dir(output_dir).path_from(bld.srcnode) bld.add_manual_dependency(snode, pidl_src_nodes) if generate_tables and table_header_idx is not None: pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS') pidl_headers[name] = [bld.path.find_or_declare(out_files[table_header_idx])] t.more_includes = '#' + bld.path.path_from(bld.srcnode) Build.BuildContext.SAMBA_PIDL = SAMBA_PIDL def SAMBA_PIDL_LIST(bld, name, source, options='', output_dir='.', generate_tables=True): '''A wrapper for building a set of IDL files''' for p in TO_LIST(source): bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, generate_tables=generate_tables) Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST ################################################################# # the rule for generating the NDR tables @feature('collect') @before('exec_rule') def collect(self): pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS') # The first source is tables.pl itself self.source = Utils.to_list(self.source) for (name, hd) in pidl_headers.items(): y = self.bld.get_tgen_by_name(name) self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name) y.post() for node in hd: self.bld.ASSERT(node is not None, 'Got None as build node generating PIDL table for %s' % name) self.source.append(node) def SAMBA_PIDL_TABLES(bld, name, target): '''generate the pidl NDR tables file''' bld.SET_BUILD_GROUP('main') t = bld( features = 'collect', rule = '${PERL} ${SRC} > ${TGT}', ext_out = '.c', before = 'c', update_outputs = True, shell = True, source = '../../librpc/tables.pl', target = target, name = name) t.env.LIBRPC = os.path.join(bld.srcnode.abspath(), 'librpc') Build.BuildContext.SAMBA_PIDL_TABLES = SAMBA_PIDL_TABLES ldb-2.0.8/buildtools/wafsamba/samba_python.py0000660000000000000000000001206713573675413021241 0ustar rootroot00000000000000# waf build tool for building IDL files with pidl import os, sys from waflib import Build, Logs, Utils, Configure, Errors from waflib.Configure import conf @conf def SAMBA_CHECK_PYTHON(conf, version=(3,4,0)): if conf.env.disable_python: version=(2,6,0) # enable tool to build python extensions if conf.env.HAVE_PYTHON_H: conf.check_python_version(version) return interpreters = [] conf.find_program('python3', var='PYTHON', mandatory=not conf.env.disable_python) conf.load('python') path_python = conf.find_program('python3') conf.env.PYTHON_SPECIFIED = (conf.env.PYTHON != path_python) conf.check_python_version(version) interpreters.append(conf.env['PYTHON']) conf.env.python_interpreters = interpreters @conf def SAMBA_CHECK_PYTHON_HEADERS(conf): if conf.env.disable_python: conf.msg("python headers", "Check disabled due to --disable-python") # we don't want PYTHONDIR in config.h, as otherwise changing # --prefix causes a complete rebuild conf.env.DEFINES = [x for x in conf.env.DEFINES if not x.startswith('PYTHONDIR=') and not x.startswith('PYTHONARCHDIR=')] return if conf.env["python_headers_checked"] == []: _check_python_headers(conf) conf.env["python_headers_checked"] = "yes" else: conf.msg("python headers", "using cache") # we don't want PYTHONDIR in config.h, as otherwise changing # --prefix causes a complete rebuild conf.env.DEFINES = [x for x in conf.env.DEFINES if not x.startswith('PYTHONDIR=') and not x.startswith('PYTHONARCHDIR=')] def _check_python_headers(conf): conf.check_python_headers() if conf.env['PYTHON_VERSION'] > '3': abi_pattern = os.path.splitext(conf.env['pyext_PATTERN'])[0] conf.env['PYTHON_SO_ABI_FLAG'] = abi_pattern % '' else: conf.env['PYTHON_SO_ABI_FLAG'] = '' conf.env['PYTHON_LIBNAME_SO_ABI_FLAG'] = ( conf.env['PYTHON_SO_ABI_FLAG'].replace('_', '-')) for lib in conf.env['LINKFLAGS_PYEMBED']: if lib.startswith('-L'): conf.env.append_unique('LIBPATH_PYEMBED', lib[2:]) # strip '-L' conf.env['LINKFLAGS_PYEMBED'].remove(lib) # same as in waf 1.5, keep only '-fno-strict-aliasing' # and ignore defines such as NDEBUG _FORTIFY_SOURCE=2 conf.env.DEFINES_PYEXT = [] conf.env.CFLAGS_PYEXT = ['-fno-strict-aliasing'] return def PYTHON_BUILD_IS_ENABLED(self): return self.CONFIG_SET('HAVE_PYTHON_H') Build.BuildContext.PYTHON_BUILD_IS_ENABLED = PYTHON_BUILD_IS_ENABLED def SAMBA_PYTHON(bld, name, source='', deps='', public_deps='', realname=None, cflags='', cflags_end=None, includes='', init_function_sentinel=None, local_include=True, vars=None, install=True, enabled=True): '''build a python extension for Samba''' # force-disable when we can't build python modules, so # every single call doesn't need to pass this in. if not bld.PYTHON_BUILD_IS_ENABLED(): enabled = False # when we support static python modules we'll need to gather # the list from all the SAMBA_PYTHON() targets if init_function_sentinel is not None: cflags += ' -DSTATIC_LIBPYTHON_MODULES=%s' % init_function_sentinel # From https://docs.python.org/2/c-api/arg.html: # Starting with Python 2.5 the type of the length argument to # PyArg_ParseTuple(), PyArg_ParseTupleAndKeywords() and PyArg_Parse() # can be controlled by defining the macro PY_SSIZE_T_CLEAN before # including Python.h. If the macro is defined, length is a Py_ssize_t # rather than an int. # Because if often included before includes.h/config.h # This must be in the -D compiler options cflags += ' -DPY_SSIZE_T_CLEAN=1' source = bld.EXPAND_VARIABLES(source, vars=vars) if realname is not None: link_name = 'python/%s' % realname else: link_name = None bld.SAMBA_LIBRARY(name, source=source, deps=deps, public_deps=public_deps, includes=includes, cflags=cflags, cflags_end=cflags_end, local_include=local_include, vars=vars, realname=realname, link_name=link_name, pyext=True, target_type='PYTHON', install_path='${PYTHONARCHDIR}', allow_undefined_symbols=True, install=install, enabled=enabled) Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON def pyembed_libname(bld, name): if bld.env['PYTHON_SO_ABI_FLAG']: return name + bld.env['PYTHON_SO_ABI_FLAG'] else: return name Build.BuildContext.pyembed_libname = pyembed_libname ldb-2.0.8/buildtools/wafsamba/samba_third_party.py0000660000000000000000000000400613573675413022243 0ustar rootroot00000000000000# functions to support third party libraries import os from waflib import Utils, Build, Context from waflib.Configure import conf @conf def CHECK_FOR_THIRD_PARTY(conf): return os.path.exists(os.path.join(Context.g_module.top, 'third_party')) Build.BuildContext.CHECK_FOR_THIRD_PARTY = CHECK_FOR_THIRD_PARTY @conf def CHECK_ZLIB(conf): version_check=''' #if (ZLIB_VERNUM >= 0x1230) #else #error "ZLIB_VERNUM < 0x1230" #endif z_stream *z; inflateInit2(z, -15); ''' return conf.CHECK_BUNDLED_SYSTEM('z', minversion='1.2.3', pkg='zlib', checkfunctions='zlibVersion', headers='zlib.h', checkcode=version_check, implied_deps='replace') Build.BuildContext.CHECK_ZLIB = CHECK_ZLIB @conf def CHECK_POPT(conf): return conf.CHECK_BUNDLED_SYSTEM('popt', checkfunctions='poptGetContext', headers='popt.h') Build.BuildContext.CHECK_POPT = CHECK_POPT @conf def CHECK_CMOCKA(conf): return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.3') Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA @conf def CHECK_SOCKET_WRAPPER(conf): return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.2.3') Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER @conf def CHECK_NSS_WRAPPER(conf): return conf.CHECK_BUNDLED_SYSTEM_PKG('nss_wrapper', minversion='1.1.6') Build.BuildContext.CHECK_NSS_WRAPPER = CHECK_NSS_WRAPPER @conf def CHECK_RESOLV_WRAPPER(conf): return conf.CHECK_BUNDLED_SYSTEM_PKG('resolv_wrapper', minversion='1.1.4') Build.BuildContext.CHECK_RESOLV_WRAPPER = CHECK_RESOLV_WRAPPER @conf def CHECK_UID_WRAPPER(conf): return conf.CHECK_BUNDLED_SYSTEM_PKG('uid_wrapper', minversion='1.2.4') Build.BuildContext.CHECK_UID_WRAPPER = CHECK_UID_WRAPPER @conf def CHECK_PAM_WRAPPER(conf): return conf.CHECK_BUNDLED_SYSTEM_PKG('pam_wrapper', minversion='1.0.7') Build.BuildContext.CHECK_PAM_WRAPPER = CHECK_PAM_WRAPPER ldb-2.0.8/buildtools/wafsamba/samba_utils.py0000660000000000000000000006062013573675413021056 0ustar rootroot00000000000000# a waf tool to add autoconf-like macros to the configure section # and for SAMBA_ macros for building libraries, binaries etc import errno import os, sys, re, fnmatch, shlex, inspect from optparse import SUPPRESS_HELP from waflib import Build, Options, Utils, Task, Logs, Configure, Errors, Context from waflib import Scripting from waflib.TaskGen import feature, before, after from waflib.Configure import ConfigurationContext from waflib.Logs import debug from waflib import ConfigSet from waflib.Build import CACHE_SUFFIX # TODO: make this a --option LIB_PATH="shared" PY3 = sys.version_info[0] == 3 if PY3: # helper function to get a string from a variable that maybe 'str' or # 'bytes' if 'bytes' then it is decoded using 'utf8'. If 'str' is passed # it is returned unchanged # Using this function is PY2/PY3 code should ensure in most cases # the PY2 code runs unchanged in PY2 whereas the code in PY3 possibly # decodes the variable (see PY2 implementation of this function below) def get_string(bytesorstring): tmp = bytesorstring if isinstance(bytesorstring, bytes): tmp = bytesorstring.decode('utf8') elif not isinstance(bytesorstring, str): raise ValueError('Expected byte of string for %s:%s' % (type(bytesorstring), bytesorstring)) return tmp else: # Helper function to return string. # if 'str' or 'unicode' passed in they are returned unchanged # otherwise an exception is generated # Using this function is PY2/PY3 code should ensure in most cases # the PY2 code runs unchanged in PY2 whereas the code in PY3 possibly # decodes the variable (see PY3 implementation of this function above) def get_string(bytesorstring): tmp = bytesorstring if not(isinstance(bytesorstring, str) or isinstance(bytesorstring, unicode)): raise ValueError('Expected str or unicode for %s:%s' % (type(bytesorstring), bytesorstring)) return tmp # sigh, python octal constants are a mess MODE_644 = int('644', 8) MODE_744 = int('744', 8) MODE_755 = int('755', 8) MODE_777 = int('777', 8) def conf(f): # override in order to propagate the argument "mandatory" def fun(*k, **kw): mandatory = True if 'mandatory' in kw: mandatory = kw['mandatory'] del kw['mandatory'] try: return f(*k, **kw) except Errors.ConfigurationError: if mandatory: raise fun.__name__ = f.__name__ if 'mandatory' in inspect.getsource(f): fun = f setattr(Configure.ConfigurationContext, f.__name__, fun) setattr(Build.BuildContext, f.__name__, fun) return f Configure.conf = conf Configure.conftest = conf @conf def SET_TARGET_TYPE(ctx, target, value): '''set the target type of a target''' cache = LOCAL_CACHE(ctx, 'TARGET_TYPE') if target in cache and cache[target] != 'EMPTY': Logs.error("ERROR: Target '%s' in directory %s re-defined as %s - was %s" % (target, ctx.path.abspath(), value, cache[target])) sys.exit(1) LOCAL_CACHE_SET(ctx, 'TARGET_TYPE', target, value) debug("task_gen: Target '%s' created of type '%s' in %s" % (target, value, ctx.path.abspath())) return True def GET_TARGET_TYPE(ctx, target): '''get target type from cache''' cache = LOCAL_CACHE(ctx, 'TARGET_TYPE') if not target in cache: return None return cache[target] def ADD_LD_LIBRARY_PATH(path): '''add something to LD_LIBRARY_PATH''' if 'LD_LIBRARY_PATH' in os.environ: oldpath = os.environ['LD_LIBRARY_PATH'] else: oldpath = '' newpath = oldpath.split(':') if not path in newpath: newpath.append(path) os.environ['LD_LIBRARY_PATH'] = ':'.join(newpath) def needs_private_lib(bld, target): '''return True if a target links to a private library''' for lib in getattr(target, "final_libs", []): t = bld.get_tgen_by_name(lib) if t and getattr(t, 'private_library', False): return True return False def install_rpath(target): '''the rpath value for installation''' bld = target.bld bld.env['RPATH'] = [] ret = set() if bld.env.RPATH_ON_INSTALL: ret.add(bld.EXPAND_VARIABLES(bld.env.LIBDIR)) if bld.env.RPATH_ON_INSTALL_PRIVATE and needs_private_lib(bld, target): ret.add(bld.EXPAND_VARIABLES(bld.env.PRIVATELIBDIR)) return list(ret) def build_rpath(bld): '''the rpath value for build''' rpaths = [os.path.normpath('%s/%s' % (bld.env.BUILD_DIRECTORY, d)) for d in ("shared", "shared/private")] bld.env['RPATH'] = [] if bld.env.RPATH_ON_BUILD: return rpaths for rpath in rpaths: ADD_LD_LIBRARY_PATH(rpath) return [] @conf def LOCAL_CACHE(ctx, name): '''return a named build cache dictionary, used to store state inside other functions''' if name in ctx.env: return ctx.env[name] ctx.env[name] = {} return ctx.env[name] @conf def LOCAL_CACHE_SET(ctx, cachename, key, value): '''set a value in a local cache''' cache = LOCAL_CACHE(ctx, cachename) cache[key] = value @conf def ASSERT(ctx, expression, msg): '''a build assert call''' if not expression: raise Errors.WafError("ERROR: %s\n" % msg) Build.BuildContext.ASSERT = ASSERT def SUBDIR(bld, subdir, list): '''create a list of files by pre-pending each with a subdir name''' ret = '' for l in TO_LIST(list): ret = ret + os.path.normpath(os.path.join(subdir, l)) + ' ' return ret Build.BuildContext.SUBDIR = SUBDIR def dict_concat(d1, d2): '''concatenate two dictionaries d1 += d2''' for t in d2: if t not in d1: d1[t] = d2[t] def ADD_COMMAND(opt, name, function): '''add a new top level command to waf''' Context.g_module.__dict__[name] = function opt.name = function Options.OptionsContext.ADD_COMMAND = ADD_COMMAND @feature('c', 'cc', 'cshlib', 'cprogram') @before('apply_core','exec_rule') def process_depends_on(self): '''The new depends_on attribute for build rules allow us to specify a dependency on output from a source generation rule''' if getattr(self , 'depends_on', None): lst = self.to_list(self.depends_on) for x in lst: y = self.bld.get_tgen_by_name(x) self.bld.ASSERT(y is not None, "Failed to find dependency %s of %s" % (x, self.name)) y.post() if getattr(y, 'more_includes', None): self.includes += " " + y.more_includes os_path_relpath = getattr(os.path, 'relpath', None) if os_path_relpath is None: # Python < 2.6 does not have os.path.relpath, provide a replacement # (imported from Python2.6.5~rc2) def os_path_relpath(path, start): """Return a relative version of a path""" start_list = os.path.abspath(start).split("/") path_list = os.path.abspath(path).split("/") # Work out how much of the filepath is shared by start and path. i = len(os.path.commonprefix([start_list, path_list])) rel_list = ['..'] * (len(start_list)-i) + path_list[i:] if not rel_list: return start return os.path.join(*rel_list) def unique_list(seq): '''return a uniquified list in the same order as the existing list''' seen = {} result = [] for item in seq: if item in seen: continue seen[item] = True result.append(item) return result def TO_LIST(str, delimiter=None): '''Split a list, preserving quoted strings and existing lists''' if str is None: return [] if isinstance(str, list): # we need to return a new independent list... return list(str) if len(str) == 0: return [] lst = str.split(delimiter) # the string may have had quotes in it, now we # check if we did have quotes, and use the slower shlex # if we need to for e in lst: if e[0] == '"': return shlex.split(str) return lst def subst_vars_error(string, env): '''substitute vars, throw an error if a variable is not defined''' lst = re.split('(\$\{\w+\})', string) out = [] for v in lst: if re.match('\$\{\w+\}', v): vname = v[2:-1] if not vname in env: raise KeyError("Failed to find variable %s in %s in env %s <%s>" % (vname, string, env.__class__, str(env))) v = env[vname] if isinstance(v, list): v = ' '.join(v) out.append(v) return ''.join(out) @conf def SUBST_ENV_VAR(ctx, varname): '''Substitute an environment variable for any embedded variables''' return subst_vars_error(ctx.env[varname], ctx.env) Build.BuildContext.SUBST_ENV_VAR = SUBST_ENV_VAR def recursive_dirlist(dir, relbase, pattern=None): '''recursive directory list''' ret = [] for f in os.listdir(dir): f2 = dir + '/' + f if os.path.isdir(f2): ret.extend(recursive_dirlist(f2, relbase)) else: if pattern and not fnmatch.fnmatch(f, pattern): continue ret.append(os_path_relpath(f2, relbase)) return ret def symlink(src, dst, force=True): """Can create symlink by force""" try: os.symlink(src, dst) except OSError as exc: if exc.errno == errno.EEXIST and force: os.remove(dst) os.symlink(src, dst) else: raise def mkdir_p(dir): '''like mkdir -p''' if not dir: return if dir.endswith("/"): mkdir_p(dir[:-1]) return if os.path.isdir(dir): return mkdir_p(os.path.dirname(dir)) os.mkdir(dir) def SUBST_VARS_RECURSIVE(string, env): '''recursively expand variables''' if string is None: return string limit=100 while (string.find('${') != -1 and limit > 0): string = subst_vars_error(string, env) limit -= 1 return string @conf def EXPAND_VARIABLES(ctx, varstr, vars=None): '''expand variables from a user supplied dictionary This is most useful when you pass vars=locals() to expand all your local variables in strings ''' if isinstance(varstr, list): ret = [] for s in varstr: ret.append(EXPAND_VARIABLES(ctx, s, vars=vars)) return ret if not isinstance(varstr, str): return varstr env = ConfigSet.ConfigSet() ret = varstr # substitute on user supplied dict if avaiilable if vars is not None: for v in vars.keys(): env[v] = vars[v] ret = SUBST_VARS_RECURSIVE(ret, env) # if anything left, subst on the environment as well if ret.find('${') != -1: ret = SUBST_VARS_RECURSIVE(ret, ctx.env) # make sure there is nothing left. Also check for the common # typo of $( instead of ${ if ret.find('${') != -1 or ret.find('$(') != -1: Logs.error('Failed to substitute all variables in varstr=%s' % ret) sys.exit(1) return ret Build.BuildContext.EXPAND_VARIABLES = EXPAND_VARIABLES def RUN_COMMAND(cmd, env=None, shell=False): '''run a external command, return exit code or signal''' if env: cmd = SUBST_VARS_RECURSIVE(cmd, env) status = os.system(cmd) if os.WIFEXITED(status): return os.WEXITSTATUS(status) if os.WIFSIGNALED(status): return - os.WTERMSIG(status) Logs.error("Unknown exit reason %d for command: %s" % (status, cmd)) return -1 def RUN_PYTHON_TESTS(testfiles, pythonpath=None, extra_env=None): env = LOAD_ENVIRONMENT() if pythonpath is None: pythonpath = os.path.join(Context.g_module.out, 'python') result = 0 for interp in env.python_interpreters: if not isinstance(interp, str): interp = ' '.join(interp) for testfile in testfiles: cmd = "PYTHONPATH=%s %s %s" % (pythonpath, interp, testfile) if extra_env: for key, value in extra_env.items(): cmd = "%s=%s %s" % (key, value, cmd) print('Running Python test with %s: %s' % (interp, testfile)) ret = RUN_COMMAND(cmd) if ret: print('Python test failed: %s' % cmd) result = ret return result # make sure we have md5. some systems don't have it try: from hashlib import md5 # Even if hashlib.md5 exists, it may be unusable. # Try to use MD5 function. In FIPS mode this will cause an exception # and we'll get to the replacement code foo = md5(b'abcd') except: try: import md5 # repeat the same check here, mere success of import is not enough. # Try to use MD5 function. In FIPS mode this will cause an exception foo = md5.md5(b'abcd') except: Context.SIG_NIL = hash('abcd') class replace_md5(object): def __init__(self): self.val = None def update(self, val): self.val = hash((self.val, val)) def digest(self): return str(self.val) def hexdigest(self): return self.digest().encode('hex') def replace_h_file(filename): f = open(filename, 'rb') m = replace_md5() while (filename): filename = f.read(100000) m.update(filename) f.close() return m.digest() Utils.md5 = replace_md5 Task.md5 = replace_md5 Utils.h_file = replace_h_file def LOAD_ENVIRONMENT(): '''load the configuration environment, allowing access to env vars from new commands''' env = ConfigSet.ConfigSet() try: p = os.path.join(Context.g_module.out, 'c4che/default'+CACHE_SUFFIX) env.load(p) except (OSError, IOError): pass return env def IS_NEWER(bld, file1, file2): '''return True if file1 is newer than file2''' curdir = bld.path.abspath() t1 = os.stat(os.path.join(curdir, file1)).st_mtime t2 = os.stat(os.path.join(curdir, file2)).st_mtime return t1 > t2 Build.BuildContext.IS_NEWER = IS_NEWER @conf def RECURSE(ctx, directory): '''recurse into a directory, relative to the curdir or top level''' try: visited_dirs = ctx.visited_dirs except AttributeError: visited_dirs = ctx.visited_dirs = set() d = os.path.join(ctx.path.abspath(), directory) if os.path.exists(d): abspath = os.path.abspath(d) else: abspath = os.path.abspath(os.path.join(Context.g_module.top, directory)) ctxclass = ctx.__class__.__name__ key = ctxclass + ':' + abspath if key in visited_dirs: # already done it return visited_dirs.add(key) relpath = os_path_relpath(abspath, ctx.path.abspath()) if ctxclass in ['tmp', 'OptionsContext', 'ConfigurationContext', 'BuildContext']: return ctx.recurse(relpath) if 'waflib.extras.compat15' in sys.modules: return ctx.recurse(relpath) Logs.error('Unknown RECURSE context class: {}'.format(ctxclass)) raise Options.OptionsContext.RECURSE = RECURSE Build.BuildContext.RECURSE = RECURSE def CHECK_MAKEFLAGS(options): '''check for MAKEFLAGS environment variable in case we are being called from a Makefile try to honor a few make command line flags''' if not 'WAF_MAKE' in os.environ: return makeflags = os.environ.get('MAKEFLAGS') if makeflags is None: makeflags = "" jobs_set = False jobs = None # we need to use shlex.split to cope with the escaping of spaces # in makeflags for opt in shlex.split(makeflags): # options can come either as -x or as x if opt[0:2] == 'V=': options.verbose = Logs.verbose = int(opt[2:]) if Logs.verbose > 0: Logs.zones = ['runner'] if Logs.verbose > 2: Logs.zones = ['*'] elif opt[0].isupper() and opt.find('=') != -1: # this allows us to set waf options on the make command line # for example, if you do "make FOO=blah", then we set the # option 'FOO' in Options.options, to blah. If you look in wafsamba/wscript # you will see that the command line accessible options have their dest= # set to uppercase, to allow for passing of options from make in this way # this is also how "make test TESTS=testpattern" works, and # "make VERBOSE=1" as well as things like "make SYMBOLCHECK=1" loc = opt.find('=') setattr(options, opt[0:loc], opt[loc+1:]) elif opt[0] != '-': for v in opt: if re.search(r'j[0-9]*$', v): jobs_set = True jobs = opt.strip('j') elif v == 'k': options.keep = True elif re.search(r'-j[0-9]*$', opt): jobs_set = True jobs = opt.strip('-j') elif opt == '-k': options.keep = True if not jobs_set: # default to one job options.jobs = 1 elif jobs_set and jobs: options.jobs = int(jobs) waflib_options_parse_cmd_args = Options.OptionsContext.parse_cmd_args def wafsamba_options_parse_cmd_args(self, _args=None, cwd=None, allow_unknown=False): (options, commands, envvars) = \ waflib_options_parse_cmd_args(self, _args=_args, cwd=cwd, allow_unknown=allow_unknown) CHECK_MAKEFLAGS(options) if options.jobs == 1: # # waflib.Runner.Parallel processes jobs inline if the possible number # of jobs is just 1. But (at least in waf <= 2.0.12) it still calls # create a waflib.Runner.Spawner() which creates a single # waflib.Runner.Consumer() thread that tries to process jobs from the # queue. # # This has strange effects, which are not noticed typically, # but at least on AIX python has broken threading and fails # in random ways. # # So we just add a dummy Spawner class. class NoOpSpawner(object): def __init__(self, master): return from waflib import Runner Runner.Spawner = NoOpSpawner return options, commands, envvars Options.OptionsContext.parse_cmd_args = wafsamba_options_parse_cmd_args option_groups = {} def option_group(opt, name): '''find or create an option group''' global option_groups if name in option_groups: return option_groups[name] gr = opt.add_option_group(name) option_groups[name] = gr return gr Options.OptionsContext.option_group = option_group def save_file(filename, contents, create_dir=False): '''save data to a file''' if create_dir: mkdir_p(os.path.dirname(filename)) try: f = open(filename, 'w') f.write(contents) f.close() except: return False return True def load_file(filename): '''return contents of a file''' try: f = open(filename, 'r') r = f.read() f.close() except: return None return r def reconfigure(ctx): '''rerun configure if necessary''' if not os.path.exists(os.environ.get('WAFLOCK', '.lock-wscript')): raise Errors.WafError('configure has not been run') import samba_wildcard bld = samba_wildcard.fake_build_environment() Configure.autoconfig = True Scripting.check_configured(bld) def map_shlib_extension(ctx, name, python=False): '''map a filename with a shared library extension of .so to the real shlib name''' if name is None: return None if name[-1:].isdigit(): # some libraries have specified versions in the wscript rule return name (root1, ext1) = os.path.splitext(name) if python: return ctx.env.pyext_PATTERN % root1 else: (root2, ext2) = os.path.splitext(ctx.env.cshlib_PATTERN) return root1+ext2 Build.BuildContext.map_shlib_extension = map_shlib_extension def apply_pattern(filename, pattern): '''apply a filename pattern to a filename that may have a directory component''' dirname = os.path.dirname(filename) if not dirname: return pattern % filename basename = os.path.basename(filename) return os.path.join(dirname, pattern % basename) def make_libname(ctx, name, nolibprefix=False, version=None, python=False): """make a library filename Options: nolibprefix: don't include the lib prefix version : add a version number python : if we should use python module name conventions""" if python: libname = apply_pattern(name, ctx.env.pyext_PATTERN) else: libname = apply_pattern(name, ctx.env.cshlib_PATTERN) if nolibprefix and libname[0:3] == 'lib': libname = libname[3:] if version: if version[0] == '.': version = version[1:] (root, ext) = os.path.splitext(libname) if ext == ".dylib": # special case - version goes before the prefix libname = "%s.%s%s" % (root, version, ext) else: libname = "%s%s.%s" % (root, ext, version) return libname Build.BuildContext.make_libname = make_libname def get_tgt_list(bld): '''return a list of build objects for samba''' targets = LOCAL_CACHE(bld, 'TARGET_TYPE') # build a list of task generators we are interested in tgt_list = [] for tgt in targets: type = targets[tgt] if not type in ['SUBSYSTEM', 'MODULE', 'BINARY', 'LIBRARY', 'ASN1', 'PYTHON']: continue t = bld.get_tgen_by_name(tgt) if t is None: Logs.error("Target %s of type %s has no task generator" % (tgt, type)) sys.exit(1) tgt_list.append(t) return tgt_list from waflib.Context import WSCRIPT_FILE def PROCESS_SEPARATE_RULE(self, rule): ''' cause waf to process additional script based on `rule'. You should have file named wscript__rule in the current directory where stage is either 'configure' or 'build' ''' stage = '' if isinstance(self, Configure.ConfigurationContext): stage = 'configure' elif isinstance(self, Build.BuildContext): stage = 'build' file_path = os.path.join(self.path.abspath(), WSCRIPT_FILE+'_'+stage+'_'+rule) node = self.root.find_node(file_path) if node: try: cache = self.recurse_cache except AttributeError: cache = self.recurse_cache = {} if node not in cache: cache[node] = True self.pre_recurse(node) try: function_code = node.read('rU', None) exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict) finally: self.post_recurse(node) Build.BuildContext.PROCESS_SEPARATE_RULE = PROCESS_SEPARATE_RULE ConfigurationContext.PROCESS_SEPARATE_RULE = PROCESS_SEPARATE_RULE def AD_DC_BUILD_IS_ENABLED(self): if self.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'): return True return False Build.BuildContext.AD_DC_BUILD_IS_ENABLED = AD_DC_BUILD_IS_ENABLED @feature('cprogram', 'cshlib', 'cstaticlib') @after('apply_lib_vars') @before('apply_obj_vars') def samba_before_apply_obj_vars(self): """before apply_obj_vars for uselib, this removes the standard paths""" def is_standard_libpath(env, path): for _path in env.STANDARD_LIBPATH: if _path == os.path.normpath(path): return True return False v = self.env for i in v['RPATH']: if is_standard_libpath(v, i): v['RPATH'].remove(i) for i in v['LIBPATH']: if is_standard_libpath(v, i): v['LIBPATH'].remove(i) def samba_add_onoff_option(opt, option, help=(), dest=None, default=True, with_name="with", without_name="without"): if default is None: default_str = "auto" elif default is True: default_str = "yes" elif default is False: default_str = "no" else: default_str = str(default) if help == (): help = ("Build with %s support (default=%s)" % (option, default_str)) if dest is None: dest = "with_%s" % option.replace('-', '_') with_val = "--%s-%s" % (with_name, option) without_val = "--%s-%s" % (without_name, option) opt.add_option(with_val, help=help, action="store_true", dest=dest, default=default) opt.add_option(without_val, help=SUPPRESS_HELP, action="store_false", dest=dest) Options.OptionsContext.samba_add_onoff_option = samba_add_onoff_option ldb-2.0.8/buildtools/wafsamba/samba_version.py0000660000000000000000000002204513573675413021402 0ustar rootroot00000000000000import os, sys from waflib import Utils, Context import samba_utils from samba_git import find_git def git_version_summary(path, env=None): git = find_git(env) if git is None: return ("GIT-UNKNOWN", {}) env.GIT = git environ = dict(os.environ) environ["GIT_DIR"] = '%s/.git' % path environ["GIT_WORK_TREE"] = path git = samba_utils.get_string(Utils.cmd_output(env.GIT + ' show --pretty=format:"%h%n%ct%n%H%n%cd" --stat HEAD', silent=True, env=environ)) lines = git.splitlines() if not lines or len(lines) < 4: return ("GIT-UNKNOWN", {}) fields = { "GIT_COMMIT_ABBREV": lines[0], "GIT_COMMIT_FULLREV": lines[2], "COMMIT_TIME": int(lines[1]), "COMMIT_DATE": lines[3], } ret = "GIT-" + fields["GIT_COMMIT_ABBREV"] if env.GIT_LOCAL_CHANGES: clean = Utils.cmd_output('%s diff HEAD | wc -l' % env.GIT, silent=True).strip() if clean == "0": fields["COMMIT_IS_CLEAN"] = 1 else: fields["COMMIT_IS_CLEAN"] = 0 ret += "+" return (ret, fields) def distversion_version_summary(path): #get version from .distversion file suffix = None fields = {} for line in Utils.readf(path + '/.distversion').splitlines(): if line == '': continue if line.startswith("#"): continue try: split_line = line.split("=") if split_line[1] != "": key = split_line[0] value = split_line[1] if key == "SUFFIX": suffix = value continue fields[key] = value except: print("Failed to parse line %s from .distversion file." % (line)) raise if "COMMIT_TIME" in fields: fields["COMMIT_TIME"] = int(fields["COMMIT_TIME"]) if suffix is None: return ("UNKNOWN", fields) return (suffix, fields) class SambaVersion(object): def __init__(self, version_dict, path, env=None, is_install=True): '''Determine the version number of samba See VERSION for the format. Entries on that file are also accepted as dictionary entries here ''' self.MAJOR=None self.MINOR=None self.RELEASE=None self.REVISION=None self.TP_RELEASE=None self.ALPHA_RELEASE=None self.BETA_RELEASE=None self.PRE_RELEASE=None self.RC_RELEASE=None self.IS_SNAPSHOT=True self.RELEASE_NICKNAME=None self.VENDOR_SUFFIX=None self.VENDOR_PATCH=None for a, b in version_dict.items(): if a.startswith("SAMBA_VERSION_"): setattr(self, a[14:], b) else: setattr(self, a, b) if self.IS_GIT_SNAPSHOT == "yes": self.IS_SNAPSHOT=True elif self.IS_GIT_SNAPSHOT == "no": self.IS_SNAPSHOT=False else: raise Exception("Unknown value for IS_GIT_SNAPSHOT: %s" % self.IS_GIT_SNAPSHOT) ## ## start with "3.0.22" ## self.MAJOR=int(self.MAJOR) self.MINOR=int(self.MINOR) self.RELEASE=int(self.RELEASE) SAMBA_VERSION_STRING = ("%u.%u.%u" % (self.MAJOR, self.MINOR, self.RELEASE)) ## ## maybe add "3.0.22a" or "4.0.0tp11" or "4.0.0alpha1" or "4.0.0beta1" or "3.0.22pre1" or "3.0.22rc1" ## We do not do pre or rc version on patch/letter releases ## if self.REVISION is not None: SAMBA_VERSION_STRING += self.REVISION if self.TP_RELEASE is not None: self.TP_RELEASE = int(self.TP_RELEASE) SAMBA_VERSION_STRING += "tp%u" % self.TP_RELEASE if self.ALPHA_RELEASE is not None: self.ALPHA_RELEASE = int(self.ALPHA_RELEASE) SAMBA_VERSION_STRING += ("alpha%u" % self.ALPHA_RELEASE) if self.BETA_RELEASE is not None: self.BETA_RELEASE = int(self.BETA_RELEASE) SAMBA_VERSION_STRING += ("beta%u" % self.BETA_RELEASE) if self.PRE_RELEASE is not None: self.PRE_RELEASE = int(self.PRE_RELEASE) SAMBA_VERSION_STRING += ("pre%u" % self.PRE_RELEASE) if self.RC_RELEASE is not None: self.RC_RELEASE = int(self.RC_RELEASE) SAMBA_VERSION_STRING += ("rc%u" % self.RC_RELEASE) if self.IS_SNAPSHOT: if not is_install: suffix = "DEVELOPERBUILD" self.vcs_fields = {} elif os.path.exists(os.path.join(path, ".git")): suffix, self.vcs_fields = git_version_summary(path, env=env) elif os.path.exists(os.path.join(path, ".distversion")): suffix, self.vcs_fields = distversion_version_summary(path) else: suffix = "UNKNOWN" self.vcs_fields = {} self.vcs_fields["SUFFIX"] = suffix SAMBA_VERSION_STRING += "-" + suffix else: self.vcs_fields = {} self.OFFICIAL_STRING = SAMBA_VERSION_STRING if self.VENDOR_SUFFIX is not None: SAMBA_VERSION_STRING += ("-" + self.VENDOR_SUFFIX) self.VENDOR_SUFFIX = self.VENDOR_SUFFIX if self.VENDOR_PATCH is not None: SAMBA_VERSION_STRING += ("-" + self.VENDOR_PATCH) self.VENDOR_PATCH = self.VENDOR_PATCH self.STRING = SAMBA_VERSION_STRING if self.RELEASE_NICKNAME is not None: self.STRING_WITH_NICKNAME = "%s (%s)" % (self.STRING, self.RELEASE_NICKNAME) else: self.STRING_WITH_NICKNAME = self.STRING def __str__(self): string="/* Autogenerated by waf */\n" string+="#define SAMBA_VERSION_MAJOR %u\n" % self.MAJOR string+="#define SAMBA_VERSION_MINOR %u\n" % self.MINOR string+="#define SAMBA_VERSION_RELEASE %u\n" % self.RELEASE if self.REVISION is not None: string+="#define SAMBA_VERSION_REVISION %u\n" % self.REVISION if self.TP_RELEASE is not None: string+="#define SAMBA_VERSION_TP_RELEASE %u\n" % self.TP_RELEASE if self.ALPHA_RELEASE is not None: string+="#define SAMBA_VERSION_ALPHA_RELEASE %u\n" % self.ALPHA_RELEASE if self.BETA_RELEASE is not None: string+="#define SAMBA_VERSION_BETA_RELEASE %u\n" % self.BETA_RELEASE if self.PRE_RELEASE is not None: string+="#define SAMBA_VERSION_PRE_RELEASE %u\n" % self.PRE_RELEASE if self.RC_RELEASE is not None: string+="#define SAMBA_VERSION_RC_RELEASE %u\n" % self.RC_RELEASE for name in sorted(self.vcs_fields.keys()): string+="#define SAMBA_VERSION_%s " % name value = self.vcs_fields[name] string_types = str if sys.version_info[0] < 3: string_types = basestring if isinstance(value, string_types): string += "\"%s\"" % value elif type(value) is int: string += "%d" % value else: raise Exception("Unknown type for %s: %r" % (name, value)) string += "\n" string+="#define SAMBA_VERSION_OFFICIAL_STRING \"" + self.OFFICIAL_STRING + "\"\n" if self.VENDOR_SUFFIX is not None: string+="#define SAMBA_VERSION_VENDOR_SUFFIX " + self.VENDOR_SUFFIX + "\n" if self.VENDOR_PATCH is not None: string+="#define SAMBA_VERSION_VENDOR_PATCH " + self.VENDOR_PATCH + "\n" if self.RELEASE_NICKNAME is not None: string+="#define SAMBA_VERSION_RELEASE_NICKNAME " + self.RELEASE_NICKNAME + "\n" # We need to put this #ifdef in to the headers so that vendors can override the version with a function string+=''' #ifdef SAMBA_VERSION_VENDOR_FUNCTION # define SAMBA_VERSION_STRING SAMBA_VERSION_VENDOR_FUNCTION #else /* SAMBA_VERSION_VENDOR_FUNCTION */ # define SAMBA_VERSION_STRING "''' + self.STRING_WITH_NICKNAME + '''" #endif ''' string+="/* Version for mkrelease.sh: \nSAMBA_VERSION_STRING=" + self.STRING_WITH_NICKNAME + "\n */\n" return string def samba_version_file(version_file, path, env=None, is_install=True): '''Parse the version information from a VERSION file''' f = open(version_file, 'r') version_dict = {} for line in f: line = line.strip() if line == '': continue if line.startswith("#"): continue try: split_line = line.split("=") if split_line[1] != "": value = split_line[1].strip('"') version_dict[split_line[0]] = value except: print("Failed to parse line %s from %s" % (line, version_file)) raise return SambaVersion(version_dict, path, env=env, is_install=is_install) def load_version(env=None, is_install=True): '''load samba versions either from ./VERSION or git return a version object for detailed breakdown''' if not env: env = samba_utils.LOAD_ENVIRONMENT() version = samba_version_file("./VERSION", ".", env, is_install=is_install) Context.g_module.VERSION = version.STRING return version ldb-2.0.8/buildtools/wafsamba/samba_waf18.py0000660000000000000000000003405713573675413020651 0ustar rootroot00000000000000# compatibility layer for building with more recent waf versions import os, shlex, sys from waflib import Build, Configure, Node, Utils, Options, Logs, TaskGen from waflib import ConfigSet from waflib.TaskGen import feature, after from waflib.Configure import conf, ConfigurationContext from waflib.Tools.flex import decide_ext # This version of flexfun runs in tsk.get_cwd() as opposed to the # bld.variant_dir: since input paths adjusted against tsk.get_cwd(), we have to # use tsk.get_cwd() for the work directory as well. def flexfun(tsk): env = tsk.env bld = tsk.generator.bld def to_list(xx): if isinstance(xx, str): return [xx] return xx tsk.last_cmd = lst = [] lst.extend(to_list(env.FLEX)) lst.extend(to_list(env.FLEXFLAGS)) inputs = [a.path_from(tsk.get_cwd()) for a in tsk.inputs] if env.FLEX_MSYS: inputs = [x.replace(os.sep, '/') for x in inputs] lst.extend(inputs) lst = [x for x in lst if x] txt = bld.cmd_and_log(lst, cwd=tsk.get_cwd(), env=env.env or None, quiet=0) tsk.outputs[0].write(txt.replace('\r\n', '\n').replace('\r', '\n')) # issue #1207 TaskGen.declare_chain( name = 'flex', rule = flexfun, # issue #854 ext_in = '.l', decider = decide_ext, ) for y in (Build.BuildContext, Build.CleanContext, Build.InstallContext, Build.UninstallContext, Build.ListContext): class tmp(y): variant = 'default' def abspath(self, env=None): if env and hasattr(self, 'children'): return self.get_bld().abspath() return self.old_abspath() Node.Node.old_abspath = Node.Node.abspath Node.Node.abspath = abspath def bldpath(self, env=None): return self.abspath() #return self.path_from(self.ctx.bldnode.parent) Node.Node.bldpath = bldpath def srcpath(self, env=None): return self.abspath() #return self.path_from(self.ctx.bldnode.parent) Node.Node.srcpath = srcpath def store_fast(self, filename): file = open(filename, 'wb') data = self.get_merged_dict() try: Build.cPickle.dump(data, file, -1) finally: file.close() ConfigSet.ConfigSet.store_fast = store_fast def load_fast(self, filename): file = open(filename, 'rb') try: data = Build.cPickle.load(file) finally: file.close() self.table.update(data) ConfigSet.ConfigSet.load_fast = load_fast @feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') @after('propagate_uselib_vars', 'process_source') def apply_incpaths(self): lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) self.includes_nodes = lst cwdx = getattr(self.bld, 'cwdx', self.bld.bldnode) self.env['INCPATHS'] = [x.path_from(cwdx) for x in lst] @conf def define(self, key, val, quote=True, comment=None): assert key and isinstance(key, str) if val is None: val = () elif isinstance(val, bool): val = int(val) # waf 1.5 self.env[key] = val if isinstance(val, int) or isinstance(val, float): s = '%s=%s' else: s = quote and '%s="%s"' or '%s=%s' app = s % (key, str(val)) ban = key + '=' lst = self.env.DEFINES for x in lst: if x.startswith(ban): lst[lst.index(x)] = app break else: self.env.append_value('DEFINES', app) self.env.append_unique('define_key', key) # compat15 removes this but we want to keep it @conf def undefine(self, key, from_env=True, comment=None): assert key and isinstance(key, str) ban = key + '=' self.env.DEFINES = [x for x in self.env.DEFINES if not x.startswith(ban)] self.env.append_unique('define_key', key) # waf 1.5 if from_env: self.env[key] = () class ConfigurationContext(Configure.ConfigurationContext): def init_dirs(self): self.setenv('default') self.env.merge_config_header = True return super(ConfigurationContext, self).init_dirs() def find_program_samba(self, *k, **kw): # Override the waf default set in the @conf decorator in Configure.py if 'mandatory' not in kw: kw['mandatory'] = False ret = self.find_program_old(*k, **kw) return ret Configure.ConfigurationContext.find_program_old = Configure.ConfigurationContext.find_program Configure.ConfigurationContext.find_program = find_program_samba Build.BuildContext.ENFORCE_GROUP_ORDERING = Utils.nada Build.BuildContext.AUTOCLEANUP_STALE_FILES = Utils.nada @conf def check(self, *k, **kw): '''Override the waf defaults to inject --with-directory options''' # match the configuration test with speficic options, for example: # --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv" self.validate_c(kw) additional_dirs = [] if 'msg' in kw: msg = kw['msg'] for x in Options.OptionsContext.parser.parser.option_list: if getattr(x, 'match', None) and msg in x.match: d = getattr(Options.options, x.dest, '') if d: additional_dirs.append(d) # we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below def add_options_dir(dirs, env): for x in dirs: if not x in env.CPPPATH: env.CPPPATH = [os.path.join(x, 'include')] + env.CPPPATH if not x in env.LIBPATH: env.LIBPATH = [os.path.join(x, 'lib')] + env.LIBPATH add_options_dir(additional_dirs, kw['env']) self.start_msg(kw['msg'], **kw) ret = None try: ret = self.run_build(*k, **kw) except self.errors.ConfigurationError: self.end_msg(kw['errmsg'], 'YELLOW', **kw) if Logs.verbose > 1: raise else: self.fatal('The configuration failed') else: kw['success'] = ret # success! time for brandy add_options_dir(additional_dirs, self.env) ret = self.post_check(*k, **kw) if not ret: self.end_msg(kw['errmsg'], 'YELLOW', **kw) self.fatal('The configuration failed %r' % ret) else: self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) return ret @conf def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): '''see if the platform supports building libraries''' if msg is None: if rpath: msg = "rpath library support" else: msg = "building library support" def build(bld): lib_node = bld.srcnode.make_node('libdir/liblc1.c') lib_node.parent.mkdir() lib_node.write('int lib_func(void) { return 42; }\n', 'w') main_node = bld.srcnode.make_node('main.c') main_node.write('int main(void) {return !(lib_func() == 42);}', 'w') linkflags = [] if version_script: script = bld.srcnode.make_node('ldscript') script.write('TEST_1.0A2 { global: *; };\n', 'w') linkflags.append('-Wl,--version-script=%s' % script.abspath()) bld(features='c cshlib', source=lib_node, target='lib1', linkflags=linkflags, name='lib1') o = bld(features='c cprogram', source=main_node, target='prog1', uselib_local='lib1') if rpath: o.rpath = [lib_node.parent.abspath()] def run_app(self): args = conf.SAMBA_CROSS_ARGS(msg=msg) env = dict(os.environ) env['LD_LIBRARY_PATH'] = self.inputs[0].parent.abspath() + os.pathsep + env.get('LD_LIBRARY_PATH', '') self.generator.bld.cmd_and_log([self.inputs[0].abspath()] + args, env=env) o.post() bld(rule=run_app, source=o.link_task.outputs[0]) # ok, so it builds try: conf.check(build_fun=build, msg='Checking for %s' % msg) except conf.errors.ConfigurationError: return False return True @conf def CHECK_NEED_LC(conf, msg): '''check if we need -lc''' def build(bld): lib_node = bld.srcnode.make_node('libdir/liblc1.c') lib_node.parent.mkdir() lib_node.write('#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n', 'w') bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') try: conf.check(build_fun=build, msg=msg, okmsg='-lc is unnecessary', errmsg='-lc is necessary') except conf.errors.ConfigurationError: return False return True # already implemented on "waf -v" def order(bld, tgt_list): return True Build.BuildContext.check_group_ordering = order @conf def CHECK_CFG(self, *k, **kw): if 'args' in kw: kw['args'] = shlex.split(kw['args']) if not 'mandatory' in kw: kw['mandatory'] = False kw['global_define'] = True return self.check_cfg(*k, **kw) def cmd_output(cmd, **kw): silent = False if 'silent' in kw: silent = kw['silent'] del(kw['silent']) if 'e' in kw: tmp = kw['e'] del(kw['e']) kw['env'] = tmp kw['shell'] = isinstance(cmd, str) kw['stdout'] = Utils.subprocess.PIPE if silent: kw['stderr'] = Utils.subprocess.PIPE try: p = Utils.subprocess.Popen(cmd, **kw) output = p.communicate()[0] except OSError as e: raise ValueError(str(e)) if p.returncode: if not silent: msg = "command execution failed: %s -> %r" % (cmd, str(output)) raise ValueError(msg) output = '' return output Utils.cmd_output = cmd_output @TaskGen.feature('c', 'cxx', 'd') @TaskGen.before('apply_incpaths', 'propagate_uselib_vars') @TaskGen.after('apply_link', 'process_source') def apply_uselib_local(self): """ process the uselib_local attribute execute after apply_link because of the execution order set on 'link_task' """ env = self.env from waflib.Tools.ccroot import stlink_task # 1. the case of the libs defined in the project (visit ancestors first) # the ancestors external libraries (uselib) will be prepended self.uselib = self.to_list(getattr(self, 'uselib', [])) self.includes = self.to_list(getattr(self, 'includes', [])) names = self.to_list(getattr(self, 'uselib_local', [])) get = self.bld.get_tgen_by_name seen = set() seen_uselib = set() tmp = Utils.deque(names) # consume a copy of the list of names if tmp: if Logs.verbose: Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') while tmp: lib_name = tmp.popleft() # visit dependencies only once if lib_name in seen: continue y = get(lib_name) y.post() seen.add(lib_name) # object has ancestors to process (shared libraries): add them to the end of the list if getattr(y, 'uselib_local', None): for x in self.to_list(getattr(y, 'uselib_local', [])): obj = get(x) obj.post() if getattr(obj, 'link_task', None): if not isinstance(obj.link_task, stlink_task): tmp.append(x) # link task and flags if getattr(y, 'link_task', None): link_name = y.target[y.target.rfind(os.sep) + 1:] if isinstance(y.link_task, stlink_task): env.append_value('STLIB', [link_name]) else: # some linkers can link against programs env.append_value('LIB', [link_name]) # the order self.link_task.set_run_after(y.link_task) # for the recompilation self.link_task.dep_nodes += y.link_task.outputs # add the link path too tmp_path = y.link_task.outputs[0].parent.bldpath() if not tmp_path in env['LIBPATH']: env.prepend_value('LIBPATH', [tmp_path]) # add ancestors uselib too - but only propagate those that have no staticlib defined for v in self.to_list(getattr(y, 'uselib', [])): if v not in seen_uselib: seen_uselib.add(v) if not env['STLIB_' + v]: if not v in self.uselib: self.uselib.insert(0, v) # if the library task generator provides 'export_includes', add to the include path # the export_includes must be a list of paths relative to the other library if getattr(y, 'export_includes', None): self.includes.extend(y.to_incnodes(y.export_includes)) @TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib') @TaskGen.after('apply_link') def apply_objdeps(self): "add the .o files produced by some other object files in the same manner as uselib_local" names = getattr(self, 'add_objects', []) if not names: return names = self.to_list(names) get = self.bld.get_tgen_by_name seen = [] while names: x = names[0] # visit dependencies only once if x in seen: names = names[1:] continue # object does not exist ? y = get(x) # object has ancestors to process first ? update the list of names if getattr(y, 'add_objects', None): added = 0 lst = y.to_list(y.add_objects) lst.reverse() for u in lst: if u in seen: continue added = 1 names = [u]+names if added: continue # list of names modified, loop # safe to process the current object y.post() seen.append(x) for t in getattr(y, 'compiled_tasks', []): self.link_task.inputs.extend(t.outputs) @TaskGen.after('apply_link') def process_obj_files(self): if not hasattr(self, 'obj_files'): return for x in self.obj_files: node = self.path.find_resource(x) self.link_task.inputs.append(node) @TaskGen.taskgen_method def add_obj_file(self, file): """Small example on how to link object files as if they were source obj = bld.create_obj('cc') obj.add_obj_file('foo.o')""" if not hasattr(self, 'obj_files'): self.obj_files = [] if not 'process_obj_files' in self.meths: self.meths.append('process_obj_files') self.obj_files.append(file) ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py0000660000000000000000000001063413573675413021507 0ustar rootroot00000000000000# based on playground/evil in the waf svn tree import os, datetime, fnmatch from waflib import Scripting, Utils, Options, Logs, Errors from waflib import ConfigSet, Context from samba_utils import LOCAL_CACHE, os_path_relpath def run_task(t, k): '''run a single build task''' ret = t.run() if ret: raise Errors.WafError("Failed to build %s: %u" % (k, ret)) def run_named_build_task(cmd): '''run a named build task, matching the cmd name using fnmatch wildcards against inputs and outputs of all build tasks''' bld = fake_build_environment(info=False) found = False cwd_node = bld.root.find_dir(os.getcwd()) top_node = bld.root.find_dir(bld.srcnode.abspath()) cmd = os.path.normpath(cmd) # cope with builds of bin/*/* if os.path.islink(cmd): cmd = os_path_relpath(os.readlink(cmd), os.getcwd()) if cmd[0:12] == "bin/default/": cmd = cmd[12:] for g in bld.task_manager.groups: for attr in ['outputs', 'inputs']: for t in g.tasks: s = getattr(t, attr, []) for k in s: relpath1 = k.relpath_gen(cwd_node) relpath2 = k.relpath_gen(top_node) if (fnmatch.fnmatch(relpath1, cmd) or fnmatch.fnmatch(relpath2, cmd)): t.position = [0,0] print(t.display()) run_task(t, k) found = True if not found: raise Errors.WafError("Unable to find build target matching %s" % cmd) def rewrite_compile_targets(): '''cope with the bin/ form of compile target''' if not Options.options.compile_targets: return bld = fake_build_environment(info=False) targets = LOCAL_CACHE(bld, 'TARGET_TYPE') tlist = [] for t in Options.options.compile_targets.split(','): if not os.path.islink(t): tlist.append(t) continue link = os.readlink(t) list = link.split('/') for name in [list[-1], '/'.join(list[-2:])]: if name in targets: tlist.append(name) continue Options.options.compile_targets = ",".join(tlist) def wildcard_main(missing_cmd_fn): '''this replaces main from Scripting, allowing us to override the behaviour for unknown commands If a unknown command is found, then missing_cmd_fn() is called with the name of the requested command ''' Scripting.commands = Options.arg_line[:] # rewrite the compile targets to cope with the bin/xx form rewrite_compile_targets() while Scripting.commands: x = Scripting.commands.pop(0) ini = datetime.datetime.now() if x == 'configure': fun = Scripting.configure elif x == 'build': fun = Scripting.build else: fun = getattr(Utils.g_module, x, None) # this is the new addition on top of main from Scripting.py if not fun: missing_cmd_fn(x) break ctx = getattr(Utils.g_module, x + '_context', Utils.Context)() if x in ['init', 'shutdown', 'dist', 'distclean', 'distcheck']: try: fun(ctx) except TypeError: fun() else: fun(ctx) ela = '' if not Options.options.progress_bar: ela = ' (%s)' % Utils.get_elapsed_time(ini) if x != 'init' and x != 'shutdown': Logs.info('%r finished successfully%s' % (x, ela)) if not Scripting.commands and x != 'shutdown': Scripting.commands.append('shutdown') def fake_build_environment(info=True, flush=False): """create all the tasks for the project, but do not run the build return the build context in use""" bld = getattr(Context.g_module, 'build_context', Utils.Context)() bld = Scripting.check_configured(bld) Options.commands['install'] = False Options.commands['uninstall'] = False bld.is_install = 0 # False try: proj = ConfigSet.ConfigSet(Options.lockfile) except IOError: raise Errors.WafError("Project not configured (run 'waf configure' first)") bld.load_envs() if info: Logs.info("Waf: Entering directory `%s'" % bld.bldnode.abspath()) bld.add_subdirs([os.path.split(Context.g_module.root_path)[0]]) bld.pre_build() if flush: bld.flush() return bld ldb-2.0.8/buildtools/wafsamba/stale_files.py0000660000000000000000000000771713573675413021055 0ustar rootroot00000000000000# encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) """ Add a pre-build hook to remove all build files which do not have a corresponding target This can be used for example to remove the targets that have changed name without performing a full 'waf clean' Of course, it will only work if there are no dynamically generated nodes/tasks, in which case the method will have to be modified to exclude some folders for example. """ from waflib import Logs, Build, Options, Utils, Errors import os from wafsamba import samba_utils from Runner import Parallel old_refill_task_list = Parallel.refill_task_list def replace_refill_task_list(self): '''replacement for refill_task_list() that deletes stale files''' iit = old_refill_task_list(self) bld = self.bld if not getattr(bld, 'new_rules', False): # we only need to check for stale files if the build rules changed return iit if Options.options.compile_targets: # not safe when --target is used return iit # execute only once if getattr(self, 'cleanup_done', False): return iit self.cleanup_done = True def group_name(g): tm = self.bld.task_manager return [x for x in tm.groups_names if id(tm.groups_names[x]) == id(g)][0] bin_base = bld.bldnode.abspath() bin_base_len = len(bin_base) # paranoia if bin_base[-4:] != '/bin': raise Errors.WafError("Invalid bin base: %s" % bin_base) # obtain the expected list of files expected = [] for i in range(len(bld.task_manager.groups)): g = bld.task_manager.groups[i] tasks = g.tasks_gen for x in tasks: try: if getattr(x, 'target'): tlist = samba_utils.TO_LIST(getattr(x, 'target')) ttype = getattr(x, 'samba_type', None) task_list = getattr(x, 'compiled_tasks', []) if task_list: # this gets all of the .o files, including the task # ids, so foo.c maps to foo_3.o for idx=3 for tsk in task_list: for output in tsk.outputs: objpath = os.path.normpath(output.abspath(bld.env)) expected.append(objpath) for t in tlist: if ttype in ['LIBRARY','MODULE']: t = samba_utils.apply_pattern(t, bld.env.shlib_PATTERN) if ttype == 'PYTHON': t = samba_utils.apply_pattern(t, bld.env.pyext_PATTERN) p = os.path.join(x.path.abspath(bld.env), t) p = os.path.normpath(p) expected.append(p) for n in x.allnodes: p = n.abspath(bld.env) if p[0:bin_base_len] == bin_base: expected.append(p) except: pass for root, dirs, files in os.walk(bin_base): for f in files: p = root + '/' + f if os.path.islink(p): link = os.readlink(p) if link[0:bin_base_len] == bin_base: p = link if f in ['config.h']: continue (froot, fext) = os.path.splitext(f) if fext not in [ '.c', '.h', '.so', '.o' ]: continue if f[-7:] == '.inst.h': continue if p.find("/.conf") != -1: continue if not p in expected and os.path.exists(p): Logs.warn("Removing stale file: %s" % p) os.unlink(p) return iit def AUTOCLEANUP_STALE_FILES(bld): """automatically clean up any files in bin that shouldn't be there""" old_refill_task_list = Parallel.refill_task_list Parallel.refill_task_list = replace_refill_task_list Parallel.bld = bld Build.BuildContext.AUTOCLEANUP_STALE_FILES = AUTOCLEANUP_STALE_FILES ldb-2.0.8/buildtools/wafsamba/symbols.py0000660000000000000000000005336713573675413020255 0ustar rootroot00000000000000# a waf tool to extract symbols from object files or libraries # using nm, producing a set of exposed defined/undefined symbols import os, re, subprocess from waflib import Utils, Build, Options, Logs, Errors from waflib.Logs import debug from samba_utils import TO_LIST, LOCAL_CACHE, get_tgt_list, os_path_relpath # these are the data structures used in symbols.py: # # bld.env.symbol_map : dictionary mapping public symbol names to list of # subsystem names where that symbol exists # # t.in_library : list of libraries that t is in # # bld.env.public_symbols: set of public symbols for each subsystem # bld.env.used_symbols : set of used symbols for each subsystem # # bld.env.syslib_symbols: dictionary mapping system library name to set of symbols # for that library # bld.env.library_dict : dictionary mapping built library paths to subsystem names # # LOCAL_CACHE(bld, 'TARGET_TYPE') : dictionary mapping subsystem name to target type def symbols_extract(bld, objfiles, dynamic=False): '''extract symbols from objfile, returning a dictionary containing the set of undefined and public symbols for each file''' ret = {} # see if we can get some results from the nm cache if not bld.env.nm_cache: bld.env.nm_cache = {} objfiles = set(objfiles).copy() remaining = set() for obj in objfiles: if obj in bld.env.nm_cache: ret[obj] = bld.env.nm_cache[obj].copy() else: remaining.add(obj) objfiles = remaining if len(objfiles) == 0: return ret cmd = ["nm"] if dynamic: # needed for some .so files cmd.append("-D") cmd.extend(list(objfiles)) nmpipe = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout if len(objfiles) == 1: filename = list(objfiles)[0] ret[filename] = { "PUBLIC": set(), "UNDEFINED" : set()} for line in nmpipe: line = line.strip() if line.endswith(b':'): filename = line[:-1] ret[filename] = { "PUBLIC": set(), "UNDEFINED" : set() } continue cols = line.split(b" ") if cols == [b'']: continue # see if the line starts with an address if len(cols) == 3: symbol_type = cols[1] symbol = cols[2] else: symbol_type = cols[0] symbol = cols[1] if symbol_type in b"BDGTRVWSi": # its a public symbol ret[filename]["PUBLIC"].add(symbol) elif symbol_type in b"U": ret[filename]["UNDEFINED"].add(symbol) # add to the cache for obj in objfiles: if obj in ret: bld.env.nm_cache[obj] = ret[obj].copy() else: bld.env.nm_cache[obj] = { "PUBLIC": set(), "UNDEFINED" : set() } return ret def real_name(name): if name.find(".objlist") != -1: name = name[:-8] return name def find_ldd_path(bld, libname, binary): '''find the path to the syslib we will link against''' ret = None if not bld.env.syslib_paths: bld.env.syslib_paths = {} if libname in bld.env.syslib_paths: return bld.env.syslib_paths[libname] lddpipe = subprocess.Popen(['ldd', binary], stdout=subprocess.PIPE).stdout for line in lddpipe: line = line.strip() cols = line.split(b" ") if len(cols) < 3 or cols[1] != b"=>": continue if cols[0].startswith(b"libc."): # save this one too bld.env.libc_path = cols[2] if cols[0].startswith(libname): ret = cols[2] bld.env.syslib_paths[libname] = ret return ret # some regular expressions for parsing readelf output re_sharedlib = re.compile(b'Shared library: \[(.*)\]') # output from readelf could be `Library rpath` or `Libray runpath` re_rpath = re.compile(b'Library (rpath|runpath): \[(.*)\]') def get_libs(bld, binname): '''find the list of linked libraries for any binary or library binname is the path to the binary/library on disk We do this using readelf instead of ldd as we need to avoid recursing into system libraries ''' # see if we can get the result from the ldd cache if not bld.env.lib_cache: bld.env.lib_cache = {} if binname in bld.env.lib_cache: return bld.env.lib_cache[binname].copy() rpath = [] libs = set() elfpipe = subprocess.Popen(['readelf', '--dynamic', binname], stdout=subprocess.PIPE).stdout for line in elfpipe: m = re_sharedlib.search(line) if m: libs.add(m.group(1)) m = re_rpath.search(line) if m: # output from Popen is always bytestr even in py3 rpath.extend(m.group(2).split(b":")) ret = set() for lib in libs: found = False for r in rpath: path = os.path.join(r, lib) if os.path.exists(path): ret.add(os.path.realpath(path)) found = True break if not found: # we didn't find this lib using rpath. It is probably a system # library, so to find the path to it we either need to use ldd # or we need to start parsing /etc/ld.so.conf* ourselves. We'll # use ldd for now, even though it is slow path = find_ldd_path(bld, lib, binname) if path: ret.add(os.path.realpath(path)) bld.env.lib_cache[binname] = ret.copy() return ret def get_libs_recursive(bld, binname, seen): '''find the recursive list of linked libraries for any binary or library binname is the path to the binary/library on disk. seen is a set used to prevent loops ''' if binname in seen: return set() ret = get_libs(bld, binname) seen.add(binname) for lib in ret: # we don't want to recurse into system libraries. If a system # library that we use (eg. libcups) happens to use another library # (such as libkrb5) which contains common symbols with our own # libraries, then that is not an error if lib in bld.env.library_dict: ret = ret.union(get_libs_recursive(bld, lib, seen)) return ret def find_syslib_path(bld, libname, deps): '''find the path to the syslib we will link against''' # the strategy is to use the targets that depend on the library, and run ldd # on it to find the real location of the library that is used linkpath = deps[0].link_task.outputs[0].abspath(bld.env) if libname == "python": libname += bld.env.PYTHON_VERSION return find_ldd_path(bld, "lib%s" % libname.lower(), linkpath) def build_symbol_sets(bld, tgt_list): '''build the public_symbols and undefined_symbols attributes for each target''' if bld.env.public_symbols: return objlist = [] # list of object file objmap = {} # map from object filename to target (subsystem) name for t in tgt_list: t.public_symbols = set() t.undefined_symbols = set() t.used_symbols = set() for tsk in getattr(t, 'compiled_tasks', []): for output in tsk.outputs: objpath = output.abspath(bld.env) objlist.append(objpath) objmap[objpath] = t symbols = symbols_extract(bld, objlist) for obj in objlist: t = objmap[obj] t.public_symbols = t.public_symbols.union(symbols[obj]["PUBLIC"]) t.undefined_symbols = t.undefined_symbols.union(symbols[obj]["UNDEFINED"]) t.used_symbols = t.used_symbols.union(symbols[obj]["UNDEFINED"]) t.undefined_symbols = t.undefined_symbols.difference(t.public_symbols) # and the reverse map of public symbols to subsystem name bld.env.symbol_map = {} for t in tgt_list: for s in t.public_symbols: if not s in bld.env.symbol_map: bld.env.symbol_map[s] = [] bld.env.symbol_map[s].append(real_name(t.sname)) targets = LOCAL_CACHE(bld, 'TARGET_TYPE') bld.env.public_symbols = {} for t in tgt_list: name = real_name(t.sname) if name in bld.env.public_symbols: bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t.public_symbols) else: bld.env.public_symbols[name] = t.public_symbols if t.samba_type == 'LIBRARY': for dep in t.add_objects: t2 = bld.get_tgen_by_name(dep) bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t2.public_symbols) bld.env.used_symbols = {} for t in tgt_list: name = real_name(t.sname) if name in bld.env.used_symbols: bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t.used_symbols) else: bld.env.used_symbols[name] = t.used_symbols if t.samba_type == 'LIBRARY': for dep in t.add_objects: t2 = bld.get_tgen_by_name(dep) bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t2.used_symbols) def build_library_dict(bld, tgt_list): '''build the library_dict dictionary''' if bld.env.library_dict: return bld.env.library_dict = {} for t in tgt_list: if t.samba_type in [ 'LIBRARY', 'PYTHON' ]: linkpath = os.path.realpath(t.link_task.outputs[0].abspath(bld.env)) bld.env.library_dict[linkpath] = t.sname def build_syslib_sets(bld, tgt_list): '''build the public_symbols for all syslibs''' if bld.env.syslib_symbols: return # work out what syslibs we depend on, and what targets those are used in syslibs = {} objmap = {} for t in tgt_list: if getattr(t, 'uselib', []) and t.samba_type in [ 'LIBRARY', 'BINARY', 'PYTHON' ]: for lib in t.uselib: if lib in ['PYEMBED', 'PYEXT']: lib = "python" if not lib in syslibs: syslibs[lib] = [] syslibs[lib].append(t) # work out the paths to each syslib syslib_paths = [] for lib in syslibs: path = find_syslib_path(bld, lib, syslibs[lib]) if path is None: Logs.warn("Unable to find syslib path for %s" % lib) if path is not None: syslib_paths.append(path) objmap[path] = lib.lower() # add in libc syslib_paths.append(bld.env.libc_path) objmap[bld.env.libc_path] = 'c' symbols = symbols_extract(bld, syslib_paths, dynamic=True) # keep a map of syslib names to public symbols bld.env.syslib_symbols = {} for lib in symbols: bld.env.syslib_symbols[lib] = symbols[lib]["PUBLIC"] # add to the map of symbols to dependencies for lib in symbols: for sym in symbols[lib]["PUBLIC"]: if not sym in bld.env.symbol_map: bld.env.symbol_map[sym] = [] bld.env.symbol_map[sym].append(objmap[lib]) # keep the libc symbols as well, as these are useful for some of the # sanity checks bld.env.libc_symbols = symbols[bld.env.libc_path]["PUBLIC"] # add to the combined map of dependency name to public_symbols for lib in bld.env.syslib_symbols: bld.env.public_symbols[objmap[lib]] = bld.env.syslib_symbols[lib] def build_autodeps(bld, t): '''build the set of dependencies for a target''' deps = set() name = real_name(t.sname) targets = LOCAL_CACHE(bld, 'TARGET_TYPE') for sym in t.undefined_symbols: if sym in t.public_symbols: continue if sym in bld.env.symbol_map: depname = bld.env.symbol_map[sym] if depname == [ name ]: # self dependencies aren't interesting continue if t.in_library == depname: # no need to depend on the library we are part of continue if depname[0] in ['c', 'python']: # these don't go into autodeps continue if targets[depname[0]] in [ 'SYSLIB' ]: deps.add(depname[0]) continue t2 = bld.get_tgen_by_name(depname[0]) if len(t2.in_library) != 1: deps.add(depname[0]) continue if t2.in_library == t.in_library: # if we're part of the same library, we don't need to autodep continue deps.add(t2.in_library[0]) t.autodeps = deps def build_library_names(bld, tgt_list): '''add a in_library attribute to all targets that are part of a library''' if bld.env.done_build_library_names: return for t in tgt_list: t.in_library = [] for t in tgt_list: if t.samba_type in [ 'LIBRARY' ]: for obj in t.samba_deps_extended: t2 = bld.get_tgen_by_name(obj) if t2 and t2.samba_type in [ 'SUBSYSTEM', 'ASN1' ]: if not t.sname in t2.in_library: t2.in_library.append(t.sname) bld.env.done_build_library_names = True def check_library_deps(bld, t): '''check that all the autodeps that have mutual dependency of this target are in the same library as the target''' name = real_name(t.sname) if len(t.in_library) > 1: Logs.warn("WARNING: Target '%s' in multiple libraries: %s" % (t.sname, t.in_library)) for dep in t.autodeps: t2 = bld.get_tgen_by_name(dep) if t2 is None: continue for dep2 in t2.autodeps: if dep2 == name and t.in_library != t2.in_library: Logs.warn("WARNING: mutual dependency %s <=> %s" % (name, real_name(t2.sname))) Logs.warn("Libraries should match. %s != %s" % (t.in_library, t2.in_library)) # raise Errors.WafError("illegal mutual dependency") def check_syslib_collisions(bld, tgt_list): '''check if a target has any symbol collisions with a syslib We do not want any code in Samba to use a symbol name from a system library. The chance of that causing problems is just too high. Note that libreplace uses a rep_XX approach of renaming symbols via macros ''' has_error = False for t in tgt_list: for lib in bld.env.syslib_symbols: common = t.public_symbols.intersection(bld.env.syslib_symbols[lib]) if common: Logs.error("ERROR: Target '%s' has symbols '%s' which is also in syslib '%s'" % (t.sname, common, lib)) has_error = True if has_error: raise Errors.WafError("symbols in common with system libraries") def check_dependencies(bld, t): '''check for depenencies that should be changed''' if bld.get_tgen_by_name(t.sname + ".objlist"): return targets = LOCAL_CACHE(bld, 'TARGET_TYPE') remaining = t.undefined_symbols.copy() remaining = remaining.difference(t.public_symbols) sname = real_name(t.sname) deps = set(t.samba_deps) for d in t.samba_deps: if targets[d] in [ 'EMPTY', 'DISABLED', 'SYSLIB', 'GENERATOR' ]: continue bld.ASSERT(d in bld.env.public_symbols, "Failed to find symbol list for dependency '%s'" % d) diff = remaining.intersection(bld.env.public_symbols[d]) if not diff and targets[sname] != 'LIBRARY': Logs.info("Target '%s' has no dependency on %s" % (sname, d)) else: remaining = remaining.difference(diff) t.unsatisfied_symbols = set() needed = {} for sym in remaining: if sym in bld.env.symbol_map: dep = bld.env.symbol_map[sym] if not dep[0] in needed: needed[dep[0]] = set() needed[dep[0]].add(sym) else: t.unsatisfied_symbols.add(sym) for dep in needed: Logs.info("Target '%s' should add dep '%s' for symbols %s" % (sname, dep, " ".join(needed[dep]))) def check_syslib_dependencies(bld, t): '''check for syslib depenencies''' if bld.get_tgen_by_name(t.sname + ".objlist"): return sname = real_name(t.sname) remaining = set() features = TO_LIST(t.features) if 'pyembed' in features or 'pyext' in features: if 'python' in bld.env.public_symbols: t.unsatisfied_symbols = t.unsatisfied_symbols.difference(bld.env.public_symbols['python']) needed = {} for sym in t.unsatisfied_symbols: if sym in bld.env.symbol_map: dep = bld.env.symbol_map[sym][0] if dep == 'c': continue if not dep in needed: needed[dep] = set() needed[dep].add(sym) else: remaining.add(sym) for dep in needed: Logs.info("Target '%s' should add syslib dep '%s' for symbols %s" % (sname, dep, " ".join(needed[dep]))) if remaining: debug("deps: Target '%s' has unsatisfied symbols: %s" % (sname, " ".join(remaining))) def symbols_symbolcheck(task): '''check the internal dependency lists''' bld = task.env.bld tgt_list = get_tgt_list(bld) build_symbol_sets(bld, tgt_list) build_library_names(bld, tgt_list) for t in tgt_list: t.autodeps = set() if getattr(t, 'source', ''): build_autodeps(bld, t) for t in tgt_list: check_dependencies(bld, t) for t in tgt_list: check_library_deps(bld, t) def symbols_syslibcheck(task): '''check the syslib dependencies''' bld = task.env.bld tgt_list = get_tgt_list(bld) build_syslib_sets(bld, tgt_list) check_syslib_collisions(bld, tgt_list) for t in tgt_list: check_syslib_dependencies(bld, t) def symbols_whyneeded(task): """check why 'target' needs to link to 'subsystem'""" bld = task.env.bld tgt_list = get_tgt_list(bld) why = Options.options.WHYNEEDED.split(":") if len(why) != 2: raise Errors.WafError("usage: WHYNEEDED=TARGET:DEPENDENCY") target = why[0] subsystem = why[1] build_symbol_sets(bld, tgt_list) build_library_names(bld, tgt_list) build_syslib_sets(bld, tgt_list) Logs.info("Checking why %s needs to link to %s" % (target, subsystem)) if not target in bld.env.used_symbols: Logs.warn("unable to find target '%s' in used_symbols dict" % target) return if not subsystem in bld.env.public_symbols: Logs.warn("unable to find subsystem '%s' in public_symbols dict" % subsystem) return overlap = bld.env.used_symbols[target].intersection(bld.env.public_symbols[subsystem]) if not overlap: Logs.info("target '%s' doesn't use any public symbols from '%s'" % (target, subsystem)) else: Logs.info("target '%s' uses symbols %s from '%s'" % (target, overlap, subsystem)) def report_duplicate(bld, binname, sym, libs, fail_on_error): '''report duplicated symbols''' if sym in ['_init', '_fini', '_edata', '_end', '__bss_start']: return libnames = [] for lib in libs: if lib in bld.env.library_dict: libnames.append(bld.env.library_dict[lib]) else: libnames.append(lib) if fail_on_error: raise Errors.WafError("%s: Symbol %s linked in multiple libraries %s" % (binname, sym, libnames)) else: print("%s: Symbol %s linked in multiple libraries %s" % (binname, sym, libnames)) def symbols_dupcheck_binary(bld, binname, fail_on_error): '''check for duplicated symbols in one binary''' libs = get_libs_recursive(bld, binname, set()) symlist = symbols_extract(bld, libs, dynamic=True) symmap = {} for libpath in symlist: for sym in symlist[libpath]['PUBLIC']: if sym == '_GLOBAL_OFFSET_TABLE_': continue if not sym in symmap: symmap[sym] = set() symmap[sym].add(libpath) for sym in symmap: if len(symmap[sym]) > 1: for libpath in symmap[sym]: if libpath in bld.env.library_dict: report_duplicate(bld, binname, sym, symmap[sym], fail_on_error) break def symbols_dupcheck(task, fail_on_error=False): '''check for symbols defined in two different subsystems''' bld = task.env.bld tgt_list = get_tgt_list(bld) targets = LOCAL_CACHE(bld, 'TARGET_TYPE') build_library_dict(bld, tgt_list) for t in tgt_list: if t.samba_type == 'BINARY': binname = os_path_relpath(t.link_task.outputs[0].abspath(bld.env), os.getcwd()) symbols_dupcheck_binary(bld, binname, fail_on_error) def symbols_dupcheck_fatal(task): '''check for symbols defined in two different subsystems (and fail if duplicates are found)''' symbols_dupcheck(task, fail_on_error=True) def SYMBOL_CHECK(bld): '''check our dependency lists''' if Options.options.SYMBOLCHECK: bld.SET_BUILD_GROUP('symbolcheck') task = bld(rule=symbols_symbolcheck, always=True, name='symbol checking') task.env.bld = bld bld.SET_BUILD_GROUP('syslibcheck') task = bld(rule=symbols_syslibcheck, always=True, name='syslib checking') task.env.bld = bld bld.SET_BUILD_GROUP('syslibcheck') task = bld(rule=symbols_dupcheck, always=True, name='symbol duplicate checking') task.env.bld = bld if Options.options.WHYNEEDED: bld.SET_BUILD_GROUP('syslibcheck') task = bld(rule=symbols_whyneeded, always=True, name='check why a dependency is needed') task.env.bld = bld Build.BuildContext.SYMBOL_CHECK = SYMBOL_CHECK def DUP_SYMBOL_CHECK(bld): if Options.options.DUP_SYMBOLCHECK and bld.env.DEVELOPER: '''check for duplicate symbols''' bld.SET_BUILD_GROUP('syslibcheck') task = bld(rule=symbols_dupcheck_fatal, always=True, name='symbol duplicate checking') task.env.bld = bld Build.BuildContext.DUP_SYMBOL_CHECK = DUP_SYMBOL_CHECK ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh0000770000000000000000000000044413573675413023133 0ustar rootroot00000000000000#!/bin/sh # Run the waf duplicate symbol check, wrapped in subunit. . testprogs/blackbox/subunit.sh subunit_start_test duplicate_symbols if $PYTHON ./buildtools/bin/waf build --dup-symbol-check; then subunit_pass_test duplicate_symbols else echo | subunit_fail_test duplicate_symbols fi ldb-2.0.8/buildtools/wafsamba/tests/__init__.py0000660000000000000000000000224012406075657021444 0ustar rootroot00000000000000# Copyright (C) 2012 Jelmer Vernooij # This program 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 2.1 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 Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Tests for wafsamba.""" from unittest import ( TestCase, TestLoader, ) def test_suite(): names = [ 'abi', 'bundled', 'utils', ] module_names = ['wafsamba.tests.test_' + name for name in names] loader = TestLoader() result = loader.suiteClass() suite = loader.loadTestsFromNames(module_names) result.addTests(suite) return result ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py0000660000000000000000000001042013573675413021500 0ustar rootroot00000000000000# Copyright (C) 2012 Jelmer Vernooij # This program 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 2.1 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 Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from wafsamba.tests import TestCase from wafsamba.samba_abi import ( abi_write_vscript, normalise_signature, ) from samba.compat import StringIO class NormaliseSignatureTests(TestCase): def test_function_simple(self): self.assertEquals("int (const struct GUID *, const struct GUID *)", normalise_signature("$2 = {int (const struct GUID *, const struct GUID *)} 0xe871 ")) def test_maps_Bool(self): # Some types have different internal names self.assertEquals("bool (const struct GUID *)", normalise_signature("$1 = {_Bool (const struct GUID *)} 0xe75b ")) def test_function_keep(self): self.assertEquals( "enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)", normalise_signature("enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)")) def test_struct_constant(self): self.assertEquals( 'uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0', normalise_signature('$239 = {uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0}')) def test_incomplete_sequence(self): # Newer versions of gdb insert these incomplete sequence elements self.assertEquals( 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237", , node = "\\b\\000+\\020H`"}, if_version = 2}')) self.assertEquals( 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2}')) class WriteVscriptTests(TestCase): def test_one(self): f = StringIO() abi_write_vscript(f, "MYLIB", "1.0", [], { "old": "1.0", "new": "1.0"}, ["*"]) self.assertEquals(f.getvalue(), """\ 1.0 { \tglobal: \t\t*; \tlocal: \t\t_end; \t\t__bss_start; \t\t_edata; }; """) def test_simple(self): # No restrictions. f = StringIO() abi_write_vscript(f, "MYLIB", "1.0", ["0.1"], { "old": "0.1", "new": "1.0"}, ["*"]) self.assertEquals(f.getvalue(), """\ MYLIB_0.1 { \tglobal: \t\told; }; 1.0 { \tglobal: \t\t*; \tlocal: \t\t_end; \t\t__bss_start; \t\t_edata; }; """) def test_exclude(self): f = StringIO() abi_write_vscript(f, "MYLIB", "1.0", [], { "exc_old": "0.1", "old": "0.1", "new": "1.0"}, ["!exc_*"]) self.assertEquals(f.getvalue(), """\ 1.0 { \tglobal: \t\t*; \tlocal: \t\texc_*; \t\t_end; \t\t__bss_start; \t\t_edata; }; """) def test_excludes_and_includes(self): f = StringIO() abi_write_vscript(f, "MYLIB", "1.0", [], { "pub_foo": "1.0", "exc_bar": "1.0", "other": "1.0" }, ["pub_*", "!exc_*"]) self.assertEquals(f.getvalue(), """\ 1.0 { \tglobal: \t\tpub_*; \tlocal: \t\texc_*; \t\t_end; \t\t__bss_start; \t\t_edata; \t\t*; }; """) ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py0000660000000000000000000000176412406075657022373 0ustar rootroot00000000000000# Copyright (C) 2012 Jelmer Vernooij # This program 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 2.1 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 Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from wafsamba.tests import TestCase from wafsamba.samba_bundled import ( tuplize_version, ) class TuplizeVersionTests(TestCase): def test_simple(self): self.assertEquals((1, 2, 10), tuplize_version("1.2.10")) ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py0000660000000000000000000000473412406075657022116 0ustar rootroot00000000000000# Copyright (C) 2012 Jelmer Vernooij # This program 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 2.1 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 Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from wafsamba.tests import TestCase from wafsamba.samba_utils import ( TO_LIST, dict_concat, subst_vars_error, unique_list, ) class ToListTests(TestCase): def test_none(self): self.assertEquals([], TO_LIST(None)) def test_already_list(self): self.assertEquals(["foo", "bar", 1], TO_LIST(["foo", "bar", 1])) def test_default_delimiter(self): self.assertEquals(["foo", "bar"], TO_LIST("foo bar")) self.assertEquals(["foo", "bar"], TO_LIST(" foo bar ")) self.assertEquals(["foo ", "bar"], TO_LIST(" \"foo \" bar ")) def test_delimiter(self): self.assertEquals(["foo", "bar"], TO_LIST("foo,bar", ",")) self.assertEquals([" foo", "bar "], TO_LIST(" foo,bar ", ",")) self.assertEquals([" \" foo\"", " bar "], TO_LIST(" \" foo\", bar ", ",")) class UniqueListTests(TestCase): def test_unique_list(self): self.assertEquals(["foo", "bar"], unique_list(["foo", "bar", "foo"])) class SubstVarsErrorTests(TestCase): def test_valid(self): self.assertEquals("", subst_vars_error("", {})) self.assertEquals("FOO bar", subst_vars_error("${F} bar", {"F": "FOO"})) def test_invalid(self): self.assertRaises(KeyError, subst_vars_error, "${F}", {}) class DictConcatTests(TestCase): def test_empty(self): ret = {} dict_concat(ret, {}) self.assertEquals({}, ret) def test_same(self): ret = {"foo": "bar"} dict_concat(ret, {"foo": "bla"}) self.assertEquals({"foo": "bar"}, ret) def test_simple(self): ret = {"foo": "bar"} dict_concat(ret, {"blie": "bla"}) self.assertEquals({"foo": "bar", "blie": "bla"}, ret) ldb-2.0.8/buildtools/wafsamba/wafsamba.py0000660000000000000000000010331413573675413020332 0ustar rootroot00000000000000# a waf tool to add autoconf-like macros to the configure section # and for SAMBA_ macros for building libraries, binaries etc import os, sys, re, shutil, fnmatch from waflib import Build, Options, Task, Utils, TaskGen, Logs, Context, Errors from waflib.Configure import conf from waflib.Logs import debug from samba_utils import SUBST_VARS_RECURSIVE TaskGen.task_gen.apply_verif = Utils.nada # bring in the other samba modules from samba_utils import * from samba_utils import symlink from samba_version import * from samba_autoconf import * from samba_patterns import * from samba_pidl import * from samba_autoproto import * from samba_python import * from samba_perl import * from samba_deps import * from samba_bundled import * from samba_third_party import * import samba_cross import samba_install import samba_conftests import samba_abi import samba_headers import generic_cc import samba_dist import samba_wildcard import symbols import pkgconfig import configure_file import samba_waf18 LIB_PATH="shared" os.environ['PYTHONUNBUFFERED'] = '1' if Context.HEXVERSION not in (0x2001200,): Logs.error(''' Please use the version of waf that comes with Samba, not a system installed version. See http://wiki.samba.org/index.php/Waf for details. Alternatively, please run ./configure and make as usual. That will call the right version of waf.''') sys.exit(1) @conf def SAMBA_BUILD_ENV(conf): '''create the samba build environment''' conf.env.BUILD_DIRECTORY = conf.bldnode.abspath() mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH)) mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH, "private")) mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, "modules")) mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'python/samba/dcerpc')) # this allows all of the bin/shared and bin/python targets # to be expressed in terms of build directory paths mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'default')) for (source, target) in [('shared', 'shared'), ('modules', 'modules'), ('python', 'python')]: link_target = os.path.join(conf.env.BUILD_DIRECTORY, 'default/' + target) if not os.path.lexists(link_target): symlink('../' + source, link_target) # get perl to put the blib files in the build directory blib_bld = os.path.join(conf.env.BUILD_DIRECTORY, 'default/pidl/blib') blib_src = os.path.join(conf.srcnode.abspath(), 'pidl/blib') mkdir_p(blib_bld + '/man1') mkdir_p(blib_bld + '/man3') if os.path.islink(blib_src): os.unlink(blib_src) elif os.path.exists(blib_src): shutil.rmtree(blib_src) def ADD_INIT_FUNCTION(bld, subsystem, target, init_function): '''add an init_function to the list for a subsystem''' if init_function is None: return bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function) cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') if not subsystem in cache: cache[subsystem] = [] cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } ) Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION def generate_empty_file(task): task.outputs[0].write('') return 0 ################################################################# def SAMBA_LIBRARY(bld, libname, source, deps='', public_deps='', includes='', public_headers=None, public_headers_install=True, private_headers=None, header_path=None, pc_files=None, vnum=None, soname=None, cflags='', cflags_end=None, ldflags='', external_library=False, realname=None, keep_underscore=False, autoproto=None, autoproto_extra_source='', group='main', depends_on='', local_include=True, global_include=True, vars=None, subdir=None, install_path=None, install=True, pyembed=False, pyext=False, target_type='LIBRARY', bundled_extension=False, bundled_name=None, link_name=None, abi_directory=None, abi_match=None, hide_symbols=False, manpages=None, private_library=False, grouping_library=False, allow_undefined_symbols=False, allow_warnings=False, enabled=True): '''define a Samba library''' if private_library and public_headers: raise Errors.WafError("private library '%s' must not have public header files" % libname) if LIB_MUST_BE_PRIVATE(bld, libname): private_library = True if not enabled: SET_TARGET_TYPE(bld, libname, 'DISABLED') return source = bld.EXPAND_VARIABLES(source, vars=vars) if subdir: source = bld.SUBDIR(subdir, source) # remember empty libraries, so we can strip the dependencies if ((source == '') or (source == [])): if deps == '' and public_deps == '': SET_TARGET_TYPE(bld, libname, 'EMPTY') return empty_c = libname + '.empty.c' bld.SAMBA_GENERATOR('%s_empty_c' % libname, rule=generate_empty_file, target=empty_c) source=empty_c if BUILTIN_LIBRARY(bld, libname): obj_target = libname else: obj_target = libname + '.objlist' if group == 'libraries': subsystem_group = 'main' else: subsystem_group = group # first create a target for building the object files for this library # by separating in this way, we avoid recompiling the C files # separately for the install library and the build library bld.SAMBA_SUBSYSTEM(obj_target, source = source, deps = deps, public_deps = public_deps, includes = includes, public_headers = public_headers, public_headers_install = public_headers_install, private_headers= private_headers, header_path = header_path, cflags = cflags, cflags_end = cflags_end, group = subsystem_group, autoproto = autoproto, autoproto_extra_source=autoproto_extra_source, depends_on = depends_on, hide_symbols = hide_symbols, allow_warnings = allow_warnings, pyembed = pyembed, pyext = pyext, local_include = local_include, global_include = global_include) if BUILTIN_LIBRARY(bld, libname): return if not SET_TARGET_TYPE(bld, libname, target_type): return # the library itself will depend on that object target deps += ' ' + public_deps deps = TO_LIST(deps) deps.append(obj_target) realname = bld.map_shlib_extension(realname, python=(target_type=='PYTHON')) link_name = bld.map_shlib_extension(link_name, python=(target_type=='PYTHON')) # we don't want any public libraries without version numbers if (not private_library and target_type != 'PYTHON' and not realname): if vnum is None and soname is None: raise Errors.WafError("public library '%s' must have a vnum" % libname) if pc_files is None: raise Errors.WafError("public library '%s' must have pkg-config file" % libname) if public_headers is None: raise Errors.WafError("public library '%s' must have header files" % libname) if bundled_name is not None: pass elif target_type == 'PYTHON' or realname or not private_library: if keep_underscore: bundled_name = libname else: bundled_name = libname.replace('_', '-') else: assert (private_library == True and realname is None) if abi_directory or vnum or soname: bundled_extension=True bundled_name = PRIVATE_NAME(bld, libname.replace('_', '-'), bundled_extension, private_library) ldflags = TO_LIST(ldflags) if bld.env['ENABLE_RELRO'] is True: ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now')) features = 'c cshlib symlink_lib install_lib' if pyext: features += ' pyext' if pyembed: features += ' pyembed' if abi_directory: features += ' abi_check' if pyembed and bld.env['PYTHON_SO_ABI_FLAG']: # For ABI checking, we don't care about the Python version. # Remove the Python ABI tag (e.g. ".cpython-35m") abi_flag = bld.env['PYTHON_SO_ABI_FLAG'] replacement = '' version_libname = libname.replace(abi_flag, replacement) else: version_libname = libname vscript = None if bld.env.HAVE_LD_VERSION_SCRIPT: if private_library: version = "%s_%s" % (Context.g_module.APPNAME, Context.g_module.VERSION) elif vnum: version = "%s_%s" % (libname, vnum) else: version = None if version: vscript = "%s.vscript" % libname bld.ABI_VSCRIPT(version_libname, abi_directory, version, vscript, abi_match) fullname = apply_pattern(bundled_name, bld.env.cshlib_PATTERN) fullpath = bld.path.find_or_declare(fullname) vscriptpath = bld.path.find_or_declare(vscript) if not fullpath: raise Errors.WafError("unable to find fullpath for %s" % fullname) if not vscriptpath: raise Errors.WafError("unable to find vscript path for %s" % vscript) bld.add_manual_dependency(fullpath, vscriptpath) if bld.is_install: # also make the .inst file depend on the vscript instname = apply_pattern(bundled_name + '.inst', bld.env.cshlib_PATTERN) bld.add_manual_dependency(bld.path.find_or_declare(instname), bld.path.find_or_declare(vscript)) vscript = os.path.join(bld.path.abspath(bld.env), vscript) bld.SET_BUILD_GROUP(group) t = bld( features = features, source = [], target = bundled_name, depends_on = depends_on, samba_ldflags = ldflags, samba_deps = deps, samba_includes = includes, version_script = vscript, version_libname = version_libname, local_include = local_include, global_include = global_include, vnum = vnum, soname = soname, install_path = None, samba_inst_path = install_path, name = libname, samba_realname = realname, samba_install = install, abi_directory = "%s/%s" % (bld.path.abspath(), abi_directory), abi_match = abi_match, private_library = private_library, grouping_library=grouping_library, allow_undefined_symbols=allow_undefined_symbols ) if realname and not link_name: link_name = 'shared/%s' % realname if link_name: if 'waflib.extras.compat15' in sys.modules: link_name = 'default/' + link_name t.link_name = link_name if pc_files is not None and not private_library: if pyembed: bld.PKG_CONFIG_FILES(pc_files, vnum=vnum, extra_name=bld.env['PYTHON_SO_ABI_FLAG']) else: bld.PKG_CONFIG_FILES(pc_files, vnum=vnum) if (manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']): bld.MANPAGES(manpages, install) Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY ################################################################# def SAMBA_BINARY(bld, binname, source, deps='', includes='', public_headers=None, private_headers=None, header_path=None, modules=None, ldflags=None, cflags='', cflags_end=None, autoproto=None, use_hostcc=False, use_global_deps=True, compiler=None, group='main', manpages=None, local_include=True, global_include=True, subsystem_name=None, pyembed=False, vars=None, subdir=None, install=True, install_path=None, enabled=True): '''define a Samba binary''' if not enabled: SET_TARGET_TYPE(bld, binname, 'DISABLED') return if not SET_TARGET_TYPE(bld, binname, 'BINARY'): return features = 'c cprogram symlink_bin install_bin' if pyembed: features += ' pyembed' obj_target = binname + '.objlist' source = bld.EXPAND_VARIABLES(source, vars=vars) if subdir: source = bld.SUBDIR(subdir, source) source = unique_list(TO_LIST(source)) if group == 'binaries': subsystem_group = 'main' else: subsystem_group = group # only specify PIE flags for binaries pie_cflags = cflags pie_ldflags = TO_LIST(ldflags) if bld.env['ENABLE_PIE'] is True: pie_cflags += ' -fPIE' pie_ldflags.extend(TO_LIST('-pie')) if bld.env['ENABLE_RELRO'] is True: pie_ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now')) # first create a target for building the object files for this binary # by separating in this way, we avoid recompiling the C files # separately for the install binary and the build binary bld.SAMBA_SUBSYSTEM(obj_target, source = source, deps = deps, includes = includes, cflags = pie_cflags, cflags_end = cflags_end, group = subsystem_group, autoproto = autoproto, subsystem_name = subsystem_name, local_include = local_include, global_include = global_include, use_hostcc = use_hostcc, pyext = pyembed, use_global_deps= use_global_deps) bld.SET_BUILD_GROUP(group) # the binary itself will depend on that object target deps = TO_LIST(deps) deps.append(obj_target) t = bld( features = features, source = [], target = binname, samba_deps = deps, samba_includes = includes, local_include = local_include, global_include = global_include, samba_modules = modules, top = True, samba_subsystem= subsystem_name, install_path = None, samba_inst_path= install_path, samba_install = install, samba_ldflags = pie_ldflags ) if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']: bld.MANPAGES(manpages, install) Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY ################################################################# def SAMBA_MODULE(bld, modname, source, deps='', includes='', subsystem=None, init_function=None, module_init_name='samba_init_module', autoproto=None, autoproto_extra_source='', cflags='', cflags_end=None, internal_module=True, local_include=True, global_include=True, vars=None, subdir=None, enabled=True, pyembed=False, manpages=None, allow_undefined_symbols=False, allow_warnings=False, install=True ): '''define a Samba module.''' bld.ASSERT(subsystem, "You must specify a subsystem for SAMBA_MODULE(%s)" % modname) source = bld.EXPAND_VARIABLES(source, vars=vars) if subdir: source = bld.SUBDIR(subdir, source) if internal_module or BUILTIN_LIBRARY(bld, modname): # Do not create modules for disabled subsystems if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED': return bld.SAMBA_SUBSYSTEM(modname, source, deps=deps, includes=includes, 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, enabled=enabled) bld.ADD_INIT_FUNCTION(subsystem, modname, init_function) return if not enabled: SET_TARGET_TYPE(bld, modname, 'DISABLED') return # Do not create modules for disabled subsystems if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED': return realname = modname deps += ' ' + subsystem while realname.startswith("lib"+subsystem+"_"): realname = realname[len("lib"+subsystem+"_"):] while realname.startswith(subsystem+"_"): realname = realname[len(subsystem+"_"):] build_name = "%s_module_%s" % (subsystem, realname) realname = bld.make_libname(realname) while realname.startswith("lib"): realname = realname[len("lib"):] build_link_name = "modules/%s/%s" % (subsystem, realname) if init_function: cflags += " -D%s=%s" % (init_function, module_init_name) bld.SAMBA_LIBRARY(modname, source, deps=deps, includes=includes, cflags=cflags, cflags_end=cflags_end, realname = realname, autoproto = autoproto, local_include=local_include, global_include=global_include, vars=vars, bundled_name=build_name, link_name=build_link_name, install_path="${MODULESDIR}/%s" % subsystem, pyembed=pyembed, manpages=manpages, allow_undefined_symbols=allow_undefined_symbols, allow_warnings=allow_warnings, install=install ) Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE ################################################################# def SAMBA_SUBSYSTEM(bld, modname, source, deps='', public_deps='', includes='', public_headers=None, public_headers_install=True, private_headers=None, header_path=None, cflags='', cflags_end=None, group='main', init_function_sentinel=None, autoproto=None, autoproto_extra_source='', depends_on='', local_include=True, local_include_first=True, global_include=True, subsystem_name=None, enabled=True, use_hostcc=False, use_global_deps=True, vars=None, subdir=None, hide_symbols=False, allow_warnings=False, pyext=False, pyembed=False): '''define a Samba subsystem''' if not enabled: SET_TARGET_TYPE(bld, modname, 'DISABLED') return # remember empty subsystems, so we can strip the dependencies if ((source == '') or (source == [])): if deps == '' and public_deps == '': SET_TARGET_TYPE(bld, modname, 'EMPTY') return empty_c = modname + '.empty.c' bld.SAMBA_GENERATOR('%s_empty_c' % modname, rule=generate_empty_file, target=empty_c) source=empty_c if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'): return source = bld.EXPAND_VARIABLES(source, vars=vars) if subdir: source = bld.SUBDIR(subdir, source) source = unique_list(TO_LIST(source)) deps += ' ' + public_deps bld.SET_BUILD_GROUP(group) features = 'c' if pyext: features += ' pyext' if pyembed: features += ' pyembed' t = bld( features = features, source = source, target = modname, samba_cflags = CURRENT_CFLAGS(bld, modname, cflags, allow_warnings=allow_warnings, hide_symbols=hide_symbols), depends_on = depends_on, samba_deps = TO_LIST(deps), samba_includes = includes, local_include = local_include, local_include_first = local_include_first, global_include = global_include, samba_subsystem= subsystem_name, samba_use_hostcc = use_hostcc, samba_use_global_deps = use_global_deps, ) if cflags_end is not None: t.samba_cflags.extend(TO_LIST(cflags_end)) if autoproto is not None: bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source)) if public_headers is not None: bld.PUBLIC_HEADERS(public_headers, header_path=header_path, public_headers_install=public_headers_install) return t Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM def SAMBA_GENERATOR(bld, name, rule, source='', target='', group='generators', enabled=True, public_headers=None, public_headers_install=True, private_headers=None, header_path=None, vars=None, dep_vars=[], always=False): '''A generic source generator target''' if not SET_TARGET_TYPE(bld, name, 'GENERATOR'): return if not enabled: return dep_vars.append('ruledeps') dep_vars.append('SAMBA_GENERATOR_VARS') bld.SET_BUILD_GROUP(group) t = bld( rule=rule, source=bld.EXPAND_VARIABLES(source, vars=vars), target=target, shell=isinstance(rule, str), update_outputs=True, before='c', ext_out='.c', samba_type='GENERATOR', dep_vars = dep_vars, name=name) if vars is None: vars = {} t.env.SAMBA_GENERATOR_VARS = vars if always: t.always = True if public_headers is not None: bld.PUBLIC_HEADERS(public_headers, header_path=header_path, public_headers_install=public_headers_install) return t Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR @Utils.run_once def SETUP_BUILD_GROUPS(bld): '''setup build groups used to ensure that the different build phases happen consecutively''' bld.p_ln = bld.srcnode # we do want to see all targets! bld.env['USING_BUILD_GROUPS'] = True bld.add_group('setup') bld.add_group('build_compiler_source') bld.add_group('vscripts') bld.add_group('base_libraries') bld.add_group('generators') bld.add_group('compiler_prototypes') bld.add_group('compiler_libraries') bld.add_group('build_compilers') bld.add_group('build_source') bld.add_group('prototypes') bld.add_group('headers') bld.add_group('main') bld.add_group('symbolcheck') bld.add_group('syslibcheck') bld.add_group('final') Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS def SET_BUILD_GROUP(bld, group): '''set the current build group''' if not 'USING_BUILD_GROUPS' in bld.env: return bld.set_group(group) Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None): '''used to copy scripts from the source tree into the build directory for use by selftest''' source = bld.path.ant_glob(pattern, flat=True) bld.SET_BUILD_GROUP('build_source') for s in TO_LIST(source): iname = s if installname is not None: iname = installname target = os.path.join(installdir, iname) tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target)) mkdir_p(tgtdir) link_src = os.path.normpath(os.path.join(bld.path.abspath(), s)) link_dst = os.path.join(tgtdir, os.path.basename(iname)) if os.path.islink(link_dst) and os.readlink(link_dst) == link_src: continue if os.path.islink(link_dst): os.unlink(link_dst) Logs.info("symlink: %s -> %s/%s" % (s, installdir, iname)) symlink(link_src, link_dst) Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT def copy_and_fix_python_path(task): pattern='sys.path.insert(0, "bin/python")' if task.env["PYTHONARCHDIR"] in sys.path and task.env["PYTHONDIR"] in sys.path: replacement = "" elif task.env["PYTHONARCHDIR"] == task.env["PYTHONDIR"]: replacement="""sys.path.insert(0, "%s")""" % task.env["PYTHONDIR"] else: replacement="""sys.path.insert(0, "%s") sys.path.insert(1, "%s")""" % (task.env["PYTHONARCHDIR"], task.env["PYTHONDIR"]) if task.env["PYTHON"][0].startswith("/"): replacement_shebang = "#!%s\n" % task.env["PYTHON"][0] else: replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PYTHON"][0] installed_location=task.outputs[0].bldpath(task.env) source_file = open(task.inputs[0].srcpath(task.env)) installed_file = open(installed_location, 'w') lineno = 0 for line in source_file: newline = line if (lineno == 0 and line[:2] == "#!"): newline = replacement_shebang elif pattern in line: newline = line.replace(pattern, replacement) installed_file.write(newline) lineno = lineno + 1 installed_file.close() os.chmod(installed_location, 0o755) return 0 def copy_and_fix_perl_path(task): pattern='use lib "$RealBin/lib";' replacement = "" if not task.env["PERL_LIB_INSTALL_DIR"] in task.env["PERL_INC"]: replacement = 'use lib "%s";' % task.env["PERL_LIB_INSTALL_DIR"] if task.env["PERL"][0] == "/": replacement_shebang = "#!%s\n" % task.env["PERL"] else: replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PERL"] installed_location=task.outputs[0].bldpath(task.env) source_file = open(task.inputs[0].srcpath(task.env)) installed_file = open(installed_location, 'w') lineno = 0 for line in source_file: newline = line if lineno == 0 and task.env["PERL_SPECIFIED"] == True and line[:2] == "#!": newline = replacement_shebang elif pattern in line: newline = line.replace(pattern, replacement) installed_file.write(newline) lineno = lineno + 1 installed_file.close() os.chmod(installed_location, 0o755) return 0 def install_file(bld, destdir, file, chmod=MODE_644, flat=False, python_fixup=False, perl_fixup=False, destname=None, base_name=None): '''install a file''' if not isinstance(file, str): file = file.abspath() destdir = bld.EXPAND_VARIABLES(destdir) if not destname: destname = file if flat: destname = os.path.basename(destname) dest = os.path.join(destdir, destname) if python_fixup: # fix the path python will use to find Samba modules inst_file = file + '.inst' bld.SAMBA_GENERATOR('python_%s' % destname, rule=copy_and_fix_python_path, dep_vars=["PYTHON","PYTHON_SPECIFIED","PYTHONDIR","PYTHONARCHDIR"], source=file, target=inst_file) file = inst_file if perl_fixup: # fix the path perl will use to find Samba modules inst_file = file + '.inst' bld.SAMBA_GENERATOR('perl_%s' % destname, rule=copy_and_fix_perl_path, dep_vars=["PERL","PERL_SPECIFIED","PERL_LIB_INSTALL_DIR"], source=file, target=inst_file) file = inst_file if base_name: file = os.path.join(base_name, file) bld.install_as(dest, file, chmod=chmod) def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False, python_fixup=False, perl_fixup=False, destname=None, base_name=None): '''install a set of files''' for f in TO_LIST(files): install_file(bld, destdir, f, chmod=chmod, flat=flat, python_fixup=python_fixup, perl_fixup=perl_fixup, destname=destname, base_name=base_name) Build.BuildContext.INSTALL_FILES = INSTALL_FILES def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False, python_fixup=False, exclude=None, trim_path=None): '''install a set of files matching a wildcard pattern''' files=TO_LIST(bld.path.ant_glob(pattern, flat=True)) if trim_path: files2 = [] for f in files: files2.append(os_path_relpath(f, trim_path)) files = files2 if exclude: for f in files[:]: if fnmatch.fnmatch(f, exclude): files.remove(f) INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat, python_fixup=python_fixup, base_name=trim_path) Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD def INSTALL_DIR(bld, path, chmod=0o755, env=None): """Install a directory if it doesn't exist, always set permissions.""" if not path: return [] destpath = bld.EXPAND_VARIABLES(path) if Options.options.destdir: destpath = os.path.join(Options.options.destdir, destpath.lstrip(os.sep)) if bld.is_install > 0: if not os.path.isdir(destpath): try: Logs.info('* create %s', destpath) os.makedirs(destpath) os.chmod(destpath, chmod) except OSError as e: if not os.path.isdir(destpath): raise Errors.WafError("Cannot create the folder '%s' (error: %s)" % (path, e)) Build.BuildContext.INSTALL_DIR = INSTALL_DIR def INSTALL_DIRS(bld, destdir, dirs, chmod=0o755, env=None): '''install a set of directories''' destdir = bld.EXPAND_VARIABLES(destdir) dirs = bld.EXPAND_VARIABLES(dirs) for d in TO_LIST(dirs): INSTALL_DIR(bld, os.path.join(destdir, d), chmod, env) Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS def MANPAGES(bld, manpages, install): '''build and install manual pages''' bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' for m in manpages.split(): source = m + '.xml' bld.SAMBA_GENERATOR(m, source=source, target=m, group='final', rule='${XSLTPROC} --xinclude -o ${TGT} --nonet ${MAN_XSL} ${SRC}' ) if install: bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) Build.BuildContext.MANPAGES = MANPAGES def SAMBAMANPAGES(bld, manpages, extra_source=None): '''build and install manual pages''' bld.env.SAMBA_EXPAND_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/expand-sambadoc.xsl' bld.env.SAMBA_MAN_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/man.xsl' bld.env.SAMBA_CATALOG = bld.bldnode.abspath() + '/docs-xml/build/catalog.xml' bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file:///usr/local/share/xml/catalog file://' + bld.env.SAMBA_CATALOG for m in manpages.split(): source = m + '.xml' if extra_source is not None: source = [source, extra_source] bld.SAMBA_GENERATOR(m, source=source, target=m, group='final', dep_vars=['SAMBA_MAN_XSL', 'SAMBA_EXPAND_XSL', 'SAMBA_CATALOG'], rule='''XML_CATALOG_FILES="${SAMBA_CATALOGS}" export XML_CATALOG_FILES ${XSLTPROC} --xinclude --stringparam noreference 0 -o ${TGT}.xml --nonet ${SAMBA_EXPAND_XSL} ${SRC[0].abspath(env)} ${XSLTPROC} --nonet -o ${TGT} ${SAMBA_MAN_XSL} ${TGT}.xml''' ) bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) Build.BuildContext.SAMBAMANPAGES = SAMBAMANPAGES @after('apply_link') @feature('cshlib') def apply_bundle_remove_dynamiclib_patch(self): if self.env['MACBUNDLE'] or getattr(self,'mac_bundle',False): if not getattr(self,'vnum',None): try: self.env['LINKFLAGS'].remove('-dynamiclib') self.env['LINKFLAGS'].remove('-single_module') except ValueError: pass ldb-2.0.8/buildtools/wafsamba/wscript0000660000000000000000000006331413573675413017622 0ustar rootroot00000000000000#!/usr/bin/env python # this is a base set of waf rules that everything else pulls in first import os, sys from waflib import Configure, Logs, Options, Utils, Context, Errors import wafsamba from samba_utils import os_path_relpath from optparse import SUPPRESS_HELP # this forces configure to be re-run if any of the configure # sections of the build scripts change. We have to check # for this in sys.argv as options have not yet been parsed when # we need to set this. This is off by default until some issues # are resolved related to WAFCACHE. It will need a lot of testing # before it is enabled by default. if '--enable-auto-reconfigure' in sys.argv: Configure.autoconfig = 'clobber' def default_value(option, default=''): if option in Options.options.__dict__: return Options.options.__dict__[option] return default def options(opt): opt.load('compiler_cc') opt.load('gnu_dirs') gr = opt.option_group('library handling options') gr.add_option('--bundled-libraries', help=("comma separated list of bundled libraries. May include !LIBNAME to disable bundling a library. Can be 'NONE' or 'ALL' [auto]"), action="store", dest='BUNDLED_LIBS', default='') gr.add_option('--private-libraries', help=("comma separated list of normally public libraries to build instead as private libraries. May include !LIBNAME to disable making a library private. Can be 'NONE' or 'ALL' [auto]"), action="store", dest='PRIVATE_LIBS', default='') extension_default = default_value('PRIVATE_EXTENSION_DEFAULT') gr.add_option('--private-library-extension', help=("name extension for private libraries [%s]" % extension_default), action="store", dest='PRIVATE_EXTENSION', default=extension_default) extension_exception = default_value('PRIVATE_EXTENSION_EXCEPTION') gr.add_option('--private-extension-exception', help=("comma separated list of libraries to not apply extension to [%s]" % extension_exception), action="store", dest='PRIVATE_EXTENSION_EXCEPTION', default=extension_exception) builtin_default = default_value('BUILTIN_LIBRARIES_DEFAULT') gr.add_option('--builtin-libraries', help=("command separated list of libraries to build directly into binaries [%s]" % builtin_default), action="store", dest='BUILTIN_LIBRARIES', default=builtin_default) gr.add_option('--minimum-library-version', help=("list of minimum system library versions (LIBNAME1:version,LIBNAME2:version)"), action="store", dest='MINIMUM_LIBRARY_VERSION', default='') gr.add_option('--disable-rpath', help=("Disable use of rpath for build binaries"), action="store_true", dest='disable_rpath_build', default=False) gr.add_option('--disable-rpath-install', help=("Disable use of rpath for library path in installed files"), action="store_true", dest='disable_rpath_install', default=False) gr.add_option('--disable-rpath-private-install', help=("Disable use of rpath for private library path in installed files"), action="store_true", dest='disable_rpath_private_install', default=False) gr.add_option('--nonshared-binary', help=("Disable use of shared libs for the listed binaries"), action="store", dest='NONSHARED_BINARIES', default='') gr.add_option('--disable-symbol-versions', help=("Disable use of the --version-script linker option"), action="store_true", dest='disable_symbol_versions', default=False) opt.add_option('--with-modulesdir', help=("modules directory [PREFIX/modules]"), action="store", dest='MODULESDIR', default='${PREFIX}/modules') opt.add_option('--with-privatelibdir', help=("private library directory [PREFIX/lib/%s]" % Context.g_module.APPNAME), action="store", dest='PRIVATELIBDIR', default=None) opt.add_option('--with-libiconv', help='additional directory to search for libiconv', action='store', dest='iconv_open', default='/usr/local', match = ['Checking for library iconv', 'Checking for iconv_open', 'Checking for header iconv.h']) opt.add_option('--without-gettext', help=("Disable use of gettext"), action="store_true", dest='disable_gettext', default=False) gr = opt.option_group('developer options') gr.add_option('-C', help='enable configure cacheing', action='store_true', dest='enable_configure_cache') gr.add_option('--enable-auto-reconfigure', help='enable automatic reconfigure on build', action='store_true', dest='enable_auto_reconfigure') gr.add_option('--enable-debug', help=("Turn on debugging symbols"), action="store_true", dest='debug', default=False) gr.add_option('--enable-developer', help=("Turn on developer warnings and debugging"), action="store_true", dest='developer', default=False) opt.add_option('--enable-coverage', help=("enable options necessary for code coverage " "reporting on selftest (default=no)"), action="store_true", dest='enable_coverage', default=False) def picky_developer_callback(option, opt_str, value, parser): parser.values.developer = True parser.values.picky_developer = True gr.add_option('--picky-developer', help=("Treat all warnings as errors (enable -Werror)"), action="callback", callback=picky_developer_callback, dest='picky_developer', default=False) gr.add_option('--fatal-errors', help=("Stop compilation on first error (enable -Wfatal-errors)"), action="store_true", dest='fatal_errors', default=False) gr.add_option('--enable-gccdeps', help=("Enable use of gcc -MD dependency module"), action="store_true", dest='enable_gccdeps', default=True) gr.add_option('--pedantic', help=("Enable even more compiler warnings"), action='store_true', dest='pedantic', default=False) gr.add_option('--git-local-changes', help=("mark version with + if local git changes"), action='store_true', dest='GIT_LOCAL_CHANGES', default=False) gr.add_option('--address-sanitizer', help=("Enable address sanitizer compile and linker flags"), action="store_true", dest='address_sanitizer', default=False) gr.add_option('--undefined-sanitizer', help=("Enable undefined behaviour sanitizer compile and linker flags"), action="store_true", dest='undefined_sanitizer', default=False) gr.add_option('--abi-check', help=("Check ABI signatures for libraries"), action='store_true', dest='ABI_CHECK', default=False) gr.add_option('--abi-check-disable', help=("Disable ABI checking (used with --enable-developer)"), action='store_true', dest='ABI_CHECK_DISABLE', default=False) gr.add_option('--abi-update', help=("Update ABI signature files for libraries"), action='store_true', dest='ABI_UPDATE', default=False) gr.add_option('--show-deps', help=("Show dependency tree for the given target"), dest='SHOWDEPS', default='') gr.add_option('--symbol-check', help=("check symbols in object files against project rules"), action='store_true', dest='SYMBOLCHECK', default=False) gr.add_option('--dup-symbol-check', help=("check for duplicate symbols in object files and system libs (must be configured with --enable-developer)"), action='store_true', dest='DUP_SYMBOLCHECK', default=False) gr.add_option('--why-needed', help=("TARGET:DEPENDENCY check why TARGET needs DEPENDENCY"), action='store', type='str', dest='WHYNEEDED', default=None) gr.add_option('--show-duplicates', help=("Show objects which are included in multiple binaries or libraries"), action='store_true', dest='SHOW_DUPLICATES', default=False) gr = opt.add_option_group('cross compilation options') gr.add_option('--cross-compile', help=("configure for cross-compilation"), action='store_true', dest='CROSS_COMPILE', default=False) gr.add_option('--cross-execute', help=("command prefix to use for cross-execution in configure"), action='store', dest='CROSS_EXECUTE', default='') gr.add_option('--cross-answers', help=("answers to cross-compilation configuration (auto modified)"), action='store', dest='CROSS_ANSWERS', default='') gr.add_option('--hostcc', help=("set host compiler when cross compiling"), action='store', dest='HOSTCC', default=False) # we use SUPPRESS_HELP for these, as they are ignored, and are there only # to allow existing RPM spec files to work opt.add_option('--build', help=SUPPRESS_HELP, action='store', dest='AUTOCONF_BUILD', default='') opt.add_option('--host', help=SUPPRESS_HELP, action='store', dest='AUTOCONF_HOST', default='') opt.add_option('--target', help=SUPPRESS_HELP, action='store', dest='AUTOCONF_TARGET', default='') opt.add_option('--program-prefix', help=SUPPRESS_HELP, action='store', dest='AUTOCONF_PROGRAM_PREFIX', default='') opt.add_option('--disable-dependency-tracking', help=SUPPRESS_HELP, action='store_true', dest='AUTOCONF_DISABLE_DEPENDENCY_TRACKING', default=False) opt.add_option('--disable-silent-rules', help=SUPPRESS_HELP, action='store_true', dest='AUTOCONF_DISABLE_SILENT_RULES', default=False) gr = opt.option_group('dist options') gr.add_option('--sign-release', help='sign the release tarball created by waf dist', action='store_true', dest='SIGN_RELEASE') gr.add_option('--tag', help='tag release in git at the same time', type='string', action='store', dest='TAG_RELEASE') opt.add_option('--disable-python', help='do not generate python modules', action='store_true', dest='disable_python', default=False) @Utils.run_once def configure(conf): conf.env.hlist = [] conf.env.srcdir = conf.srcnode.abspath() conf.define('SRCDIR', conf.env['srcdir']) conf.SETUP_CONFIGURE_CACHE(Options.options.enable_configure_cache) # load our local waf extensions conf.load('gnu_dirs') conf.load('wafsamba') conf.CHECK_CC_ENV() conf.load('compiler_c') conf.CHECK_STANDARD_LIBPATH() # we need git for 'waf dist' conf.find_program('git', var='GIT') # older gcc versions (< 4.4) does not work with gccdeps, so we have to see if the .d file is generated if Options.options.enable_gccdeps: # stale file removal - the configuration may pick up the old .pyc file p = os.path.join(conf.env.srcdir, 'buildtools/wafsamba/gccdeps.pyc') if os.path.exists(p): os.remove(p) conf.load('gccdeps') # make the install paths available in environment conf.env.LIBDIR = Options.options.LIBDIR or '${PREFIX}/lib' conf.env.BINDIR = Options.options.BINDIR or '${PREFIX}/bin' conf.env.SBINDIR = Options.options.SBINDIR or '${PREFIX}/sbin' conf.env.MODULESDIR = Options.options.MODULESDIR conf.env.PRIVATELIBDIR = Options.options.PRIVATELIBDIR conf.env.BUNDLED_LIBS = Options.options.BUNDLED_LIBS.split(',') conf.env.SYSTEM_LIBS = () conf.env.PRIVATE_LIBS = Options.options.PRIVATE_LIBS.split(',') conf.env.BUILTIN_LIBRARIES = Options.options.BUILTIN_LIBRARIES.split(',') conf.env.NONSHARED_BINARIES = Options.options.NONSHARED_BINARIES.split(',') conf.env.PRIVATE_EXTENSION = Options.options.PRIVATE_EXTENSION conf.env.PRIVATE_EXTENSION_EXCEPTION = Options.options.PRIVATE_EXTENSION_EXCEPTION.split(',') conf.env.CROSS_COMPILE = Options.options.CROSS_COMPILE conf.env.CROSS_EXECUTE = Options.options.CROSS_EXECUTE conf.env.CROSS_ANSWERS = Options.options.CROSS_ANSWERS conf.env.HOSTCC = Options.options.HOSTCC conf.env.AUTOCONF_BUILD = Options.options.AUTOCONF_BUILD conf.env.AUTOCONF_HOST = Options.options.AUTOCONF_HOST conf.env.AUTOCONF_PROGRAM_PREFIX = Options.options.AUTOCONF_PROGRAM_PREFIX conf.env.disable_python = Options.options.disable_python if (conf.env.AUTOCONF_HOST and conf.env.AUTOCONF_BUILD and conf.env.AUTOCONF_BUILD != conf.env.AUTOCONF_HOST): Logs.error('ERROR: Mismatch between --build and --host. Please use --cross-compile instead') sys.exit(1) if conf.env.AUTOCONF_PROGRAM_PREFIX: Logs.error('ERROR: --program-prefix not supported') sys.exit(1) # enable ABI checking for developers conf.env.ABI_CHECK = Options.options.ABI_CHECK or Options.options.developer if Options.options.ABI_CHECK_DISABLE: conf.env.ABI_CHECK = False try: conf.find_program('gdb', mandatory=True) except: conf.env.ABI_CHECK = False conf.env.enable_coverage = Options.options.enable_coverage if conf.env.enable_coverage: conf.ADD_LDFLAGS('-lgcov', testflags=True) conf.ADD_CFLAGS('--coverage', testflags=True) # disable abi check for coverage, otherwise ld will fail conf.env.ABI_CHECK = False conf.env.GIT_LOCAL_CHANGES = Options.options.GIT_LOCAL_CHANGES conf.CHECK_UNAME() # see if we can compile and run a simple C program conf.CHECK_CODE('printf("hello world")', define='HAVE_SIMPLE_C_PROG', mandatory=True, execute=True, headers='stdio.h', msg='Checking simple C program') # Try to find the right extra flags for -Werror behaviour for f in ["-Werror", # GCC "-errwarn=%all", # Sun Studio "-qhalt=w", # IBM xlc "-w2", # Tru64 ]: if conf.CHECK_CFLAGS([f]): if not 'WERROR_CFLAGS' in conf.env: conf.env['WERROR_CFLAGS'] = [] conf.env['WERROR_CFLAGS'].extend([f]) break # check which compiler/linker flags are needed for rpath support if conf.CHECK_LDFLAGS(['-Wl,-rpath,.']): conf.env['RPATH_ST'] = '-Wl,-rpath,%s' elif conf.CHECK_LDFLAGS(['-Wl,-R,.']): conf.env['RPATH_ST'] = '-Wl,-R,%s' # check for rpath if conf.CHECK_LIBRARY_SUPPORT(rpath=True): support_rpath = True conf.env.RPATH_ON_BUILD = not Options.options.disable_rpath_build conf.env.RPATH_ON_INSTALL = (conf.env.RPATH_ON_BUILD and not Options.options.disable_rpath_install) if not conf.env.PRIVATELIBDIR: conf.env.PRIVATELIBDIR = '%s/%s' % (conf.env.LIBDIR, Context.g_module.APPNAME) conf.env.RPATH_ON_INSTALL_PRIVATE = ( not Options.options.disable_rpath_private_install) else: support_rpath = False conf.env.RPATH_ON_INSTALL = False conf.env.RPATH_ON_BUILD = False conf.env.RPATH_ON_INSTALL_PRIVATE = False if not conf.env.PRIVATELIBDIR: # rpath is not possible so there is no sense in having a # private library directory by default. # the user can of course always override it. conf.env.PRIVATELIBDIR = conf.env.LIBDIR if (not Options.options.disable_symbol_versions and conf.CHECK_LIBRARY_SUPPORT(rpath=support_rpath, version_script=True, msg='-Wl,--version-script support')): conf.env.HAVE_LD_VERSION_SCRIPT = True else: conf.env.HAVE_LD_VERSION_SCRIPT = False if conf.CHECK_CFLAGS(['-fvisibility=hidden']): conf.env.VISIBILITY_CFLAGS = '-fvisibility=hidden' conf.CHECK_CODE('''int main(void) { return 0; } __attribute__((visibility("default"))) void vis_foo2(void) {}\n''', cflags=conf.env.VISIBILITY_CFLAGS, strict=True, define='HAVE_VISIBILITY_ATTR', addmain=False) # check HAVE_CONSTRUCTOR_ATTRIBUTE conf.CHECK_CODE(''' void test_constructor_attribute(void) __attribute__ ((constructor)); void test_constructor_attribute(void) { return; } int main(void) { return 0; } ''', 'HAVE_CONSTRUCTOR_ATTRIBUTE', addmain=False, strict=True, msg='Checking for library constructor support') # check HAVE_DESTRUCTOR_ATTRIBUTE conf.CHECK_CODE(''' void test_destructor_attribute(void) __attribute__ ((destructor)); void test_destructor_attribute(void) { return; } int main(void) { return 0; } ''', 'HAVE_DESTRUCTOR_ATTRIBUTE', addmain=False, strict=True, msg='Checking for library destructor support') conf.CHECK_CODE(''' void test_attribute(void) __attribute__ (()); void test_attribute(void) { return; } int main(void) { return 0; } ''', 'HAVE___ATTRIBUTE__', addmain=False, strict=True, msg='Checking for __attribute__') if sys.platform.startswith('aix'): conf.DEFINE('_ALL_SOURCE', 1, add_to_cflags=True) # Might not be needed if ALL_SOURCE is defined # conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) # we should use the PIC options in waf instead # Some compilo didn't support -fPIC but just print a warning if conf.env['COMPILER_CC'] == "suncc": conf.ADD_CFLAGS('-KPIC', testflags=True) # we really want define here as we need to have this # define even during the tests otherwise detection of # boolean is broken conf.DEFINE('_STDC_C99', 1, add_to_cflags=True) conf.DEFINE('_XPG6', 1, add_to_cflags=True) else: conf.ADD_CFLAGS('-fPIC', testflags=True) # On Solaris 8 with suncc (at least) the flags for the linker to define the name of the # library are not always working (if the command line is very very long and with a lot # files) if conf.env['COMPILER_CC'] == "suncc": save = conf.env['SONAME_ST'] conf.env['SONAME_ST'] = '-Wl,-h,%s' if not conf.CHECK_SHLIB_INTRASINC_NAME_FLAGS("Checking if flags %s are ok" % conf.env['SONAME_ST']): conf.env['SONAME_ST'] = save conf.CHECK_INLINE() # check for pkgconfig conf.CHECK_CFG(atleast_pkgconfig_version='0.0.0') conf.DEFINE('_GNU_SOURCE', 1, add_to_cflags=True) conf.DEFINE('_XOPEN_SOURCE_EXTENDED', 1, add_to_cflags=True) # # Needs to be defined before std*.h and string*.h are included # As Python.h already brings string.h we need it in CFLAGS. # See memset_s() details here: # https://en.cppreference.com/w/c/string/byte/memset # if conf.CHECK_CFLAGS(['-D__STDC_WANT_LIB_EXT1__=1']): conf.ADD_CFLAGS('-D__STDC_WANT_LIB_EXT1__=1') # on Tru64 certain features are only available with _OSF_SOURCE set to 1 # and _XOPEN_SOURCE set to 600 if conf.env['SYSTEM_UNAME_SYSNAME'] == 'OSF1': conf.DEFINE('_OSF_SOURCE', 1, add_to_cflags=True) conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) # SCM_RIGHTS is only avail if _XOPEN_SOURCE iѕ defined on IRIX if conf.env['SYSTEM_UNAME_SYSNAME'] == 'IRIX': conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) conf.DEFINE('_BSD_TYPES', 1, add_to_cflags=True) # Try to find the right extra flags for C99 initialisers for f in ["", "-AC99", "-qlanglvl=extc99", "-qlanglvl=stdc99", "-c99"]: if conf.CHECK_CFLAGS([f], ''' struct foo {int x;char y;}; struct foo bar = { .y = 'X', .x = 1 }; '''): if f != "": conf.ADD_CFLAGS(f) break # get the base headers we'll use for the rest of the tests conf.CHECK_HEADERS('stdio.h sys/types.h sys/stat.h stdlib.h stddef.h memory.h string.h', add_headers=True) conf.CHECK_HEADERS('strings.h inttypes.h stdint.h unistd.h minix/config.h', add_headers=True) conf.CHECK_HEADERS('ctype.h', add_headers=True) if sys.platform != 'darwin': conf.CHECK_HEADERS('standards.h', add_headers=True) conf.CHECK_HEADERS('stdbool.h stdint.h stdarg.h vararg.h', add_headers=True) conf.CHECK_HEADERS('limits.h assert.h') # see if we need special largefile flags if not conf.CHECK_LARGEFILE(): raise Errors.WafError('Samba requires large file support support, but not available on this platform: sizeof(off_t) < 8') if conf.env.HAVE_STDDEF_H and conf.env.HAVE_STDLIB_H: conf.DEFINE('STDC_HEADERS', 1) conf.CHECK_HEADERS('sys/time.h time.h', together=True) if conf.env.HAVE_SYS_TIME_H and conf.env.HAVE_TIME_H: conf.DEFINE('TIME_WITH_SYS_TIME', 1) # cope with different extensions for libraries (root, ext) = os.path.splitext(conf.env.cshlib_PATTERN) if ext[0] == '.': conf.define('SHLIBEXT', ext[1:], quote=True) else: conf.define('SHLIBEXT', "so", quote=True) # First try a header check for cross-compile friendlyness conf.CHECK_CODE(code = """#ifdef __BYTE_ORDER #define B __BYTE_ORDER #elif defined(BYTE_ORDER) #define B BYTE_ORDER #endif #ifdef __LITTLE_ENDIAN #define LITTLE __LITTLE_ENDIAN #elif defined(LITTLE_ENDIAN) #define LITTLE LITTLE_ENDIAN #endif #if !defined(LITTLE) || !defined(B) || LITTLE != B #error Not little endian. #endif int main(void) { return 0; }\n""", addmain=False, headers="endian.h sys/endian.h", define="HAVE_LITTLE_ENDIAN") conf.CHECK_CODE(code = """#ifdef __BYTE_ORDER #define B __BYTE_ORDER #elif defined(BYTE_ORDER) #define B BYTE_ORDER #endif #ifdef __BIG_ENDIAN #define BIG __BIG_ENDIAN #elif defined(BIG_ENDIAN) #define BIG BIG_ENDIAN #endif #if !defined(BIG) || !defined(B) || BIG != B #error Not big endian. #endif int main(void) { return 0; }\n""", addmain=False, headers="endian.h sys/endian.h", define="HAVE_BIG_ENDIAN") if not conf.CONFIG_SET("HAVE_BIG_ENDIAN") and not conf.CONFIG_SET("HAVE_LITTLE_ENDIAN"): # That didn't work! Do runtime test. conf.CHECK_CODE("""union { int i; char c[sizeof(int)]; } u; u.i = 0x01020304; return u.c[0] == 0x04 && u.c[1] == 0x03 && u.c[2] == 0x02 && u.c[3] == 0x01 ? 0 : 1;""", addmain=True, execute=True, define='HAVE_LITTLE_ENDIAN', msg="Checking for HAVE_LITTLE_ENDIAN - runtime") conf.CHECK_CODE("""union { int i; char c[sizeof(int)]; } u; u.i = 0x01020304; return u.c[0] == 0x01 && u.c[1] == 0x02 && u.c[2] == 0x03 && u.c[3] == 0x04 ? 0 : 1;""", addmain=True, execute=True, define='HAVE_BIG_ENDIAN', msg="Checking for HAVE_BIG_ENDIAN - runtime") # Extra sanity check. if conf.CONFIG_SET("HAVE_BIG_ENDIAN") == conf.CONFIG_SET("HAVE_LITTLE_ENDIAN"): Logs.error("Failed endian determination. The PDP-11 is back?") sys.exit(1) else: if conf.CONFIG_SET("HAVE_BIG_ENDIAN"): conf.DEFINE('WORDS_BIGENDIAN', 1) # check if signal() takes a void function if conf.CHECK_CODE('return *(signal (0, 0)) (0) == 1', define='RETSIGTYPE_INT', execute=False, headers='signal.h', msg='Checking if signal handlers return int'): conf.DEFINE('RETSIGTYPE', 'int') else: conf.DEFINE('RETSIGTYPE', 'void') conf.CHECK_VARIABLE('__FUNCTION__', define='HAVE_FUNCTION_MACRO') conf.CHECK_CODE('va_list ap1,ap2; va_copy(ap1,ap2)', define="HAVE_VA_COPY", msg="Checking for va_copy") conf.CHECK_CODE(''' #define eprintf(...) fprintf(stderr, __VA_ARGS__) eprintf("bla", "bar") ''', define='HAVE__VA_ARGS__MACRO') conf.SAMBA_BUILD_ENV() def build(bld): # give a more useful message if the source directory has moved curdir = bld.path.abspath() srcdir = bld.srcnode.abspath() relpath = os_path_relpath(curdir, srcdir) if relpath.find('../') != -1: Logs.error('bld.path %s is not a child of %s' % (curdir, srcdir)) raise Errors.WafError('''The top source directory has moved. Please run distclean and reconfigure''') bld.SETUP_BUILD_GROUPS() bld.ENFORCE_GROUP_ORDERING() bld.CHECK_PROJECT_RULES() ldb-2.0.8/third_party/waf/waflib/Build.py0000660000000000000000000012470413573675414020230 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Classes related to the build phase (build, clean, install, step, etc) The inheritance tree is the following: """ import os, sys, errno, re, shutil, stat try: import cPickle except ImportError: import pickle as cPickle from waflib import Node, Runner, TaskGen, Utils, ConfigSet, Task, Logs, Options, Context, Errors CACHE_DIR = 'c4che' """Name of the cache directory""" CACHE_SUFFIX = '_cache.py' """ConfigSet cache files for variants are written under :py:attr:´waflib.Build.CACHE_DIR´ in the form ´variant_name´_cache.py""" INSTALL = 1337 """Positive value '->' install, see :py:attr:`waflib.Build.BuildContext.is_install`""" UNINSTALL = -1337 """Negative value '<-' uninstall, see :py:attr:`waflib.Build.BuildContext.is_install`""" SAVED_ATTRS = 'root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() """Build class members to save between the runs; these should be all dicts except for `root` which represents a :py:class:`waflib.Node.Node` instance """ CFG_FILES = 'cfg_files' """Files from the build directory to hash before starting the build (``config.h`` written during the configuration)""" POST_AT_ONCE = 0 """Post mode: all task generators are posted before any task executed""" POST_LAZY = 1 """Post mode: post the task generators group after group, the tasks in the next group are created when the tasks in the previous groups are done""" PROTOCOL = -1 if sys.platform == 'cli': PROTOCOL = 0 class BuildContext(Context.Context): '''executes the build''' cmd = 'build' variant = '' def __init__(self, **kw): super(BuildContext, self).__init__(**kw) self.is_install = 0 """Non-zero value when installing or uninstalling file""" self.top_dir = kw.get('top_dir', Context.top_dir) """See :py:attr:`waflib.Context.top_dir`; prefer :py:attr:`waflib.Build.BuildContext.srcnode`""" self.out_dir = kw.get('out_dir', Context.out_dir) """See :py:attr:`waflib.Context.out_dir`; prefer :py:attr:`waflib.Build.BuildContext.bldnode`""" self.run_dir = kw.get('run_dir', Context.run_dir) """See :py:attr:`waflib.Context.run_dir`""" self.launch_dir = Context.launch_dir """See :py:attr:`waflib.Context.out_dir`; prefer :py:meth:`waflib.Build.BuildContext.launch_node`""" self.post_mode = POST_LAZY """Whether to post the task generators at once or group-by-group (default is group-by-group)""" self.cache_dir = kw.get('cache_dir') if not self.cache_dir: self.cache_dir = os.path.join(self.out_dir, CACHE_DIR) self.all_envs = {} """Map names to :py:class:`waflib.ConfigSet.ConfigSet`, the empty string must map to the default environment""" # ======================================= # # cache variables self.node_sigs = {} """Dict mapping build nodes to task identifier (uid), it indicates whether a task created a particular file (persists across builds)""" self.task_sigs = {} """Dict mapping task identifiers (uid) to task signatures (persists across builds)""" self.imp_sigs = {} """Dict mapping task identifiers (uid) to implicit task dependencies used for scanning targets (persists across builds)""" self.node_deps = {} """Dict mapping task identifiers (uid) to node dependencies found by :py:meth:`waflib.Task.Task.scan` (persists across builds)""" self.raw_deps = {} """Dict mapping task identifiers (uid) to custom data returned by :py:meth:`waflib.Task.Task.scan` (persists across builds)""" self.task_gen_cache_names = {} self.jobs = Options.options.jobs """Amount of jobs to run in parallel""" self.targets = Options.options.targets """List of targets to build (default: \\*)""" self.keep = Options.options.keep """Whether the build should continue past errors""" self.progress_bar = Options.options.progress_bar """ Level of progress status: 0. normal output 1. progress bar 2. IDE output 3. No output at all """ # Manual dependencies. self.deps_man = Utils.defaultdict(list) """Manual dependencies set by :py:meth:`waflib.Build.BuildContext.add_manual_dependency`""" # just the structure here self.current_group = 0 """ Current build group """ self.groups = [] """ List containing lists of task generators """ self.group_names = {} """ Map group names to the group lists. See :py:meth:`waflib.Build.BuildContext.add_group` """ for v in SAVED_ATTRS: if not hasattr(self, v): setattr(self, v, {}) def get_variant_dir(self): """Getter for the variant_dir attribute""" if not self.variant: return self.out_dir return os.path.join(self.out_dir, os.path.normpath(self.variant)) variant_dir = property(get_variant_dir, None) def __call__(self, *k, **kw): """ Create a task generator and add it to the current build group. The following forms are equivalent:: def build(bld): tg = bld(a=1, b=2) def build(bld): tg = bld() tg.a = 1 tg.b = 2 def build(bld): tg = TaskGen.task_gen(a=1, b=2) bld.add_to_group(tg, None) :param group: group name to add the task generator to :type group: string """ kw['bld'] = self ret = TaskGen.task_gen(*k, **kw) self.task_gen_cache_names = {} # reset the cache, each time self.add_to_group(ret, group=kw.get('group')) return ret def __copy__(self): """ Build contexts cannot be copied :raises: :py:class:`waflib.Errors.WafError` """ raise Errors.WafError('build contexts cannot be copied') def load_envs(self): """ The configuration command creates files of the form ``build/c4che/NAMEcache.py``. This method creates a :py:class:`waflib.ConfigSet.ConfigSet` instance for each ``NAME`` by reading those files and stores them in :py:attr:`waflib.Build.BuildContext.allenvs`. """ node = self.root.find_node(self.cache_dir) if not node: raise Errors.WafError('The project was not configured: run "waf configure" first!') lst = node.ant_glob('**/*%s' % CACHE_SUFFIX, quiet=True) if not lst: raise Errors.WafError('The cache directory is empty: reconfigure the project') for x in lst: name = x.path_from(node).replace(CACHE_SUFFIX, '').replace('\\', '/') env = ConfigSet.ConfigSet(x.abspath()) self.all_envs[name] = env for f in env[CFG_FILES]: newnode = self.root.find_resource(f) if not newnode or not newnode.exists(): raise Errors.WafError('Missing configuration file %r, reconfigure the project!' % f) def init_dirs(self): """ Initialize the project directory and the build directory by creating the nodes :py:attr:`waflib.Build.BuildContext.srcnode` and :py:attr:`waflib.Build.BuildContext.bldnode` corresponding to ``top_dir`` and ``variant_dir`` respectively. The ``bldnode`` directory is created if necessary. """ if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)): raise Errors.WafError('The project was not configured: run "waf configure" first!') self.path = self.srcnode = self.root.find_dir(self.top_dir) self.bldnode = self.root.make_node(self.variant_dir) self.bldnode.mkdir() def execute(self): """ Restore data from previous builds and call :py:meth:`waflib.Build.BuildContext.execute_build`. Overrides from :py:func:`waflib.Context.Context.execute` """ self.restore() if not self.all_envs: self.load_envs() self.execute_build() def execute_build(self): """ Execute the build by: * reading the scripts (see :py:meth:`waflib.Context.Context.recurse`) * calling :py:meth:`waflib.Build.BuildContext.pre_build` to call user build functions * calling :py:meth:`waflib.Build.BuildContext.compile` to process the tasks * calling :py:meth:`waflib.Build.BuildContext.post_build` to call user build functions """ Logs.info("Waf: Entering directory `%s'", self.variant_dir) self.recurse([self.run_dir]) self.pre_build() # display the time elapsed in the progress bar self.timer = Utils.Timer() try: self.compile() finally: if self.progress_bar == 1 and sys.stderr.isatty(): c = self.producer.processed or 1 m = self.progress_line(c, c, Logs.colors.BLUE, Logs.colors.NORMAL) Logs.info(m, extra={'stream': sys.stderr, 'c1': Logs.colors.cursor_off, 'c2' : Logs.colors.cursor_on}) Logs.info("Waf: Leaving directory `%s'", self.variant_dir) try: self.producer.bld = None del self.producer except AttributeError: pass self.post_build() def restore(self): """ Load data from a previous run, sets the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS` """ try: env = ConfigSet.ConfigSet(os.path.join(self.cache_dir, 'build.config.py')) except EnvironmentError: pass else: if env.version < Context.HEXVERSION: raise Errors.WafError('Project was configured with a different version of Waf, please reconfigure it') for t in env.tools: self.setup(**t) dbfn = os.path.join(self.variant_dir, Context.DBFILE) try: data = Utils.readf(dbfn, 'rb') except (EnvironmentError, EOFError): # handle missing file/empty file Logs.debug('build: Could not load the build cache %s (missing)', dbfn) else: try: Node.pickle_lock.acquire() Node.Nod3 = self.node_class try: data = cPickle.loads(data) except Exception as e: Logs.debug('build: Could not pickle the build cache %s: %r', dbfn, e) else: for x in SAVED_ATTRS: setattr(self, x, data.get(x, {})) finally: Node.pickle_lock.release() self.init_dirs() def store(self): """ Store data for next runs, set the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS`. Uses a temporary file to avoid problems on ctrl+c. """ data = {} for x in SAVED_ATTRS: data[x] = getattr(self, x) db = os.path.join(self.variant_dir, Context.DBFILE) try: Node.pickle_lock.acquire() Node.Nod3 = self.node_class x = cPickle.dumps(data, PROTOCOL) finally: Node.pickle_lock.release() Utils.writef(db + '.tmp', x, m='wb') try: st = os.stat(db) os.remove(db) if not Utils.is_win32: # win32 has no chown but we're paranoid os.chown(db + '.tmp', st.st_uid, st.st_gid) except (AttributeError, OSError): pass # do not use shutil.move (copy is not thread-safe) os.rename(db + '.tmp', db) def compile(self): """ Run the build by creating an instance of :py:class:`waflib.Runner.Parallel` The cache file is written when at least a task was executed. :raises: :py:class:`waflib.Errors.BuildError` in case the build fails """ Logs.debug('build: compile()') # delegate the producer-consumer logic to another object to reduce the complexity self.producer = Runner.Parallel(self, self.jobs) self.producer.biter = self.get_build_iterator() try: self.producer.start() except KeyboardInterrupt: if self.is_dirty(): self.store() raise else: if self.is_dirty(): self.store() if self.producer.error: raise Errors.BuildError(self.producer.error) def is_dirty(self): return self.producer.dirty def setup(self, tool, tooldir=None, funs=None): """ Import waf tools defined during the configuration:: def configure(conf): conf.load('glib2') def build(bld): pass # glib2 is imported implicitly :param tool: tool list :type tool: list :param tooldir: optional tool directory (sys.path) :type tooldir: list of string :param funs: unused variable """ if isinstance(tool, list): for i in tool: self.setup(i, tooldir) return module = Context.load_tool(tool, tooldir) if hasattr(module, "setup"): module.setup(self) def get_env(self): """Getter for the env property""" try: return self.all_envs[self.variant] except KeyError: return self.all_envs[''] def set_env(self, val): """Setter for the env property""" self.all_envs[self.variant] = val env = property(get_env, set_env) def add_manual_dependency(self, path, value): """ Adds a dependency from a node object to a value:: def build(bld): bld.add_manual_dependency( bld.path.find_resource('wscript'), bld.root.find_resource('/etc/fstab')) :param path: file path :type path: string or :py:class:`waflib.Node.Node` :param value: value to depend :type value: :py:class:`waflib.Node.Node`, byte object, or function returning a byte object """ if not path: raise ValueError('Invalid input path %r' % path) if isinstance(path, Node.Node): node = path elif os.path.isabs(path): node = self.root.find_resource(path) else: node = self.path.find_resource(path) if not node: raise ValueError('Could not find the path %r' % path) if isinstance(value, list): self.deps_man[node].extend(value) else: self.deps_man[node].append(value) def launch_node(self): """Returns the launch directory as a :py:class:`waflib.Node.Node` object (cached)""" try: # private cache return self.p_ln except AttributeError: self.p_ln = self.root.find_dir(self.launch_dir) return self.p_ln def hash_env_vars(self, env, vars_lst): """ Hashes configuration set variables:: def build(bld): bld.hash_env_vars(bld.env, ['CXX', 'CC']) This method uses an internal cache. :param env: Configuration Set :type env: :py:class:`waflib.ConfigSet.ConfigSet` :param vars_lst: list of variables :type vars_list: list of string """ if not env.table: env = env.parent if not env: return Utils.SIG_NIL idx = str(id(env)) + str(vars_lst) try: cache = self.cache_env except AttributeError: cache = self.cache_env = {} else: try: return self.cache_env[idx] except KeyError: pass lst = [env[a] for a in vars_lst] cache[idx] = ret = Utils.h_list(lst) Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst) return ret def get_tgen_by_name(self, name): """ Fetches a task generator by its name or its target attribute; the name must be unique in a build:: def build(bld): tg = bld(name='foo') tg == bld.get_tgen_by_name('foo') This method use a private internal cache. :param name: Task generator name :raises: :py:class:`waflib.Errors.WafError` in case there is no task genenerator by that name """ cache = self.task_gen_cache_names if not cache: # create the index lazily for g in self.groups: for tg in g: try: cache[tg.name] = tg except AttributeError: # raised if not a task generator, which should be uncommon pass try: return cache[name] except KeyError: raise Errors.WafError('Could not find a task generator for the name %r' % name) def progress_line(self, idx, total, col1, col2): """ Computes a progress bar line displayed when running ``waf -p`` :returns: progress bar line :rtype: string """ if not sys.stderr.isatty(): return '' n = len(str(total)) Utils.rot_idx += 1 ind = Utils.rot_chr[Utils.rot_idx % 4] pc = (100. * idx)/total fs = "[%%%dd/%%d][%%s%%2d%%%%%%s][%s][" % (n, ind) left = fs % (idx, total, col1, pc, col2) right = '][%s%s%s]' % (col1, self.timer, col2) cols = Logs.get_term_cols() - len(left) - len(right) + 2*len(col1) + 2*len(col2) if cols < 7: cols = 7 ratio = ((cols * idx)//total) - 1 bar = ('='*ratio+'>').ljust(cols) msg = Logs.indicator % (left, bar, right) return msg def declare_chain(self, *k, **kw): """ Wraps :py:func:`waflib.TaskGen.declare_chain` for convenience """ return TaskGen.declare_chain(*k, **kw) def pre_build(self): """Executes user-defined methods before the build starts, see :py:meth:`waflib.Build.BuildContext.add_pre_fun`""" for m in getattr(self, 'pre_funs', []): m(self) def post_build(self): """Executes user-defined methods after the build is successful, see :py:meth:`waflib.Build.BuildContext.add_post_fun`""" for m in getattr(self, 'post_funs', []): m(self) def add_pre_fun(self, meth): """ Binds a callback method to execute after the scripts are read and before the build starts:: def mycallback(bld): print("Hello, world!") def build(bld): bld.add_pre_fun(mycallback) """ try: self.pre_funs.append(meth) except AttributeError: self.pre_funs = [meth] def add_post_fun(self, meth): """ Binds a callback method to execute immediately after the build is successful:: def call_ldconfig(bld): bld.exec_command('/sbin/ldconfig') def build(bld): if bld.cmd == 'install': bld.add_pre_fun(call_ldconfig) """ try: self.post_funs.append(meth) except AttributeError: self.post_funs = [meth] def get_group(self, x): """ Returns the build group named `x`, or the current group if `x` is None :param x: name or number or None :type x: string, int or None """ if not self.groups: self.add_group() if x is None: return self.groups[self.current_group] if x in self.group_names: return self.group_names[x] return self.groups[x] def add_to_group(self, tgen, group=None): """Adds a task or a task generator to the build; there is no attempt to remove it if it was already added.""" assert(isinstance(tgen, TaskGen.task_gen) or isinstance(tgen, Task.Task)) tgen.bld = self self.get_group(group).append(tgen) def get_group_name(self, g): """ Returns the name of the input build group :param g: build group object or build group index :type g: integer or list :return: name :rtype: string """ if not isinstance(g, list): g = self.groups[g] for x in self.group_names: if id(self.group_names[x]) == id(g): return x return '' def get_group_idx(self, tg): """ Returns the index of the group containing the task generator given as argument:: def build(bld): tg = bld(name='nada') 0 == bld.get_group_idx(tg) :param tg: Task generator object :type tg: :py:class:`waflib.TaskGen.task_gen` :rtype: int """ se = id(tg) for i, tmp in enumerate(self.groups): for t in tmp: if id(t) == se: return i return None def add_group(self, name=None, move=True): """ Adds a new group of tasks/task generators. By default the new group becomes the default group for new task generators (make sure to create build groups in order). :param name: name for this group :type name: string :param move: set this new group as default group (True by default) :type move: bool :raises: :py:class:`waflib.Errors.WafError` if a group by the name given already exists """ if name and name in self.group_names: raise Errors.WafError('add_group: name %s already present', name) g = [] self.group_names[name] = g self.groups.append(g) if move: self.current_group = len(self.groups) - 1 def set_group(self, idx): """ Sets the build group at position idx as current so that newly added task generators are added to this one by default:: def build(bld): bld(rule='touch ${TGT}', target='foo.txt') bld.add_group() # now the current group is 1 bld(rule='touch ${TGT}', target='bar.txt') bld.set_group(0) # now the current group is 0 bld(rule='touch ${TGT}', target='truc.txt') # build truc.txt before bar.txt :param idx: group name or group index :type idx: string or int """ if isinstance(idx, str): g = self.group_names[idx] for i, tmp in enumerate(self.groups): if id(g) == id(tmp): self.current_group = i break else: self.current_group = idx def total(self): """ Approximate task count: this value may be inaccurate if task generators are posted lazily (see :py:attr:`waflib.Build.BuildContext.post_mode`). The value :py:attr:`waflib.Runner.Parallel.total` is updated during the task execution. :rtype: int """ total = 0 for group in self.groups: for tg in group: try: total += len(tg.tasks) except AttributeError: total += 1 return total def get_targets(self): """ This method returns a pair containing the index of the last build group to post, and the list of task generator objects corresponding to the target names. This is used internally by :py:meth:`waflib.Build.BuildContext.get_build_iterator` to perform partial builds:: $ waf --targets=myprogram,myshlib :return: the minimum build group index, and list of task generators :rtype: tuple """ to_post = [] min_grp = 0 for name in self.targets.split(','): tg = self.get_tgen_by_name(name) m = self.get_group_idx(tg) if m > min_grp: min_grp = m to_post = [tg] elif m == min_grp: to_post.append(tg) return (min_grp, to_post) def get_all_task_gen(self): """ Returns a list of all task generators for troubleshooting purposes. """ lst = [] for g in self.groups: lst.extend(g) return lst def post_group(self): """ Post task generators from the group indexed by self.current_group; used internally by :py:meth:`waflib.Build.BuildContext.get_build_iterator` """ def tgpost(tg): try: f = tg.post except AttributeError: pass else: f() if self.targets == '*': for tg in self.groups[self.current_group]: tgpost(tg) elif self.targets: if self.current_group < self._min_grp: for tg in self.groups[self.current_group]: tgpost(tg) else: for tg in self._exact_tg: tg.post() else: ln = self.launch_node() if ln.is_child_of(self.bldnode): Logs.warn('Building from the build directory, forcing --targets=*') ln = self.srcnode elif not ln.is_child_of(self.srcnode): Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)', ln.abspath(), self.srcnode.abspath()) ln = self.srcnode def is_post(tg, ln): try: p = tg.path except AttributeError: pass else: if p.is_child_of(ln): return True def is_post_group(): for i, g in enumerate(self.groups): if i > self.current_group: for tg in g: if is_post(tg, ln): return True if self.post_mode == POST_LAZY and ln != self.srcnode: # partial folder builds require all targets from a previous build group if is_post_group(): ln = self.srcnode for tg in self.groups[self.current_group]: if is_post(tg, ln): tgpost(tg) def get_tasks_group(self, idx): """ Returns all task instances for the build group at position idx, used internally by :py:meth:`waflib.Build.BuildContext.get_build_iterator` :rtype: list of :py:class:`waflib.Task.Task` """ tasks = [] for tg in self.groups[idx]: try: tasks.extend(tg.tasks) except AttributeError: # not a task generator tasks.append(tg) return tasks def get_build_iterator(self): """ Creates a Python generator object that returns lists of tasks that may be processed in parallel. :return: tasks which can be executed immediately :rtype: generator returning lists of :py:class:`waflib.Task.Task` """ if self.targets and self.targets != '*': (self._min_grp, self._exact_tg) = self.get_targets() if self.post_mode != POST_LAZY: for self.current_group, _ in enumerate(self.groups): self.post_group() for self.current_group, _ in enumerate(self.groups): # first post the task generators for the group if self.post_mode != POST_AT_ONCE: self.post_group() # then extract the tasks tasks = self.get_tasks_group(self.current_group) # if the constraints are set properly (ext_in/ext_out, before/after) # the call to set_file_constraints may be removed (can be a 15% penalty on no-op rebuilds) # (but leave set_file_constraints for the installation step) # # if the tasks have only files, set_file_constraints is required but set_precedence_constraints is not necessary # Task.set_file_constraints(tasks) Task.set_precedence_constraints(tasks) self.cur_tasks = tasks if tasks: yield tasks while 1: # the build stops once there are no tasks to process yield [] def install_files(self, dest, files, **kw): """ Creates a task generator to install files on the system:: def build(bld): bld.install_files('${DATADIR}', self.path.find_resource('wscript')) :param dest: path representing the destination directory :type dest: :py:class:`waflib.Node.Node` or string (absolute path) :param files: input files :type files: list of strings or list of :py:class:`waflib.Node.Node` :param env: configuration set to expand *dest* :type env: :py:class:`waflib.ConfigSet.ConfigSet` :param relative_trick: preserve the folder hierarchy when installing whole folders :type relative_trick: bool :param cwd: parent node for searching srcfile, when srcfile is not an instance of :py:class:`waflib.Node.Node` :type cwd: :py:class:`waflib.Node.Node` :param postpone: execute the task immediately to perform the installation (False by default) :type postpone: bool """ assert(dest) tg = self(features='install_task', install_to=dest, install_from=files, **kw) tg.dest = tg.install_to tg.type = 'install_files' if not kw.get('postpone', True): tg.post() return tg def install_as(self, dest, srcfile, **kw): """ Creates a task generator to install a file on the system with a different name:: def build(bld): bld.install_as('${PREFIX}/bin', 'myapp', chmod=Utils.O755) :param dest: destination file :type dest: :py:class:`waflib.Node.Node` or string (absolute path) :param srcfile: input file :type srcfile: string or :py:class:`waflib.Node.Node` :param cwd: parent node for searching srcfile, when srcfile is not an instance of :py:class:`waflib.Node.Node` :type cwd: :py:class:`waflib.Node.Node` :param env: configuration set for performing substitutions in dest :type env: :py:class:`waflib.ConfigSet.ConfigSet` :param postpone: execute the task immediately to perform the installation (False by default) :type postpone: bool """ assert(dest) tg = self(features='install_task', install_to=dest, install_from=srcfile, **kw) tg.dest = tg.install_to tg.type = 'install_as' if not kw.get('postpone', True): tg.post() return tg def symlink_as(self, dest, src, **kw): """ Creates a task generator to install a symlink:: def build(bld): bld.symlink_as('${PREFIX}/lib/libfoo.so', 'libfoo.so.1.2.3') :param dest: absolute path of the symlink :type dest: :py:class:`waflib.Node.Node` or string (absolute path) :param src: link contents, which is a relative or absolute path which may exist or not :type src: string :param env: configuration set for performing substitutions in dest :type env: :py:class:`waflib.ConfigSet.ConfigSet` :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started :type add: bool :param postpone: execute the task immediately to perform the installation :type postpone: bool :param relative_trick: make the symlink relative (default: ``False``) :type relative_trick: bool """ assert(dest) tg = self(features='install_task', install_to=dest, install_from=src, **kw) tg.dest = tg.install_to tg.type = 'symlink_as' tg.link = src # TODO if add: self.add_to_group(tsk) if not kw.get('postpone', True): tg.post() return tg @TaskGen.feature('install_task') @TaskGen.before_method('process_rule', 'process_source') def process_install_task(self): """Creates the installation task for the current task generator; uses :py:func:`waflib.Build.add_install_task` internally.""" self.add_install_task(**self.__dict__) @TaskGen.taskgen_method def add_install_task(self, **kw): """ Creates the installation task for the current task generator, and executes it immediately if necessary :returns: An installation task :rtype: :py:class:`waflib.Build.inst` """ if not self.bld.is_install: return if not kw['install_to']: return if kw['type'] == 'symlink_as' and Utils.is_win32: if kw.get('win32_install'): kw['type'] = 'install_as' else: # just exit return tsk = self.install_task = self.create_task('inst') tsk.chmod = kw.get('chmod', Utils.O644) tsk.link = kw.get('link', '') or kw.get('install_from', '') tsk.relative_trick = kw.get('relative_trick', False) tsk.type = kw['type'] tsk.install_to = tsk.dest = kw['install_to'] tsk.install_from = kw['install_from'] tsk.relative_base = kw.get('cwd') or kw.get('relative_base', self.path) tsk.install_user = kw.get('install_user') tsk.install_group = kw.get('install_group') tsk.init_files() if not kw.get('postpone', True): tsk.run_now() return tsk @TaskGen.taskgen_method def add_install_files(self, **kw): """ Creates an installation task for files :returns: An installation task :rtype: :py:class:`waflib.Build.inst` """ kw['type'] = 'install_files' return self.add_install_task(**kw) @TaskGen.taskgen_method def add_install_as(self, **kw): """ Creates an installation task for a single file :returns: An installation task :rtype: :py:class:`waflib.Build.inst` """ kw['type'] = 'install_as' return self.add_install_task(**kw) @TaskGen.taskgen_method def add_symlink_as(self, **kw): """ Creates an installation task for a symbolic link :returns: An installation task :rtype: :py:class:`waflib.Build.inst` """ kw['type'] = 'symlink_as' return self.add_install_task(**kw) class inst(Task.Task): """Task that installs files or symlinks; it is typically executed by :py:class:`waflib.Build.InstallContext` and :py:class:`waflib.Build.UnInstallContext`""" def __str__(self): """Returns an empty string to disable the standard task display""" return '' def uid(self): """Returns a unique identifier for the task""" lst = self.inputs + self.outputs + [self.link, self.generator.path.abspath()] return Utils.h_list(lst) def init_files(self): """ Initializes the task input and output nodes """ if self.type == 'symlink_as': inputs = [] else: inputs = self.generator.to_nodes(self.install_from) if self.type == 'install_as': assert len(inputs) == 1 self.set_inputs(inputs) dest = self.get_install_path() outputs = [] if self.type == 'symlink_as': if self.relative_trick: self.link = os.path.relpath(self.link, os.path.dirname(dest)) outputs.append(self.generator.bld.root.make_node(dest)) elif self.type == 'install_as': outputs.append(self.generator.bld.root.make_node(dest)) else: for y in inputs: if self.relative_trick: destfile = os.path.join(dest, y.path_from(self.relative_base)) else: destfile = os.path.join(dest, y.name) outputs.append(self.generator.bld.root.make_node(destfile)) self.set_outputs(outputs) def runnable_status(self): """ Installation tasks are always executed, so this method returns either :py:const:`waflib.Task.ASK_LATER` or :py:const:`waflib.Task.RUN_ME`. """ ret = super(inst, self).runnable_status() if ret == Task.SKIP_ME and self.generator.bld.is_install: return Task.RUN_ME return ret def post_run(self): """ Disables any post-run operations """ pass def get_install_path(self, destdir=True): """ Returns the destination path where files will be installed, pre-pending `destdir`. Relative paths will be interpreted relative to `PREFIX` if no `destdir` is given. :rtype: string """ if isinstance(self.install_to, Node.Node): dest = self.install_to.abspath() else: dest = os.path.normpath(Utils.subst_vars(self.install_to, self.env)) if not os.path.isabs(dest): dest = os.path.join(self.env.PREFIX, dest) if destdir and Options.options.destdir: dest = os.path.join(Options.options.destdir, os.path.splitdrive(dest)[1].lstrip(os.sep)) return dest def copy_fun(self, src, tgt): """ Copies a file from src to tgt, preserving permissions and trying to work around path limitations on Windows platforms. On Unix-like platforms, the owner/group of the target file may be set through install_user/install_group :param src: absolute path :type src: string :param tgt: absolute path :type tgt: string """ # override this if you want to strip executables # kw['tsk'].source is the task that created the files in the build if Utils.is_win32 and len(tgt) > 259 and not tgt.startswith('\\\\?\\'): tgt = '\\\\?\\' + tgt shutil.copy2(src, tgt) self.fix_perms(tgt) def rm_empty_dirs(self, tgt): """ Removes empty folders recursively when uninstalling. :param tgt: absolute path :type tgt: string """ while tgt: tgt = os.path.dirname(tgt) try: os.rmdir(tgt) except OSError: break def run(self): """ Performs file or symlink installation """ is_install = self.generator.bld.is_install if not is_install: # unnecessary? return for x in self.outputs: if is_install == INSTALL: x.parent.mkdir() if self.type == 'symlink_as': fun = is_install == INSTALL and self.do_link or self.do_unlink fun(self.link, self.outputs[0].abspath()) else: fun = is_install == INSTALL and self.do_install or self.do_uninstall launch_node = self.generator.bld.launch_node() for x, y in zip(self.inputs, self.outputs): fun(x.abspath(), y.abspath(), x.path_from(launch_node)) def run_now(self): """ Try executing the installation task right now :raises: :py:class:`waflib.Errors.TaskNotReady` """ status = self.runnable_status() if status not in (Task.RUN_ME, Task.SKIP_ME): raise Errors.TaskNotReady('Could not process %r: status %r' % (self, status)) self.run() self.hasrun = Task.SUCCESS def do_install(self, src, tgt, lbl, **kw): """ Copies a file from src to tgt with given file permissions. The actual copy is only performed if the source and target file sizes or timestamps differ. When the copy occurs, the file is always first removed and then copied so as to prevent stale inodes. :param src: file name as absolute path :type src: string :param tgt: file destination, as absolute path :type tgt: string :param lbl: file source description :type lbl: string :param chmod: installation mode :type chmod: int :raises: :py:class:`waflib.Errors.WafError` if the file cannot be written """ if not Options.options.force: # check if the file is already there to avoid a copy try: st1 = os.stat(tgt) st2 = os.stat(src) except OSError: pass else: # same size and identical timestamps -> make no copy if st1.st_mtime + 2 >= st2.st_mtime and st1.st_size == st2.st_size: if not self.generator.bld.progress_bar: c1 = Logs.colors.NORMAL c2 = Logs.colors.BLUE Logs.info('%s- install %s%s%s (from %s)', c1, c2, tgt, c1, lbl) return False if not self.generator.bld.progress_bar: c1 = Logs.colors.NORMAL c2 = Logs.colors.BLUE Logs.info('%s+ install %s%s%s (from %s)', c1, c2, tgt, c1, lbl) # Give best attempt at making destination overwritable, # like the 'install' utility used by 'make install' does. try: os.chmod(tgt, Utils.O644 | stat.S_IMODE(os.stat(tgt).st_mode)) except EnvironmentError: pass # following is for shared libs and stale inodes (-_-) try: os.remove(tgt) except OSError: pass try: self.copy_fun(src, tgt) except EnvironmentError as e: if not os.path.exists(src): Logs.error('File %r does not exist', src) elif not os.path.isfile(src): Logs.error('Input %r is not a file', src) raise Errors.WafError('Could not install the file %r' % tgt, e) def fix_perms(self, tgt): """ Change the ownership of the file/folder/link pointed by the given path This looks up for `install_user` or `install_group` attributes on the task or on the task generator:: def build(bld): bld.install_as('${PREFIX}/wscript', 'wscript', install_user='nobody', install_group='nogroup') bld.symlink_as('${PREFIX}/wscript_link', Utils.subst_vars('${PREFIX}/wscript', bld.env), install_user='nobody', install_group='nogroup') """ if not Utils.is_win32: user = getattr(self, 'install_user', None) or getattr(self.generator, 'install_user', None) group = getattr(self, 'install_group', None) or getattr(self.generator, 'install_group', None) if user or group: Utils.lchown(tgt, user or -1, group or -1) if not os.path.islink(tgt): os.chmod(tgt, self.chmod) def do_link(self, src, tgt, **kw): """ Creates a symlink from tgt to src. :param src: file name as absolute path :type src: string :param tgt: file destination, as absolute path :type tgt: string """ if os.path.islink(tgt) and os.readlink(tgt) == src: if not self.generator.bld.progress_bar: c1 = Logs.colors.NORMAL c2 = Logs.colors.BLUE Logs.info('%s- symlink %s%s%s (to %s)', c1, c2, tgt, c1, src) else: try: os.remove(tgt) except OSError: pass if not self.generator.bld.progress_bar: c1 = Logs.colors.NORMAL c2 = Logs.colors.BLUE Logs.info('%s+ symlink %s%s%s (to %s)', c1, c2, tgt, c1, src) os.symlink(src, tgt) self.fix_perms(tgt) def do_uninstall(self, src, tgt, lbl, **kw): """ See :py:meth:`waflib.Build.inst.do_install` """ if not self.generator.bld.progress_bar: c1 = Logs.colors.NORMAL c2 = Logs.colors.BLUE Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1) #self.uninstall.append(tgt) try: os.remove(tgt) except OSError as e: if e.errno != errno.ENOENT: if not getattr(self, 'uninstall_error', None): self.uninstall_error = True Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') if Logs.verbose > 1: Logs.warn('Could not remove %s (error code %r)', e.filename, e.errno) self.rm_empty_dirs(tgt) def do_unlink(self, src, tgt, **kw): """ See :py:meth:`waflib.Build.inst.do_link` """ try: if not self.generator.bld.progress_bar: c1 = Logs.colors.NORMAL c2 = Logs.colors.BLUE Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1) os.remove(tgt) except OSError: pass self.rm_empty_dirs(tgt) class InstallContext(BuildContext): '''installs the targets on the system''' cmd = 'install' def __init__(self, **kw): super(InstallContext, self).__init__(**kw) self.is_install = INSTALL class UninstallContext(InstallContext): '''removes the targets installed''' cmd = 'uninstall' def __init__(self, **kw): super(UninstallContext, self).__init__(**kw) self.is_install = UNINSTALL class CleanContext(BuildContext): '''cleans the project''' cmd = 'clean' def execute(self): """ See :py:func:`waflib.Build.BuildContext.execute`. """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) try: self.clean() finally: self.store() def clean(self): """ Remove most files from the build directory, and reset all caches. Custom lists of files to clean can be declared as `bld.clean_files`. For example, exclude `build/program/myprogram` from getting removed:: def build(bld): bld.clean_files = bld.bldnode.ant_glob('**', excl='.lock* config.log c4che/* config.h program/myprogram', quiet=True, generator=True) """ Logs.debug('build: clean called') if hasattr(self, 'clean_files'): for n in self.clean_files: n.delete() elif self.bldnode != self.srcnode: # would lead to a disaster if top == out lst = [] for env in self.all_envs.values(): lst.extend(self.root.find_or_declare(f) for f in env[CFG_FILES]) excluded_dirs = '.lock* *conf_check_*/** config.log %s/*' % CACHE_DIR for n in self.bldnode.ant_glob('**/*', excl=excluded_dirs, quiet=True): if n in lst: continue n.delete() self.root.children = {} for v in SAVED_ATTRS: if v == 'root': continue setattr(self, v, {}) class ListContext(BuildContext): '''lists the targets to execute''' cmd = 'list' def execute(self): """ In addition to printing the name of each build target, a description column will include text for each task generator which has a "description" field set. See :py:func:`waflib.Build.BuildContext.execute`. """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) self.pre_build() # display the time elapsed in the progress bar self.timer = Utils.Timer() for g in self.groups: for tg in g: try: f = tg.post except AttributeError: pass else: f() try: # force the cache initialization self.get_tgen_by_name('') except Errors.WafError: pass targets = sorted(self.task_gen_cache_names) # figure out how much to left-justify, for largest target name line_just = max(len(t) for t in targets) if targets else 0 for target in targets: tgen = self.task_gen_cache_names[target] # Support displaying the description for the target # if it was set on the tgen descript = getattr(tgen, 'description', '') if descript: target = target.ljust(line_just) descript = ': %s' % descript Logs.pprint('GREEN', target, label=descript) class StepContext(BuildContext): '''executes tasks in a step-by-step fashion, for debugging''' cmd = 'step' def __init__(self, **kw): super(StepContext, self).__init__(**kw) self.files = Options.options.files def compile(self): """ Overrides :py:meth:`waflib.Build.BuildContext.compile` to perform a partial build on tasks matching the input/output pattern given (regular expression matching):: $ waf step --files=foo.c,bar.c,in:truc.c,out:bar.o $ waf step --files=in:foo.cpp.1.o # link task only """ if not self.files: Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') BuildContext.compile(self) return targets = [] if self.targets and self.targets != '*': targets = self.targets.split(',') for g in self.groups: for tg in g: if targets and tg.name not in targets: continue try: f = tg.post except AttributeError: pass else: f() for pat in self.files.split(','): matcher = self.get_matcher(pat) for tg in g: if isinstance(tg, Task.Task): lst = [tg] else: lst = tg.tasks for tsk in lst: do_exec = False for node in tsk.inputs: if matcher(node, output=False): do_exec = True break for node in tsk.outputs: if matcher(node, output=True): do_exec = True break if do_exec: ret = tsk.run() Logs.info('%s -> exit %r', tsk, ret) def get_matcher(self, pat): """ Converts a step pattern into a function :param: pat: pattern of the form in:truc.c,out:bar.o :returns: Python function that uses Node objects as inputs and returns matches :rtype: function """ # this returns a function inn = True out = True if pat.startswith('in:'): out = False pat = pat.replace('in:', '') elif pat.startswith('out:'): inn = False pat = pat.replace('out:', '') anode = self.root.find_node(pat) pattern = None if not anode: if not pat.startswith('^'): pat = '^.+?%s' % pat if not pat.endswith('$'): pat = '%s$' % pat pattern = re.compile(pat) def match(node, output): if output and not out: return False if not output and not inn: return False if anode: return anode == node else: return pattern.match(node.abspath()) return match class EnvContext(BuildContext): """Subclass EnvContext to create commands that require configuration data in 'env'""" fun = cmd = None def execute(self): """ See :py:func:`waflib.Build.BuildContext.execute`. """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) ldb-2.0.8/third_party/waf/waflib/ConfigSet.py0000660000000000000000000002014613573675414021045 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ ConfigSet: a special dict The values put in :py:class:`ConfigSet` must be serializable (dicts, lists, strings) """ import copy, re, os from waflib import Logs, Utils re_imp = re.compile(r'^(#)*?([^#=]*?)\ =\ (.*?)$', re.M) class ConfigSet(object): """ A copy-on-write dict with human-readable serialized format. The serialization format is human-readable (python-like) and performed by using eval() and repr(). For high performance prefer pickle. Do not store functions as they are not serializable. The values can be accessed by attributes or by keys:: from waflib.ConfigSet import ConfigSet env = ConfigSet() env.FOO = 'test' env['FOO'] = 'test' """ __slots__ = ('table', 'parent') def __init__(self, filename=None): self.table = {} """ Internal dict holding the object values """ #self.parent = None if filename: self.load(filename) def __contains__(self, key): """ Enables the *in* syntax:: if 'foo' in env: print(env['foo']) """ if key in self.table: return True try: return self.parent.__contains__(key) except AttributeError: return False # parent may not exist def keys(self): """Dict interface""" keys = set() cur = self while cur: keys.update(cur.table.keys()) cur = getattr(cur, 'parent', None) keys = list(keys) keys.sort() return keys def __iter__(self): return iter(self.keys()) def __str__(self): """Text representation of the ConfigSet (for debugging purposes)""" return "\n".join(["%r %r" % (x, self.__getitem__(x)) for x in self.keys()]) def __getitem__(self, key): """ Dictionary interface: get value from key:: def configure(conf): conf.env['foo'] = {} print(env['foo']) """ try: while 1: x = self.table.get(key) if not x is None: return x self = self.parent except AttributeError: return [] def __setitem__(self, key, value): """ Dictionary interface: set value from key """ self.table[key] = value def __delitem__(self, key): """ Dictionary interface: mark the value as missing """ self[key] = [] def __getattr__(self, name): """ Attribute access provided for convenience. The following forms are equivalent:: def configure(conf): conf.env.value conf.env['value'] """ if name in self.__slots__: return object.__getattribute__(self, name) else: return self[name] def __setattr__(self, name, value): """ Attribute access provided for convenience. The following forms are equivalent:: def configure(conf): conf.env.value = x env['value'] = x """ if name in self.__slots__: object.__setattr__(self, name, value) else: self[name] = value def __delattr__(self, name): """ Attribute access provided for convenience. The following forms are equivalent:: def configure(conf): del env.value del env['value'] """ if name in self.__slots__: object.__delattr__(self, name) else: del self[name] def derive(self): """ Returns a new ConfigSet deriving from self. The copy returned will be a shallow copy:: from waflib.ConfigSet import ConfigSet env = ConfigSet() env.append_value('CFLAGS', ['-O2']) child = env.derive() child.CFLAGS.append('test') # warning! this will modify 'env' child.CFLAGS = ['-O3'] # new list, ok child.append_value('CFLAGS', ['-O3']) # ok Use :py:func:`ConfigSet.detach` to detach the child from the parent. """ newenv = ConfigSet() newenv.parent = self return newenv def detach(self): """ Detaches this instance from its parent (if present) Modifying the parent :py:class:`ConfigSet` will not change the current object Modifying this :py:class:`ConfigSet` will not modify the parent one. """ tbl = self.get_merged_dict() try: delattr(self, 'parent') except AttributeError: pass else: keys = tbl.keys() for x in keys: tbl[x] = copy.deepcopy(tbl[x]) self.table = tbl return self def get_flat(self, key): """ Returns a value as a string. If the input is a list, the value returned is space-separated. :param key: key to use :type key: string """ s = self[key] if isinstance(s, str): return s return ' '.join(s) def _get_list_value_for_modification(self, key): """ Returns a list value for further modification. The list may be modified inplace and there is no need to do this afterwards:: self.table[var] = value """ try: value = self.table[key] except KeyError: try: value = self.parent[key] except AttributeError: value = [] else: if isinstance(value, list): # force a copy value = value[:] else: value = [value] self.table[key] = value else: if not isinstance(value, list): self.table[key] = value = [value] return value def append_value(self, var, val): """ Appends a value to the specified config key:: def build(bld): bld.env.append_value('CFLAGS', ['-O2']) The value must be a list or a tuple """ if isinstance(val, str): # if there were string everywhere we could optimize this val = [val] current_value = self._get_list_value_for_modification(var) current_value.extend(val) def prepend_value(self, var, val): """ Prepends a value to the specified item:: def configure(conf): conf.env.prepend_value('CFLAGS', ['-O2']) The value must be a list or a tuple """ if isinstance(val, str): val = [val] self.table[var] = val + self._get_list_value_for_modification(var) def append_unique(self, var, val): """ Appends a value to the specified item only if it's not already present:: def build(bld): bld.env.append_unique('CFLAGS', ['-O2', '-g']) The value must be a list or a tuple """ if isinstance(val, str): val = [val] current_value = self._get_list_value_for_modification(var) for x in val: if x not in current_value: current_value.append(x) def get_merged_dict(self): """ Computes the merged dictionary from the fusion of self and all its parent :rtype: a ConfigSet object """ table_list = [] env = self while 1: table_list.insert(0, env.table) try: env = env.parent except AttributeError: break merged_table = {} for table in table_list: merged_table.update(table) return merged_table def store(self, filename): """ Serializes the :py:class:`ConfigSet` data to a file. See :py:meth:`ConfigSet.load` for reading such files. :param filename: file to use :type filename: string """ try: os.makedirs(os.path.split(filename)[0]) except OSError: pass buf = [] merged_table = self.get_merged_dict() keys = list(merged_table.keys()) keys.sort() try: fun = ascii except NameError: fun = repr for k in keys: if k != 'undo_stack': buf.append('%s = %s\n' % (k, fun(merged_table[k]))) Utils.writef(filename, ''.join(buf)) def load(self, filename): """ Restores contents from a file (current values are not cleared). Files are written using :py:meth:`ConfigSet.store`. :param filename: file to use :type filename: string """ tbl = self.table code = Utils.readf(filename, m='r') for m in re_imp.finditer(code): g = m.group tbl[g(2)] = eval(g(3)) Logs.debug('env: %s', self.table) def update(self, d): """ Dictionary interface: replace values with the ones from another dict :param d: object to use the value from :type d: dict-like object """ self.table.update(d) def stash(self): """ Stores the object state to provide transactionality semantics:: env = ConfigSet() env.stash() try: env.append_value('CFLAGS', '-O3') call_some_method(env) finally: env.revert() The history is kept in a stack, and is lost during the serialization by :py:meth:`ConfigSet.store` """ orig = self.table tbl = self.table = self.table.copy() for x in tbl.keys(): tbl[x] = copy.deepcopy(tbl[x]) self.undo_stack = self.undo_stack + [orig] def commit(self): """ Commits transactional changes. See :py:meth:`ConfigSet.stash` """ self.undo_stack.pop(-1) def revert(self): """ Reverts the object to a previous state. See :py:meth:`ConfigSet.stash` """ self.table = self.undo_stack.pop(-1) ldb-2.0.8/third_party/waf/waflib/Configure.py0000660000000000000000000004470413573675414021113 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Configuration system A :py:class:`waflib.Configure.ConfigurationContext` instance is created when ``waf configure`` is called, it is used to: * create data dictionaries (ConfigSet instances) * store the list of modules to import * hold configuration routines such as ``find_program``, etc """ import os, re, shlex, shutil, sys, time, traceback from waflib import ConfigSet, Utils, Options, Logs, Context, Build, Errors WAF_CONFIG_LOG = 'config.log' """Name of the configuration log file""" autoconfig = False """Execute the configuration automatically""" conf_template = '''# project %(app)s configured on %(now)s by # waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) # using %(args)s #''' class ConfigurationContext(Context.Context): '''configures the project''' cmd = 'configure' error_handlers = [] """ Additional functions to handle configuration errors """ def __init__(self, **kw): super(ConfigurationContext, self).__init__(**kw) self.environ = dict(os.environ) self.all_envs = {} self.top_dir = None self.out_dir = None self.tools = [] # tools loaded in the configuration, and that will be loaded when building self.hash = 0 self.files = [] self.tool_cache = [] self.setenv('') def setenv(self, name, env=None): """ Set a new config set for conf.env. If a config set of that name already exists, recall it without modification. The name is the filename prefix to save to ``c4che/NAME_cache.py``, and it is also used as *variants* by the build commands. Though related to variants, whatever kind of data may be stored in the config set:: def configure(cfg): cfg.env.ONE = 1 cfg.setenv('foo') cfg.env.ONE = 2 def build(bld): 2 == bld.env_of_name('foo').ONE :param name: name of the configuration set :type name: string :param env: ConfigSet to copy, or an empty ConfigSet is created :type env: :py:class:`waflib.ConfigSet.ConfigSet` """ if name not in self.all_envs or env: if not env: env = ConfigSet.ConfigSet() self.prepare_env(env) else: env = env.derive() self.all_envs[name] = env self.variant = name def get_env(self): """Getter for the env property""" return self.all_envs[self.variant] def set_env(self, val): """Setter for the env property""" self.all_envs[self.variant] = val env = property(get_env, set_env) def init_dirs(self): """ Initialize the project directory and the build directory """ top = self.top_dir if not top: top = Options.options.top if not top: top = getattr(Context.g_module, Context.TOP, None) if not top: top = self.path.abspath() top = os.path.abspath(top) self.srcnode = (os.path.isabs(top) and self.root or self.path).find_dir(top) assert(self.srcnode) out = self.out_dir if not out: out = Options.options.out if not out: out = getattr(Context.g_module, Context.OUT, None) if not out: out = Options.lockfile.replace('.lock-waf_%s_' % sys.platform, '').replace('.lock-waf', '') # someone can be messing with symlinks out = os.path.realpath(out) self.bldnode = (os.path.isabs(out) and self.root or self.path).make_node(out) self.bldnode.mkdir() if not os.path.isdir(self.bldnode.abspath()): self.fatal('Could not create the build directory %s' % self.bldnode.abspath()) def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ self.init_dirs() self.cachedir = self.bldnode.make_node(Build.CACHE_DIR) self.cachedir.mkdir() path = os.path.join(self.bldnode.abspath(), WAF_CONFIG_LOG) self.logger = Logs.make_logger(path, 'cfg') app = getattr(Context.g_module, 'APPNAME', '') if app: ver = getattr(Context.g_module, 'VERSION', '') if ver: app = "%s (%s)" % (app, ver) params = {'now': time.ctime(), 'pyver': sys.hexversion, 'systype': sys.platform, 'args': " ".join(sys.argv), 'wafver': Context.WAFVERSION, 'abi': Context.ABI, 'app': app} self.to_log(conf_template % params) self.msg('Setting top to', self.srcnode.abspath()) self.msg('Setting out to', self.bldnode.abspath()) if id(self.srcnode) == id(self.bldnode): Logs.warn('Setting top == out') elif id(self.path) != id(self.srcnode): if self.srcnode.is_child_of(self.path): Logs.warn('Are you certain that you do not want to set top="." ?') super(ConfigurationContext, self).execute() self.store() Context.top_dir = self.srcnode.abspath() Context.out_dir = self.bldnode.abspath() # this will write a configure lock so that subsequent builds will # consider the current path as the root directory (see prepare_impl). # to remove: use 'waf distclean' env = ConfigSet.ConfigSet() env.argv = sys.argv env.options = Options.options.__dict__ env.config_cmd = self.cmd env.run_dir = Context.run_dir env.top_dir = Context.top_dir env.out_dir = Context.out_dir # conf.hash & conf.files hold wscript files paths and hash # (used only by Configure.autoconfig) env.hash = self.hash env.files = self.files env.environ = dict(self.environ) env.launch_dir = Context.launch_dir if not (self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN') or getattr(Options.options, 'no_lock_in_run')): env.store(os.path.join(Context.run_dir, Options.lockfile)) if not (self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP') or getattr(Options.options, 'no_lock_in_top')): env.store(os.path.join(Context.top_dir, Options.lockfile)) if not (self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT') or getattr(Options.options, 'no_lock_in_out')): env.store(os.path.join(Context.out_dir, Options.lockfile)) def prepare_env(self, env): """ Insert *PREFIX*, *BINDIR* and *LIBDIR* values into ``env`` :type env: :py:class:`waflib.ConfigSet.ConfigSet` :param env: a ConfigSet, usually ``conf.env`` """ if not env.PREFIX: if Options.options.prefix or Utils.is_win32: env.PREFIX = Options.options.prefix else: env.PREFIX = '/' if not env.BINDIR: if Options.options.bindir: env.BINDIR = Options.options.bindir else: env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env) if not env.LIBDIR: if Options.options.libdir: env.LIBDIR = Options.options.libdir else: env.LIBDIR = Utils.subst_vars('${PREFIX}/lib%s' % Utils.lib64(), env) def store(self): """Save the config results into the cache file""" n = self.cachedir.make_node('build.config.py') n.write('version = 0x%x\ntools = %r\n' % (Context.HEXVERSION, self.tools)) if not self.all_envs: self.fatal('nothing to store in the configuration context!') for key in self.all_envs: tmpenv = self.all_envs[key] tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX)) def load(self, tool_list, tooldir=None, funs=None, with_sys_path=True, cache=False): """ Load Waf tools, which will be imported whenever a build is started. :param tool_list: waf tools to import :type tool_list: list of string :param tooldir: paths for the imports :type tooldir: list of string :param funs: functions to execute from the waf tools :type funs: list of string :param cache: whether to prevent the tool from running twice :type cache: bool """ tools = Utils.to_list(tool_list) if tooldir: tooldir = Utils.to_list(tooldir) for tool in tools: # avoid loading the same tool more than once with the same functions # used by composite projects if cache: mag = (tool, id(self.env), tooldir, funs) if mag in self.tool_cache: self.to_log('(tool %s is already loaded, skipping)' % tool) continue self.tool_cache.append(mag) module = None try: module = Context.load_tool(tool, tooldir, ctx=self, with_sys_path=with_sys_path) except ImportError as e: self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, getattr(e, 'waf_sys_path', sys.path), e)) except Exception as e: self.to_log('imp %r (%r & %r)' % (tool, tooldir, funs)) self.to_log(traceback.format_exc()) raise if funs is not None: self.eval_rules(funs) else: func = getattr(module, 'configure', None) if func: if type(func) is type(Utils.readf): func(self) else: self.eval_rules(func) self.tools.append({'tool':tool, 'tooldir':tooldir, 'funs':funs}) def post_recurse(self, node): """ Records the path and a hash of the scripts visited, see :py:meth:`waflib.Context.Context.post_recurse` :param node: script :type node: :py:class:`waflib.Node.Node` """ super(ConfigurationContext, self).post_recurse(node) self.hash = Utils.h_list((self.hash, node.read('rb'))) self.files.append(node.abspath()) def eval_rules(self, rules): """ Execute configuration tests provided as list of functions to run :param rules: list of configuration method names :type rules: list of string """ self.rules = Utils.to_list(rules) for x in self.rules: f = getattr(self, x) if not f: self.fatal('No such configuration function %r' % x) f() def conf(f): """ Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and :py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter named 'mandatory' to disable the configuration errors:: def configure(conf): conf.find_program('abc', mandatory=False) :param f: method to bind :type f: function """ def fun(*k, **kw): mandatory = kw.pop('mandatory', True) try: return f(*k, **kw) except Errors.ConfigurationError: if mandatory: raise fun.__name__ = f.__name__ setattr(ConfigurationContext, f.__name__, fun) setattr(Build.BuildContext, f.__name__, fun) return f @conf def add_os_flags(self, var, dest=None, dup=False): """ Import operating system environment values into ``conf.env`` dict:: def configure(conf): conf.add_os_flags('CFLAGS') :param var: variable to use :type var: string :param dest: destination variable, by default the same as var :type dest: string :param dup: add the same set of flags again :type dup: bool """ try: flags = shlex.split(self.environ[var]) except KeyError: return if dup or ''.join(flags) not in ''.join(Utils.to_list(self.env[dest or var])): self.env.append_value(dest or var, flags) @conf def cmd_to_list(self, cmd): """ Detect if a command is written in pseudo shell like ``ccache g++`` and return a list. :param cmd: command :type cmd: a string or a list of string """ if isinstance(cmd, str): if os.path.isfile(cmd): # do not take any risk return [cmd] if os.sep == '/': return shlex.split(cmd) else: try: return shlex.split(cmd, posix=False) except TypeError: # Python 2.5 on windows? return shlex.split(cmd) return cmd @conf def check_waf_version(self, mini='1.9.99', maxi='2.1.0', **kw): """ Raise a Configuration error if the Waf version does not strictly match the given bounds:: conf.check_waf_version(mini='1.9.99', maxi='2.1.0') :type mini: number, tuple or string :param mini: Minimum required version :type maxi: number, tuple or string :param maxi: Maximum allowed version """ self.start_msg('Checking for waf version in %s-%s' % (str(mini), str(maxi)), **kw) ver = Context.HEXVERSION if Utils.num2ver(mini) > ver: self.fatal('waf version should be at least %r (%r found)' % (Utils.num2ver(mini), ver)) if Utils.num2ver(maxi) < ver: self.fatal('waf version should be at most %r (%r found)' % (Utils.num2ver(maxi), ver)) self.end_msg('ok', **kw) @conf def find_file(self, filename, path_list=[]): """ Find a file in a list of paths :param filename: name of the file to search for :param path_list: list of directories to search :return: the first matching filename; else a configuration exception is raised """ for n in Utils.to_list(filename): for d in Utils.to_list(path_list): p = os.path.expanduser(os.path.join(d, n)) if os.path.exists(p): return p self.fatal('Could not find %r' % filename) @conf def find_program(self, filename, **kw): """ Search for a program on the operating system When var is used, you may set os.environ[var] to help find a specific program version, for example:: $ CC='ccache gcc' waf configure :param path_list: paths to use for searching :type param_list: list of string :param var: store the result to conf.env[var] where var defaults to filename.upper() if not provided; the result is stored as a list of strings :type var: string :param value: obtain the program from the value passed exclusively :type value: list or string (list is preferred) :param exts: list of extensions for the binary (do not add an extension for portability) :type exts: list of string :param msg: name to display in the log, by default filename is used :type msg: string :param interpreter: interpreter for the program :type interpreter: ConfigSet variable key :raises: :py:class:`waflib.Errors.ConfigurationError` """ exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py') environ = kw.get('environ', getattr(self, 'environ', os.environ)) ret = '' filename = Utils.to_list(filename) msg = kw.get('msg', ', '.join(filename)) var = kw.get('var', '') if not var: var = re.sub(r'[-.]', '_', filename[0].upper()) path_list = kw.get('path_list', '') if path_list: path_list = Utils.to_list(path_list) else: path_list = environ.get('PATH', '').split(os.pathsep) if kw.get('value'): # user-provided in command-line options and passed to find_program ret = self.cmd_to_list(kw['value']) elif environ.get(var): # user-provided in the os environment ret = self.cmd_to_list(environ[var]) elif self.env[var]: # a default option in the wscript file ret = self.cmd_to_list(self.env[var]) else: if not ret: ret = self.find_binary(filename, exts.split(','), path_list) if not ret and Utils.winreg: ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename) if not ret and Utils.winreg: ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename) ret = self.cmd_to_list(ret) if ret: if len(ret) == 1: retmsg = ret[0] else: retmsg = ret else: retmsg = False self.msg('Checking for program %r' % msg, retmsg, **kw) if not kw.get('quiet'): self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret)) if not ret: self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename) interpreter = kw.get('interpreter') if interpreter is None: if not Utils.check_exe(ret[0], env=environ): self.fatal('Program %r is not executable' % ret) self.env[var] = ret else: self.env[var] = self.env[interpreter] + ret return ret @conf def find_binary(self, filenames, exts, paths): for f in filenames: for ext in exts: exe_name = f + ext if os.path.isabs(exe_name): if os.path.isfile(exe_name): return exe_name else: for path in paths: x = os.path.expanduser(os.path.join(path, exe_name)) if os.path.isfile(x): return x return None @conf def run_build(self, *k, **kw): """ Create a temporary build context to execute a build. A reference to that build context is kept on self.test_bld for debugging purposes, and you should not rely on it too much (read the note on the cache below). The parameters given in the arguments to this function are passed as arguments for a single task generator created in the build. Only three parameters are obligatory: :param features: features to pass to a task generator created in the build :type features: list of string :param compile_filename: file to create for the compilation (default: *test.c*) :type compile_filename: string :param code: code to write in the filename to compile :type code: string Though this function returns *0* by default, the build may set an attribute named *retval* on the build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example. This function also features a cache which can be enabled by the following option:: def options(opt): opt.add_option('--confcache', dest='confcache', default=0, action='count', help='Use a configuration cache') And execute the configuration with the following command-line:: $ waf configure --confcache """ buf = [] for key in sorted(kw.keys()): v = kw[key] if hasattr(v, '__call__'): buf.append(Utils.h_fun(v)) else: buf.append(str(v)) h = Utils.h_list(buf) dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h) cachemode = kw.get('confcache', getattr(Options.options, 'confcache', None)) if not cachemode and os.path.exists(dir): shutil.rmtree(dir) try: os.makedirs(dir) except OSError: pass try: os.stat(dir) except OSError: self.fatal('cannot use the configuration test folder %r' % dir) if cachemode == 1: try: proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build')) except EnvironmentError: pass else: ret = proj['cache_run_build'] if isinstance(ret, str) and ret.startswith('Test does not build'): self.fatal(ret) return ret bdir = os.path.join(dir, 'testbuild') if not os.path.exists(bdir): os.makedirs(bdir) cls_name = kw.get('run_build_cls') or getattr(self, 'run_build_cls', 'build') self.test_bld = bld = Context.create_context(cls_name, top_dir=dir, out_dir=bdir) bld.init_dirs() bld.progress_bar = 0 bld.targets = '*' bld.logger = self.logger bld.all_envs.update(self.all_envs) # not really necessary bld.env = kw['env'] bld.kw = kw bld.conf = self kw['build_fun'](bld) ret = -1 try: try: bld.compile() except Errors.WafError: ret = 'Test does not build: %s' % traceback.format_exc() self.fatal(ret) else: ret = getattr(bld, 'retval', 0) finally: if cachemode: # cache the results each time proj = ConfigSet.ConfigSet() proj['cache_run_build'] = ret proj.store(os.path.join(dir, 'cache_run_build')) else: shutil.rmtree(dir) return ret @conf def ret_msg(self, msg, args): if isinstance(msg, str): return msg return msg(args) @conf def test(self, *k, **kw): if not 'env' in kw: kw['env'] = self.env.derive() # validate_c for example if kw.get('validate'): kw['validate'](kw) self.start_msg(kw['msg'], **kw) ret = None try: ret = self.run_build(*k, **kw) except self.errors.ConfigurationError: self.end_msg(kw['errmsg'], 'YELLOW', **kw) if Logs.verbose > 1: raise else: self.fatal('The configuration failed') else: kw['success'] = ret if kw.get('post_check'): ret = kw['post_check'](kw) if ret: self.end_msg(kw['errmsg'], 'YELLOW', **kw) self.fatal('The configuration failed %r' % ret) else: self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) return ret ldb-2.0.8/third_party/waf/waflib/Context.py0000660000000000000000000005104513573675414020612 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010-2018 (ita) """ Classes and functions enabling the command system """ import os, re, imp, sys from waflib import Utils, Errors, Logs import waflib.Node # the following 3 constants are updated on each new release (do not touch) HEXVERSION=0x2001200 """Constant updated on new releases""" WAFVERSION="2.0.18" """Constant updated on new releases""" WAFREVISION="314689b8994259a84f0de0aaef74d7ce91f541ad" """Git revision when the waf version is updated""" ABI = 20 """Version of the build data cache file format (used in :py:const:`waflib.Context.DBFILE`)""" DBFILE = '.wafpickle-%s-%d-%d' % (sys.platform, sys.hexversion, ABI) """Name of the pickle file for storing the build data""" APPNAME = 'APPNAME' """Default application name (used by ``waf dist``)""" VERSION = 'VERSION' """Default application version (used by ``waf dist``)""" TOP = 'top' """The variable name for the top-level directory in wscript files""" OUT = 'out' """The variable name for the output directory in wscript files""" WSCRIPT_FILE = 'wscript' """Name of the waf script files""" launch_dir = '' """Directory from which waf has been called""" run_dir = '' """Location of the wscript file to use as the entry point""" top_dir = '' """Location of the project directory (top), if the project was configured""" out_dir = '' """Location of the build directory (out), if the project was configured""" waf_dir = '' """Directory containing the waf modules""" default_encoding = Utils.console_encoding() """Encoding to use when reading outputs from other processes""" g_module = None """ Module representing the top-level wscript file (see :py:const:`waflib.Context.run_dir`) """ STDOUT = 1 STDERR = -1 BOTH = 0 classes = [] """ List of :py:class:`waflib.Context.Context` subclasses that can be used as waf commands. The classes are added automatically by a metaclass. """ def create_context(cmd_name, *k, **kw): """ Returns a new :py:class:`waflib.Context.Context` instance corresponding to the given command. Used in particular by :py:func:`waflib.Scripting.run_command` :param cmd_name: command name :type cmd_name: string :param k: arguments to give to the context class initializer :type k: list :param k: keyword arguments to give to the context class initializer :type k: dict :return: Context object :rtype: :py:class:`waflib.Context.Context` """ for x in classes: if x.cmd == cmd_name: return x(*k, **kw) ctx = Context(*k, **kw) ctx.fun = cmd_name return ctx class store_context(type): """ Metaclass that registers command classes into the list :py:const:`waflib.Context.classes` Context classes must provide an attribute 'cmd' representing the command name, and a function attribute 'fun' representing the function name that the command uses. """ def __init__(cls, name, bases, dct): super(store_context, cls).__init__(name, bases, dct) name = cls.__name__ if name in ('ctx', 'Context'): return try: cls.cmd except AttributeError: raise Errors.WafError('Missing command for the context class %r (cmd)' % name) if not getattr(cls, 'fun', None): cls.fun = cls.cmd classes.insert(0, cls) ctx = store_context('ctx', (object,), {}) """Base class for all :py:class:`waflib.Context.Context` classes""" class Context(ctx): """ Default context for waf commands, and base class for new command contexts. Context objects are passed to top-level functions:: def foo(ctx): print(ctx.__class__.__name__) # waflib.Context.Context Subclasses must define the class attributes 'cmd' and 'fun': :param cmd: command to execute as in ``waf cmd`` :type cmd: string :param fun: function name to execute when the command is called :type fun: string .. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext """ errors = Errors """ Shortcut to :py:mod:`waflib.Errors` provided for convenience """ tools = {} """ A module cache for wscript files; see :py:meth:`Context.Context.load` """ def __init__(self, **kw): try: rd = kw['run_dir'] except KeyError: rd = run_dir # binds the context to the nodes in use to avoid a context singleton self.node_class = type('Nod3', (waflib.Node.Node,), {}) self.node_class.__module__ = 'waflib.Node' self.node_class.ctx = self self.root = self.node_class('', None) self.cur_script = None self.path = self.root.find_dir(rd) self.stack_path = [] self.exec_dict = {'ctx':self, 'conf':self, 'bld':self, 'opt':self} self.logger = None def finalize(self): """ Called to free resources such as logger files """ try: logger = self.logger except AttributeError: pass else: Logs.free_logger(logger) delattr(self, 'logger') def load(self, tool_list, *k, **kw): """ Loads a Waf tool as a module, and try calling the function named :py:const:`waflib.Context.Context.fun` from it. A ``tooldir`` argument may be provided as a list of module paths. :param tool_list: list of Waf tool names to load :type tool_list: list of string or space-separated string """ tools = Utils.to_list(tool_list) path = Utils.to_list(kw.get('tooldir', '')) with_sys_path = kw.get('with_sys_path', True) for t in tools: module = load_tool(t, path, with_sys_path=with_sys_path) fun = getattr(module, kw.get('name', self.fun), None) if fun: fun(self) def execute(self): """ Here, it calls the function name in the top-level wscript file. Most subclasses redefine this method to provide additional functionality. """ self.recurse([os.path.dirname(g_module.root_path)]) def pre_recurse(self, node): """ Method executed immediately before a folder is read by :py:meth:`waflib.Context.Context.recurse`. The current script is bound as a Node object on ``self.cur_script``, and the current path is bound to ``self.path`` :param node: script :type node: :py:class:`waflib.Node.Node` """ self.stack_path.append(self.cur_script) self.cur_script = node self.path = node.parent def post_recurse(self, node): """ Restores ``self.cur_script`` and ``self.path`` right after :py:meth:`waflib.Context.Context.recurse` terminates. :param node: script :type node: :py:class:`waflib.Node.Node` """ self.cur_script = self.stack_path.pop() if self.cur_script: self.path = self.cur_script.parent def recurse(self, dirs, name=None, mandatory=True, once=True, encoding=None): """ Runs user-provided functions from the supplied list of directories. The directories can be either absolute, or relative to the directory of the wscript file The methods :py:meth:`waflib.Context.Context.pre_recurse` and :py:meth:`waflib.Context.Context.post_recurse` are called immediately before and after a script has been executed. :param dirs: List of directories to visit :type dirs: list of string or space-separated string :param name: Name of function to invoke from the wscript :type name: string :param mandatory: whether sub wscript files are required to exist :type mandatory: bool :param once: read the script file once for a particular context :type once: bool """ try: cache = self.recurse_cache except AttributeError: cache = self.recurse_cache = {} for d in Utils.to_list(dirs): if not os.path.isabs(d): # absolute paths only d = os.path.join(self.path.abspath(), d) WSCRIPT = os.path.join(d, WSCRIPT_FILE) WSCRIPT_FUN = WSCRIPT + '_' + (name or self.fun) node = self.root.find_node(WSCRIPT_FUN) if node and (not once or node not in cache): cache[node] = True self.pre_recurse(node) try: function_code = node.read('r', encoding) exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict) finally: self.post_recurse(node) elif not node: node = self.root.find_node(WSCRIPT) tup = (node, name or self.fun) if node and (not once or tup not in cache): cache[tup] = True self.pre_recurse(node) try: wscript_module = load_module(node.abspath(), encoding=encoding) user_function = getattr(wscript_module, (name or self.fun), None) if not user_function: if not mandatory: continue raise Errors.WafError('No function %r defined in %s' % (name or self.fun, node.abspath())) user_function(self) finally: self.post_recurse(node) elif not node: if not mandatory: continue try: os.listdir(d) except OSError: raise Errors.WafError('Cannot read the folder %r' % d) raise Errors.WafError('No wscript file in directory %s' % d) def log_command(self, cmd, kw): if Logs.verbose: fmt = os.environ.get('WAF_CMD_FORMAT') if fmt == 'string': if not isinstance(cmd, str): cmd = Utils.shell_escape(cmd) Logs.debug('runner: %r', cmd) Logs.debug('runner_env: kw=%s', kw) def exec_command(self, cmd, **kw): """ Runs an external process and returns the exit status:: def run(tsk): ret = tsk.generator.bld.exec_command('touch foo.txt') return ret If the context has the attribute 'log', then captures and logs the process stderr/stdout. Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the stdout/stderr values captured. :param cmd: command argument for subprocess.Popen :type cmd: string or list :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. :type kw: dict :returns: process exit status :rtype: integer :raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process :raises: :py:class:`waflib.Errors.WafError` in case of execution failure """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) self.log_command(cmd, kw) if self.logger: self.logger.info(cmd) if 'stdout' not in kw: kw['stdout'] = subprocess.PIPE if 'stderr' not in kw: kw['stderr'] = subprocess.PIPE if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): raise Errors.WafError('Program %s not found!' % cmd[0]) cargs = {} if 'timeout' in kw: if sys.hexversion >= 0x3030000: cargs['timeout'] = kw['timeout'] if not 'start_new_session' in kw: kw['start_new_session'] = True del kw['timeout'] if 'input' in kw: if kw['input']: cargs['input'] = kw['input'] kw['stdin'] = subprocess.PIPE del kw['input'] if 'cwd' in kw: if not isinstance(kw['cwd'], str): kw['cwd'] = kw['cwd'].abspath() encoding = kw.pop('decode_as', default_encoding) try: ret, out, err = Utils.run_process(cmd, kw, cargs) except Exception as e: raise Errors.WafError('Execution failure: %s' % str(e), ex=e) if out: if not isinstance(out, str): out = out.decode(encoding, errors='replace') if self.logger: self.logger.debug('out: %s', out) else: Logs.info(out, extra={'stream':sys.stdout, 'c1': ''}) if err: if not isinstance(err, str): err = err.decode(encoding, errors='replace') if self.logger: self.logger.error('err: %s' % err) else: Logs.info(err, extra={'stream':sys.stderr, 'c1': ''}) return ret def cmd_and_log(self, cmd, **kw): """ Executes a process and returns stdout/stderr if the execution is successful. An exception is thrown when the exit status is non-0. In that case, both stderr and stdout will be bound to the WafError object (configuration tests):: def configure(conf): out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH) (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH) (out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT) try: conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH) except Errors.WafError as e: print(e.stdout, e.stderr) :param cmd: args for subprocess.Popen :type cmd: list or string :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. :type kw: dict :returns: a tuple containing the contents of stdout and stderr :rtype: string :raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process :raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) self.log_command(cmd, kw) quiet = kw.pop('quiet', None) to_ret = kw.pop('output', STDOUT) if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): raise Errors.WafError('Program %r not found!' % cmd[0]) kw['stdout'] = kw['stderr'] = subprocess.PIPE if quiet is None: self.to_log(cmd) cargs = {} if 'timeout' in kw: if sys.hexversion >= 0x3030000: cargs['timeout'] = kw['timeout'] if not 'start_new_session' in kw: kw['start_new_session'] = True del kw['timeout'] if 'input' in kw: if kw['input']: cargs['input'] = kw['input'] kw['stdin'] = subprocess.PIPE del kw['input'] if 'cwd' in kw: if not isinstance(kw['cwd'], str): kw['cwd'] = kw['cwd'].abspath() encoding = kw.pop('decode_as', default_encoding) try: ret, out, err = Utils.run_process(cmd, kw, cargs) except Exception as e: raise Errors.WafError('Execution failure: %s' % str(e), ex=e) if not isinstance(out, str): out = out.decode(encoding, errors='replace') if not isinstance(err, str): err = err.decode(encoding, errors='replace') if out and quiet != STDOUT and quiet != BOTH: self.to_log('out: %s' % out) if err and quiet != STDERR and quiet != BOTH: self.to_log('err: %s' % err) if ret: e = Errors.WafError('Command %r returned %r' % (cmd, ret)) e.returncode = ret e.stderr = err e.stdout = out raise e if to_ret == BOTH: return (out, err) elif to_ret == STDERR: return err return out def fatal(self, msg, ex=None): """ Prints an error message in red and stops command execution; this is usually used in the configuration section:: def configure(conf): conf.fatal('a requirement is missing') :param msg: message to display :type msg: string :param ex: optional exception object :type ex: exception :raises: :py:class:`waflib.Errors.ConfigurationError` """ if self.logger: self.logger.info('from %s: %s' % (self.path.abspath(), msg)) try: logfile = self.logger.handlers[0].baseFilename except AttributeError: pass else: if os.environ.get('WAF_PRINT_FAILURE_LOG'): # see #1930 msg = 'Log from (%s):\n%s\n' % (logfile, Utils.readf(logfile)) else: msg = '%s\n(complete log in %s)' % (msg, logfile) raise self.errors.ConfigurationError(msg, ex=ex) def to_log(self, msg): """ Logs information to the logger (if present), or to stderr. Empty messages are not printed:: def build(bld): bld.to_log('starting the build') Provide a logger on the context class or override this method if necessary. :param msg: message :type msg: string """ if not msg: return if self.logger: self.logger.info(msg) else: sys.stderr.write(str(msg)) sys.stderr.flush() def msg(self, *k, **kw): """ Prints a configuration message of the form ``msg: result``. The second part of the message will be in colors. The output can be disabled easly by setting ``in_msg`` to a positive value:: def configure(conf): self.in_msg = 1 conf.msg('Checking for library foo', 'ok') # no output :param msg: message to display to the user :type msg: string :param result: result to display :type result: string or boolean :param color: color to use, see :py:const:`waflib.Logs.colors_lst` :type color: string """ try: msg = kw['msg'] except KeyError: msg = k[0] self.start_msg(msg, **kw) try: result = kw['result'] except KeyError: result = k[1] color = kw.get('color') if not isinstance(color, str): color = result and 'GREEN' or 'YELLOW' self.end_msg(result, color, **kw) def start_msg(self, *k, **kw): """ Prints the beginning of a 'Checking for xxx' message. See :py:meth:`waflib.Context.Context.msg` """ if kw.get('quiet'): return msg = kw.get('msg') or k[0] try: if self.in_msg: self.in_msg += 1 return except AttributeError: self.in_msg = 0 self.in_msg += 1 try: self.line_just = max(self.line_just, len(msg)) except AttributeError: self.line_just = max(40, len(msg)) for x in (self.line_just * '-', msg): self.to_log(x) Logs.pprint('NORMAL', "%s :" % msg.ljust(self.line_just), sep='') def end_msg(self, *k, **kw): """Prints the end of a 'Checking for' message. See :py:meth:`waflib.Context.Context.msg`""" if kw.get('quiet'): return self.in_msg -= 1 if self.in_msg: return result = kw.get('result') or k[0] defcolor = 'GREEN' if result is True: msg = 'ok' elif not result: msg = 'not found' defcolor = 'YELLOW' else: msg = str(result) self.to_log(msg) try: color = kw['color'] except KeyError: if len(k) > 1 and k[1] in Logs.colors_lst: # compatibility waf 1.7 color = k[1] else: color = defcolor Logs.pprint(color, msg) def load_special_tools(self, var, ban=[]): """ Loads third-party extensions modules for certain programming languages by trying to list certain files in the extras/ directory. This method is typically called once for a programming language group, see for example :py:mod:`waflib.Tools.compiler_c` :param var: glob expression, for example 'cxx\\_\\*.py' :type var: string :param ban: list of exact file names to exclude :type ban: list of string """ if os.path.isdir(waf_dir): lst = self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var) for x in lst: if not x.name in ban: load_tool(x.name.replace('.py', '')) else: from zipfile import PyZipFile waflibs = PyZipFile(waf_dir) lst = waflibs.namelist() for x in lst: if not re.match('waflib/extras/%s' % var.replace('*', '.*'), var): continue f = os.path.basename(x) doban = False for b in ban: r = b.replace('*', '.*') if re.match(r, f): doban = True if not doban: f = f.replace('.py', '') load_tool(f) cache_modules = {} """ Dictionary holding already loaded modules (wscript), indexed by their absolute path. The modules are added automatically by :py:func:`waflib.Context.load_module` """ def load_module(path, encoding=None): """ Loads a wscript file as a python module. This method caches results in :py:attr:`waflib.Context.cache_modules` :param path: file path :type path: string :return: Loaded Python module :rtype: module """ try: return cache_modules[path] except KeyError: pass module = imp.new_module(WSCRIPT_FILE) try: code = Utils.readf(path, m='r', encoding=encoding) except EnvironmentError: raise Errors.WafError('Could not read the file %r' % path) module_dir = os.path.dirname(path) sys.path.insert(0, module_dir) try: exec(compile(code, path, 'exec'), module.__dict__) finally: sys.path.remove(module_dir) cache_modules[path] = module return module def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): """ Imports a Waf tool as a python module, and stores it in the dict :py:const:`waflib.Context.Context.tools` :type tool: string :param tool: Name of the tool :type tooldir: list :param tooldir: List of directories to search for the tool module :type with_sys_path: boolean :param with_sys_path: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs """ if tool == 'java': tool = 'javaw' # jython else: tool = tool.replace('++', 'xx') if not with_sys_path: back_path = sys.path sys.path = [] try: if tooldir: assert isinstance(tooldir, list) sys.path = tooldir + sys.path try: __import__(tool) except ImportError as e: e.waf_sys_path = list(sys.path) raise finally: for d in tooldir: sys.path.remove(d) ret = sys.modules[tool] Context.tools[tool] = ret return ret else: if not with_sys_path: sys.path.insert(0, waf_dir) try: for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): try: __import__(x % tool) break except ImportError: x = None else: # raise an exception __import__(tool) except ImportError as e: e.waf_sys_path = list(sys.path) raise finally: if not with_sys_path: sys.path.remove(waf_dir) ret = sys.modules[x % tool] Context.tools[tool] = ret return ret finally: if not with_sys_path: sys.path += back_path ldb-2.0.8/third_party/waf/waflib/Errors.py0000660000000000000000000000326113573675414020437 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010-2018 (ita) """ Exceptions used in the Waf code """ import traceback, sys class WafError(Exception): """Base class for all Waf errors""" def __init__(self, msg='', ex=None): """ :param msg: error message :type msg: string :param ex: exception causing this error (optional) :type ex: exception """ Exception.__init__(self) self.msg = msg assert not isinstance(msg, Exception) self.stack = [] if ex: if not msg: self.msg = str(ex) if isinstance(ex, WafError): self.stack = ex.stack else: self.stack = traceback.extract_tb(sys.exc_info()[2]) self.stack += traceback.extract_stack()[:-1] self.verbose_msg = ''.join(traceback.format_list(self.stack)) def __str__(self): return str(self.msg) class BuildError(WafError): """Error raised during the build and install phases""" def __init__(self, error_tasks=[]): """ :param error_tasks: tasks that could not complete normally :type error_tasks: list of task objects """ self.tasks = error_tasks WafError.__init__(self, self.format_error()) def format_error(self): """Formats the error messages from the tasks that failed""" lst = ['Build failed'] for tsk in self.tasks: txt = tsk.format_error() if txt: lst.append(txt) return '\n'.join(lst) class ConfigurationError(WafError): """Configuration exception raised in particular by :py:meth:`waflib.Context.Context.fatal`""" pass class TaskRescan(WafError): """Task-specific exception type signalling required signature recalculations""" pass class TaskNotReady(WafError): """Task-specific exception type signalling that task signatures cannot be computed""" pass ldb-2.0.8/third_party/waf/waflib/Logs.py0000660000000000000000000002303313573675414020066 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ logging, colors, terminal width and pretty-print """ import os, re, traceback, sys from waflib import Utils, ansiterm if not os.environ.get('NOSYNC', False): # synchronized output is nearly mandatory to prevent garbled output if sys.stdout.isatty() and id(sys.stdout) == id(sys.__stdout__): sys.stdout = ansiterm.AnsiTerm(sys.stdout) if sys.stderr.isatty() and id(sys.stderr) == id(sys.__stderr__): sys.stderr = ansiterm.AnsiTerm(sys.stderr) # import the logging module after since it holds a reference on sys.stderr # in case someone uses the root logger import logging LOG_FORMAT = os.environ.get('WAF_LOG_FORMAT', '%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s') HOUR_FORMAT = os.environ.get('WAF_HOUR_FORMAT', '%H:%M:%S') zones = [] """ See :py:class:`waflib.Logs.log_filter` """ verbose = 0 """ Global verbosity level, see :py:func:`waflib.Logs.debug` and :py:func:`waflib.Logs.error` """ colors_lst = { 'USE' : True, 'BOLD' :'\x1b[01;1m', 'RED' :'\x1b[01;31m', 'GREEN' :'\x1b[32m', 'YELLOW':'\x1b[33m', 'PINK' :'\x1b[35m', 'BLUE' :'\x1b[01;34m', 'CYAN' :'\x1b[36m', 'GREY' :'\x1b[37m', 'NORMAL':'\x1b[0m', 'cursor_on' :'\x1b[?25h', 'cursor_off' :'\x1b[?25l', } indicator = '\r\x1b[K%s%s%s' try: unicode except NameError: unicode = None def enable_colors(use): """ If *1* is given, then the system will perform a few verifications before enabling colors, such as checking whether the interpreter is running in a terminal. A value of zero will disable colors, and a value above *1* will force colors. :param use: whether to enable colors or not :type use: integer """ if use == 1: if not (sys.stderr.isatty() or sys.stdout.isatty()): use = 0 if Utils.is_win32 and os.name != 'java': term = os.environ.get('TERM', '') # has ansiterm else: term = os.environ.get('TERM', 'dumb') if term in ('dumb', 'emacs'): use = 0 if use >= 1: os.environ['TERM'] = 'vt100' colors_lst['USE'] = use # If console packages are available, replace the dummy function with a real # implementation try: get_term_cols = ansiterm.get_term_cols except AttributeError: def get_term_cols(): return 80 get_term_cols.__doc__ = """ Returns the console width in characters. :return: the number of characters per line :rtype: int """ def get_color(cl): """ Returns the ansi sequence corresponding to the given color name. An empty string is returned when coloring is globally disabled. :param cl: color name in capital letters :type cl: string """ if colors_lst['USE']: return colors_lst.get(cl, '') return '' class color_dict(object): """attribute-based color access, eg: colors.PINK""" def __getattr__(self, a): return get_color(a) def __call__(self, a): return get_color(a) colors = color_dict() re_log = re.compile(r'(\w+): (.*)', re.M) class log_filter(logging.Filter): """ Waf logs are of the form 'name: message', and can be filtered by 'waf --zones=name'. For example, the following:: from waflib import Logs Logs.debug('test: here is a message') Will be displayed only when executing:: $ waf --zones=test """ def __init__(self, name=''): logging.Filter.__init__(self, name) def filter(self, rec): """ Filters log records by zone and by logging level :param rec: log entry """ rec.zone = rec.module if rec.levelno >= logging.INFO: return True m = re_log.match(rec.msg) if m: rec.zone = m.group(1) rec.msg = m.group(2) if zones: return getattr(rec, 'zone', '') in zones or '*' in zones elif not verbose > 2: return False return True class log_handler(logging.StreamHandler): """Dispatches messages to stderr/stdout depending on the severity level""" def emit(self, record): """ Delegates the functionality to :py:meth:`waflib.Log.log_handler.emit_override` """ # default implementation try: try: self.stream = record.stream except AttributeError: if record.levelno >= logging.WARNING: record.stream = self.stream = sys.stderr else: record.stream = self.stream = sys.stdout self.emit_override(record) self.flush() except (KeyboardInterrupt, SystemExit): raise except: # from the python library -_- self.handleError(record) def emit_override(self, record, **kw): """ Writes the log record to the desired stream (stderr/stdout) """ self.terminator = getattr(record, 'terminator', '\n') stream = self.stream if unicode: # python2 msg = self.formatter.format(record) fs = '%s' + self.terminator try: if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): fs = fs.decode(stream.encoding) try: stream.write(fs % msg) except UnicodeEncodeError: stream.write((fs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: stream.write((fs % msg).encode('utf-8')) else: logging.StreamHandler.emit(self, record) class formatter(logging.Formatter): """Simple log formatter which handles colors""" def __init__(self): logging.Formatter.__init__(self, LOG_FORMAT, HOUR_FORMAT) def format(self, rec): """ Formats records and adds colors as needed. The records do not get a leading hour format if the logging level is above *INFO*. """ try: msg = rec.msg.decode('utf-8') except Exception: msg = rec.msg use = colors_lst['USE'] if (use == 1 and rec.stream.isatty()) or use == 2: c1 = getattr(rec, 'c1', None) if c1 is None: c1 = '' if rec.levelno >= logging.ERROR: c1 = colors.RED elif rec.levelno >= logging.WARNING: c1 = colors.YELLOW elif rec.levelno >= logging.INFO: c1 = colors.GREEN c2 = getattr(rec, 'c2', colors.NORMAL) msg = '%s%s%s' % (c1, msg, c2) else: # remove single \r that make long lines in text files # and other terminal commands msg = re.sub(r'\r(?!\n)|\x1B\[(K|.*?(m|h|l))', '', msg) if rec.levelno >= logging.INFO: # the goal of this is to format without the leading "Logs, hour" prefix if rec.args: try: return msg % rec.args except UnicodeDecodeError: return msg.encode('utf-8') % rec.args return msg rec.msg = msg rec.c1 = colors.PINK rec.c2 = colors.NORMAL return logging.Formatter.format(self, rec) log = None """global logger for Logs.debug, Logs.error, etc""" def debug(*k, **kw): """ Wraps logging.debug and discards messages if the verbosity level :py:attr:`waflib.Logs.verbose` ≤ 0 """ if verbose: k = list(k) k[0] = k[0].replace('\n', ' ') log.debug(*k, **kw) def error(*k, **kw): """ Wrap logging.errors, adds the stack trace when the verbosity level :py:attr:`waflib.Logs.verbose` ≥ 2 """ log.error(*k, **kw) if verbose > 2: st = traceback.extract_stack() if st: st = st[:-1] buf = [] for filename, lineno, name, line in st: buf.append(' File %r, line %d, in %s' % (filename, lineno, name)) if line: buf.append(' %s' % line.strip()) if buf: log.error('\n'.join(buf)) def warn(*k, **kw): """ Wraps logging.warning """ log.warning(*k, **kw) def info(*k, **kw): """ Wraps logging.info """ log.info(*k, **kw) def init_log(): """ Initializes the logger :py:attr:`waflib.Logs.log` """ global log log = logging.getLogger('waflib') log.handlers = [] log.filters = [] hdlr = log_handler() hdlr.setFormatter(formatter()) log.addHandler(hdlr) log.addFilter(log_filter()) log.setLevel(logging.DEBUG) def make_logger(path, name): """ Creates a simple logger, which is often used to redirect the context command output:: from waflib import Logs bld.logger = Logs.make_logger('test.log', 'build') bld.check(header_name='sadlib.h', features='cxx cprogram', mandatory=False) # have the file closed immediately Logs.free_logger(bld.logger) # stop logging bld.logger = None The method finalize() of the command will try to free the logger, if any :param path: file name to write the log output to :type path: string :param name: logger name (loggers are reused) :type name: string """ logger = logging.getLogger(name) if sys.hexversion > 0x3000000: encoding = sys.stdout.encoding else: encoding = None hdlr = logging.FileHandler(path, 'w', encoding=encoding) formatter = logging.Formatter('%(message)s') hdlr.setFormatter(formatter) logger.addHandler(hdlr) logger.setLevel(logging.DEBUG) return logger def make_mem_logger(name, to_log, size=8192): """ Creates a memory logger to avoid writing concurrently to the main logger """ from logging.handlers import MemoryHandler logger = logging.getLogger(name) hdlr = MemoryHandler(size, target=to_log) formatter = logging.Formatter('%(message)s') hdlr.setFormatter(formatter) logger.addHandler(hdlr) logger.memhandler = hdlr logger.setLevel(logging.DEBUG) return logger def free_logger(logger): """ Frees the resources held by the loggers created through make_logger or make_mem_logger. This is used for file cleanup and for handler removal (logger objects are re-used). """ try: for x in logger.handlers: x.close() logger.removeHandler(x) except Exception: pass def pprint(col, msg, label='', sep='\n'): """ Prints messages in color immediately on stderr:: from waflib import Logs Logs.pprint('RED', 'Something bad just happened') :param col: color name to use in :py:const:`Logs.colors_lst` :type col: string :param msg: message to display :type msg: string or a value that can be printed by %s :param label: a message to add after the colored output :type label: string :param sep: a string to append at the end (line separator) :type sep: string """ info('%s%s%s %s', colors(col), msg, colors.NORMAL, label, extra={'terminator':sep}) ldb-2.0.8/third_party/waf/waflib/Node.py0000660000000000000000000006162513573675414020060 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Node: filesystem structure #. Each file/folder is represented by exactly one node. #. Some potential class properties are stored on :py:class:`waflib.Build.BuildContext` : nodes to depend on, etc. Unused class members can increase the `.wafpickle` file size sensibly. #. Node objects should never be created directly, use the methods :py:func:`Node.make_node` or :py:func:`Node.find_node` for the low-level operations #. The methods :py:func:`Node.find_resource`, :py:func:`Node.find_dir` :py:func:`Node.find_or_declare` must be used when a build context is present #. Each instance of :py:class:`waflib.Context.Context` has a unique :py:class:`Node` subclass required for serialization. (:py:class:`waflib.Node.Nod3`, see the :py:class:`waflib.Context.Context` initializer). A reference to the context owning a node is held as *self.ctx* """ import os, re, sys, shutil from waflib import Utils, Errors exclude_regs = ''' **/*~ **/#*# **/.#* **/%*% **/._* **/*.swp **/CVS **/CVS/** **/.cvsignore **/SCCS **/SCCS/** **/vssver.scc **/.svn **/.svn/** **/BitKeeper **/.git **/.git/** **/.gitignore **/.bzr **/.bzrignore **/.bzr/** **/.hg **/.hg/** **/_MTN **/_MTN/** **/.arch-ids **/{arch} **/_darcs **/_darcs/** **/.intlcache **/.DS_Store''' """ Ant patterns for files and folders to exclude while doing the recursive traversal in :py:meth:`waflib.Node.Node.ant_glob` """ def ant_matcher(s, ignorecase): reflags = re.I if ignorecase else 0 ret = [] for x in Utils.to_list(s): x = x.replace('\\', '/').replace('//', '/') if x.endswith('/'): x += '**' accu = [] for k in x.split('/'): if k == '**': accu.append(k) else: k = k.replace('.', '[.]').replace('*', '.*').replace('?', '.').replace('+', '\\+') k = '^%s$' % k try: exp = re.compile(k, flags=reflags) except Exception as e: raise Errors.WafError('Invalid pattern: %s' % k, e) else: accu.append(exp) ret.append(accu) return ret def ant_sub_filter(name, nn): ret = [] for lst in nn: if not lst: pass elif lst[0] == '**': ret.append(lst) if len(lst) > 1: if lst[1].match(name): ret.append(lst[2:]) else: ret.append([]) elif lst[0].match(name): ret.append(lst[1:]) return ret def ant_sub_matcher(name, pats): nacc = ant_sub_filter(name, pats[0]) nrej = ant_sub_filter(name, pats[1]) if [] in nrej: nacc = [] return [nacc, nrej] class Node(object): """ This class is organized in two parts: * The basic methods meant for filesystem access (compute paths, create folders, etc) * The methods bound to a :py:class:`waflib.Build.BuildContext` (require ``bld.srcnode`` and ``bld.bldnode``) """ dict_class = dict """ Subclasses can provide a dict class to enable case insensitivity for example. """ __slots__ = ('name', 'parent', 'children', 'cache_abspath', 'cache_isdir') def __init__(self, name, parent): """ .. note:: Use :py:func:`Node.make_node` or :py:func:`Node.find_node` instead of calling this constructor """ self.name = name self.parent = parent if parent: if name in parent.children: raise Errors.WafError('node %s exists in the parent files %r already' % (name, parent)) parent.children[name] = self def __setstate__(self, data): "Deserializes node information, used for persistence" self.name = data[0] self.parent = data[1] if data[2] is not None: # Issue 1480 self.children = self.dict_class(data[2]) def __getstate__(self): "Serializes node information, used for persistence" return (self.name, self.parent, getattr(self, 'children', None)) def __str__(self): """ String representation (abspath), for debugging purposes :rtype: string """ return self.abspath() def __repr__(self): """ String representation (abspath), for debugging purposes :rtype: string """ return self.abspath() def __copy__(self): """ Provided to prevent nodes from being copied :raises: :py:class:`waflib.Errors.WafError` """ raise Errors.WafError('nodes are not supposed to be copied') def read(self, flags='r', encoding='latin-1'): """ Reads and returns the contents of the file represented by this node, see :py:func:`waflib.Utils.readf`:: def build(bld): bld.path.find_node('wscript').read() :param flags: Open mode :type flags: string :param encoding: encoding value for Python3 :type encoding: string :rtype: string or bytes :return: File contents """ return Utils.readf(self.abspath(), flags, encoding) def write(self, data, flags='w', encoding='latin-1'): """ Writes data to the file represented by this node, see :py:func:`waflib.Utils.writef`:: def build(bld): bld.path.make_node('foo.txt').write('Hello, world!') :param data: data to write :type data: string :param flags: Write mode :type flags: string :param encoding: encoding value for Python3 :type encoding: string """ Utils.writef(self.abspath(), data, flags, encoding) def read_json(self, convert=True, encoding='utf-8'): """ Reads and parses the contents of this node as JSON (Python ≥ 2.6):: def build(bld): bld.path.find_node('abc.json').read_json() Note that this by default automatically decodes unicode strings on Python2, unlike what the Python JSON module does. :type convert: boolean :param convert: Prevents decoding of unicode strings on Python2 :type encoding: string :param encoding: The encoding of the file to read. This default to UTF8 as per the JSON standard :rtype: object :return: Parsed file contents """ import json # Python 2.6 and up object_pairs_hook = None if convert and sys.hexversion < 0x3000000: try: _type = unicode except NameError: _type = str def convert(value): if isinstance(value, list): return [convert(element) for element in value] elif isinstance(value, _type): return str(value) else: return value def object_pairs(pairs): return dict((str(pair[0]), convert(pair[1])) for pair in pairs) object_pairs_hook = object_pairs return json.loads(self.read(encoding=encoding), object_pairs_hook=object_pairs_hook) def write_json(self, data, pretty=True): """ Writes a python object as JSON to disk (Python ≥ 2.6) as UTF-8 data (JSON standard):: def build(bld): bld.path.find_node('xyz.json').write_json(199) :type data: object :param data: The data to write to disk :type pretty: boolean :param pretty: Determines if the JSON will be nicely space separated """ import json # Python 2.6 and up indent = 2 separators = (',', ': ') sort_keys = pretty newline = os.linesep if not pretty: indent = None separators = (',', ':') newline = '' output = json.dumps(data, indent=indent, separators=separators, sort_keys=sort_keys) + newline self.write(output, encoding='utf-8') def exists(self): """ Returns whether the Node is present on the filesystem :rtype: bool """ return os.path.exists(self.abspath()) def isdir(self): """ Returns whether the Node represents a folder :rtype: bool """ return os.path.isdir(self.abspath()) def chmod(self, val): """ Changes the file/dir permissions:: def build(bld): bld.path.chmod(493) # 0755 """ os.chmod(self.abspath(), val) def delete(self, evict=True): """ Removes the file/folder from the filesystem (equivalent to `rm -rf`), and remove this object from the Node tree. Do not use this object after calling this method. """ try: try: if os.path.isdir(self.abspath()): shutil.rmtree(self.abspath()) else: os.remove(self.abspath()) except OSError: if os.path.exists(self.abspath()): raise finally: if evict: self.evict() def evict(self): """ Removes this node from the Node tree """ del self.parent.children[self.name] def suffix(self): """ Returns the file rightmost extension, for example `a.b.c.d → .d` :rtype: string """ k = max(0, self.name.rfind('.')) return self.name[k:] def height(self): """ Returns the depth in the folder hierarchy from the filesystem root or from all the file drives :returns: filesystem depth :rtype: integer """ d = self val = -1 while d: d = d.parent val += 1 return val def listdir(self): """ Lists the folder contents :returns: list of file/folder names ordered alphabetically :rtype: list of string """ lst = Utils.listdir(self.abspath()) lst.sort() return lst def mkdir(self): """ Creates a folder represented by this node. Intermediate folders are created as needed. :raises: :py:class:`waflib.Errors.WafError` when the folder is missing """ if self.isdir(): return try: self.parent.mkdir() except OSError: pass if self.name: try: os.makedirs(self.abspath()) except OSError: pass if not self.isdir(): raise Errors.WafError('Could not create the directory %r' % self) try: self.children except AttributeError: self.children = self.dict_class() def find_node(self, lst): """ Finds a node on the file system (files or folders), and creates the corresponding Node objects if it exists :param lst: relative path :type lst: string or list of string :returns: The corresponding Node object or None if no entry was found on the filesystem :rtype: :py:class:´waflib.Node.Node´ """ if isinstance(lst, str): lst = [x for x in Utils.split_path(lst) if x and x != '.'] if lst and lst[0].startswith('\\\\') and not self.parent: node = self.ctx.root.make_node(lst[0]) node.cache_isdir = True return node.find_node(lst[1:]) cur = self for x in lst: if x == '..': cur = cur.parent or cur continue try: ch = cur.children except AttributeError: cur.children = self.dict_class() else: try: cur = ch[x] continue except KeyError: pass # optimistic: create the node first then look if it was correct to do so cur = self.__class__(x, cur) if not cur.exists(): cur.evict() return None if not cur.exists(): cur.evict() return None return cur def make_node(self, lst): """ Returns or creates a Node object corresponding to the input path without considering the filesystem. :param lst: relative path :type lst: string or list of string :rtype: :py:class:´waflib.Node.Node´ """ if isinstance(lst, str): lst = [x for x in Utils.split_path(lst) if x and x != '.'] cur = self for x in lst: if x == '..': cur = cur.parent or cur continue try: cur = cur.children[x] except AttributeError: cur.children = self.dict_class() except KeyError: pass else: continue cur = self.__class__(x, cur) return cur def search_node(self, lst): """ Returns a Node previously defined in the data structure. The filesystem is not considered. :param lst: relative path :type lst: string or list of string :rtype: :py:class:´waflib.Node.Node´ or None if there is no entry in the Node datastructure """ if isinstance(lst, str): lst = [x for x in Utils.split_path(lst) if x and x != '.'] cur = self for x in lst: if x == '..': cur = cur.parent or cur else: try: cur = cur.children[x] except (AttributeError, KeyError): return None return cur def path_from(self, node): """ Path of this node seen from the other:: def build(bld): n1 = bld.path.find_node('foo/bar/xyz.txt') n2 = bld.path.find_node('foo/stuff/') n1.path_from(n2) # '../bar/xyz.txt' :param node: path to use as a reference :type node: :py:class:`waflib.Node.Node` :returns: a relative path or an absolute one if that is better :rtype: string """ c1 = self c2 = node c1h = c1.height() c2h = c2.height() lst = [] up = 0 while c1h > c2h: lst.append(c1.name) c1 = c1.parent c1h -= 1 while c2h > c1h: up += 1 c2 = c2.parent c2h -= 1 while not c1 is c2: lst.append(c1.name) up += 1 c1 = c1.parent c2 = c2.parent if c1.parent: lst.extend(['..'] * up) lst.reverse() return os.sep.join(lst) or '.' else: return self.abspath() def abspath(self): """ Returns the absolute path. A cache is kept in the context as ``cache_node_abspath`` :rtype: string """ try: return self.cache_abspath except AttributeError: pass # think twice before touching this (performance + complexity + correctness) if not self.parent: val = os.sep elif not self.parent.name: val = os.sep + self.name else: val = self.parent.abspath() + os.sep + self.name self.cache_abspath = val return val if Utils.is_win32: def abspath(self): try: return self.cache_abspath except AttributeError: pass if not self.parent: val = '' elif not self.parent.name: val = self.name + os.sep else: val = self.parent.abspath().rstrip(os.sep) + os.sep + self.name self.cache_abspath = val return val def is_child_of(self, node): """ Returns whether the object belongs to a subtree of the input node:: def build(bld): node = bld.path.find_node('wscript') node.is_child_of(bld.path) # True :param node: path to use as a reference :type node: :py:class:`waflib.Node.Node` :rtype: bool """ p = self diff = self.height() - node.height() while diff > 0: diff -= 1 p = p.parent return p is node def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True, quiet=False): """ Recursive method used by :py:meth:`waflib.Node.ant_glob`. :param accept: function used for accepting/rejecting a node, returns the patterns that can be still accepted in recursion :type accept: function :param maxdepth: maximum depth in the filesystem (25) :type maxdepth: int :param pats: list of patterns to accept and list of patterns to exclude :type pats: tuple :param dir: return folders too (False by default) :type dir: bool :param src: return files (True by default) :type src: bool :param remove: remove files/folders that do not exist (True by default) :type remove: bool :param quiet: disable build directory traversal warnings (verbose mode) :type quiet: bool :returns: A generator object to iterate from :rtype: iterator """ dircont = self.listdir() try: lst = set(self.children.keys()) except AttributeError: self.children = self.dict_class() else: if remove: for x in lst - set(dircont): self.children[x].evict() for name in dircont: npats = accept(name, pats) if npats and npats[0]: accepted = [] in npats[0] node = self.make_node([name]) isdir = node.isdir() if accepted: if isdir: if dir: yield node elif src: yield node if isdir: node.cache_isdir = True if maxdepth: for k in node.ant_iter(accept=accept, maxdepth=maxdepth - 1, pats=npats, dir=dir, src=src, remove=remove, quiet=quiet): yield k def ant_glob(self, *k, **kw): """ Finds files across folders and returns Node objects: * ``**/*`` find all files recursively * ``**/*.class`` find all files ending by .class * ``..`` find files having two dot characters For example:: def configure(cfg): # find all .cpp files cfg.path.ant_glob('**/*.cpp') # find particular files from the root filesystem (can be slow) cfg.root.ant_glob('etc/*.txt') # simple exclusion rule example cfg.path.ant_glob('*.c*', excl=['*.c'], src=True, dir=False) For more information about the patterns, consult http://ant.apache.org/manual/dirtasks.html Please remember that the '..' sequence does not represent the parent directory:: def configure(cfg): cfg.path.ant_glob('../*.h') # incorrect cfg.path.parent.ant_glob('*.h') # correct The Node structure is itself a filesystem cache, so certain precautions must be taken while matching files in the build or installation phases. Nodes objects that do have a corresponding file or folder are garbage-collected by default. This garbage collection is usually required to prevent returning files that do not exist anymore. Yet, this may also remove Node objects of files that are yet-to-be built. This typically happens when trying to match files in the build directory, but there are also cases when files are created in the source directory. Run ``waf -v`` to display any warnings, and try consider passing ``remove=False`` when matching files in the build directory. Since ant_glob can traverse both source and build folders, it is a best practice to call this method only from the most specific build node:: def build(bld): # traverses the build directory, may need ``remove=False``: bld.path.ant_glob('project/dir/**/*.h') # better, no accidental build directory traversal: bld.path.find_node('project/dir').ant_glob('**/*.h') # best In addition, files and folders are listed immediately. When matching files in the build folders, consider passing ``generator=True`` so that the generator object returned can defer computation to a later stage. For example:: def build(bld): bld(rule='tar xvf ${SRC}', source='arch.tar') bld.add_group() gen = bld.bldnode.ant_glob("*.h", generator=True, remove=True) # files will be listed only after the arch.tar is unpacked bld(rule='ls ${SRC}', source=gen, name='XYZ') :param incl: ant patterns or list of patterns to include :type incl: string or list of strings :param excl: ant patterns or list of patterns to exclude :type excl: string or list of strings :param dir: return folders too (False by default) :type dir: bool :param src: return files (True by default) :type src: bool :param maxdepth: maximum depth of recursion :type maxdepth: int :param ignorecase: ignore case while matching (False by default) :type ignorecase: bool :param generator: Whether to evaluate the Nodes lazily :type generator: bool :param remove: remove files/folders that do not exist (True by default) :type remove: bool :param quiet: disable build directory traversal warnings (verbose mode) :type quiet: bool :returns: The corresponding Node objects as a list or as a generator object (generator=True) :rtype: by default, list of :py:class:`waflib.Node.Node` instances """ src = kw.get('src', True) dir = kw.get('dir') excl = kw.get('excl', exclude_regs) incl = k and k[0] or kw.get('incl', '**') remove = kw.get('remove', True) maxdepth = kw.get('maxdepth', 25) ignorecase = kw.get('ignorecase', False) quiet = kw.get('quiet', False) pats = (ant_matcher(incl, ignorecase), ant_matcher(excl, ignorecase)) if kw.get('generator'): return Utils.lazy_generator(self.ant_iter, (ant_sub_matcher, maxdepth, pats, dir, src, remove, quiet)) it = self.ant_iter(ant_sub_matcher, maxdepth, pats, dir, src, remove, quiet) if kw.get('flat'): # returns relative paths as a space-delimited string # prefer Node objects whenever possible return ' '.join(x.path_from(self) for x in it) return list(it) # ---------------------------------------------------------------------------- # the methods below require the source/build folders (bld.srcnode/bld.bldnode) def is_src(self): """ Returns True if the node is below the source directory. Note that ``!is_src() ≠ is_bld()`` :rtype: bool """ cur = self x = self.ctx.srcnode y = self.ctx.bldnode while cur.parent: if cur is y: return False if cur is x: return True cur = cur.parent return False def is_bld(self): """ Returns True if the node is below the build directory. Note that ``!is_bld() ≠ is_src()`` :rtype: bool """ cur = self y = self.ctx.bldnode while cur.parent: if cur is y: return True cur = cur.parent return False def get_src(self): """ Returns the corresponding Node object in the source directory (or self if already under the source directory). Use this method only if the purpose is to create a Node object (this is common with folders but not with files, see ticket 1937) :rtype: :py:class:`waflib.Node.Node` """ cur = self x = self.ctx.srcnode y = self.ctx.bldnode lst = [] while cur.parent: if cur is y: lst.reverse() return x.make_node(lst) if cur is x: return self lst.append(cur.name) cur = cur.parent return self def get_bld(self): """ Return the corresponding Node object in the build directory (or self if already under the build directory). Use this method only if the purpose is to create a Node object (this is common with folders but not with files, see ticket 1937) :rtype: :py:class:`waflib.Node.Node` """ cur = self x = self.ctx.srcnode y = self.ctx.bldnode lst = [] while cur.parent: if cur is y: return self if cur is x: lst.reverse() return self.ctx.bldnode.make_node(lst) lst.append(cur.name) cur = cur.parent # the file is external to the current project, make a fake root in the current build directory lst.reverse() if lst and Utils.is_win32 and len(lst[0]) == 2 and lst[0].endswith(':'): lst[0] = lst[0][0] return self.ctx.bldnode.make_node(['__root__'] + lst) def find_resource(self, lst): """ Use this method in the build phase to find source files corresponding to the relative path given. First it looks up the Node data structure to find any declared Node object in the build directory. If None is found, it then considers the filesystem in the source directory. :param lst: relative path :type lst: string or list of string :returns: the corresponding Node object or None :rtype: :py:class:`waflib.Node.Node` """ if isinstance(lst, str): lst = [x for x in Utils.split_path(lst) if x and x != '.'] node = self.get_bld().search_node(lst) if not node: node = self.get_src().find_node(lst) if node and node.isdir(): return None return node def find_or_declare(self, lst): """ Use this method in the build phase to declare output files which are meant to be written in the build directory. This method creates the Node object and its parent folder as needed. :param lst: relative path :type lst: string or list of string """ if isinstance(lst, str) and os.path.isabs(lst): node = self.ctx.root.make_node(lst) else: node = self.get_bld().make_node(lst) node.parent.mkdir() return node def find_dir(self, lst): """ Searches for a folder on the filesystem (see :py:meth:`waflib.Node.Node.find_node`) :param lst: relative path :type lst: string or list of string :returns: The corresponding Node object or None if there is no such folder :rtype: :py:class:`waflib.Node.Node` """ if isinstance(lst, str): lst = [x for x in Utils.split_path(lst) if x and x != '.'] node = self.find_node(lst) if node and not node.isdir(): return None return node # helpers for building things def change_ext(self, ext, ext_in=None): """ Declares a build node with a distinct extension; this is uses :py:meth:`waflib.Node.Node.find_or_declare` :return: A build node of the same path, but with a different extension :rtype: :py:class:`waflib.Node.Node` """ name = self.name if ext_in is None: k = name.rfind('.') if k >= 0: name = name[:k] + ext else: name = name + ext else: name = name[:- len(ext_in)] + ext return self.parent.find_or_declare([name]) def bldpath(self): """ Returns the relative path seen from the build directory ``src/foo.cpp`` :rtype: string """ return self.path_from(self.ctx.bldnode) def srcpath(self): """ Returns the relative path seen from the source directory ``../src/foo.cpp`` :rtype: string """ return self.path_from(self.ctx.srcnode) def relpath(self): """ If a file in the build directory, returns :py:meth:`waflib.Node.Node.bldpath`, else returns :py:meth:`waflib.Node.Node.srcpath` :rtype: string """ cur = self x = self.ctx.bldnode while cur.parent: if cur is x: return self.bldpath() cur = cur.parent return self.srcpath() def bld_dir(self): """ Equivalent to self.parent.bldpath() :rtype: string """ return self.parent.bldpath() def h_file(self): """ See :py:func:`waflib.Utils.h_file` :return: a hash representing the file contents :rtype: string or bytes """ return Utils.h_file(self.abspath()) def get_bld_sig(self): """ Returns a signature (see :py:meth:`waflib.Node.Node.h_file`) for the purpose of build dependency calculation. This method uses a per-context cache. :return: a hash representing the object contents :rtype: string or bytes """ # previous behaviour can be set by returning self.ctx.node_sigs[self] when a build node try: cache = self.ctx.cache_sig except AttributeError: cache = self.ctx.cache_sig = {} try: ret = cache[self] except KeyError: p = self.abspath() try: ret = cache[self] = self.h_file() except EnvironmentError: if self.isdir(): # allow folders as build nodes, do not use the creation time st = os.stat(p) ret = cache[self] = Utils.h_list([p, st.st_ino, st.st_mode]) return ret raise return ret pickle_lock = Utils.threading.Lock() """Lock mandatory for thread-safe node serialization""" class Nod3(Node): """Mandatory subclass for thread-safe node serialization""" pass # do not remove ldb-2.0.8/third_party/waf/waflib/Options.py0000660000000000000000000002611713573675414020623 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Scott Newton, 2005 (scottn) # Thomas Nagy, 2006-2018 (ita) """ Support for waf command-line options Provides default and command-line options, as well the command that reads the ``options`` wscript function. """ import os, tempfile, optparse, sys, re from waflib import Logs, Utils, Context, Errors options = optparse.Values() """ A global dictionary representing user-provided command-line options:: $ waf --foo=bar """ commands = [] """ List of commands to execute extracted from the command-line. This list is consumed during the execution by :py:func:`waflib.Scripting.run_commands`. """ envvars = [] """ List of environment variable declarations placed after the Waf executable name. These are detected by searching for "=" in the remaining arguments. You probably do not want to use this. """ lockfile = os.environ.get('WAFLOCK', '.lock-waf_%s_build' % sys.platform) """ Name of the lock file that marks a project as configured """ class opt_parser(optparse.OptionParser): """ Command-line options parser. """ def __init__(self, ctx, allow_unknown=False): optparse.OptionParser.__init__(self, conflict_handler='resolve', add_help_option=False, version='waf %s (%s)' % (Context.WAFVERSION, Context.WAFREVISION)) self.formatter.width = Logs.get_term_cols() self.ctx = ctx self.allow_unknown = allow_unknown def _process_args(self, largs, rargs, values): """ Custom _process_args to allow unknown options according to the allow_unknown status """ while rargs: try: optparse.OptionParser._process_args(self,largs,rargs,values) except (optparse.BadOptionError, optparse.AmbiguousOptionError) as e: if self.allow_unknown: largs.append(e.opt_str) else: self.error(str(e)) def print_usage(self, file=None): return self.print_help(file) def get_usage(self): """ Builds the message to print on ``waf --help`` :rtype: string """ cmds_str = {} for cls in Context.classes: if not cls.cmd or cls.cmd == 'options' or cls.cmd.startswith( '_' ): continue s = cls.__doc__ or '' cmds_str[cls.cmd] = s if Context.g_module: for (k, v) in Context.g_module.__dict__.items(): if k in ('options', 'init', 'shutdown'): continue if type(v) is type(Context.create_context): if v.__doc__ and not k.startswith('_'): cmds_str[k] = v.__doc__ just = 0 for k in cmds_str: just = max(just, len(k)) lst = [' %s: %s' % (k.ljust(just), v) for (k, v) in cmds_str.items()] lst.sort() ret = '\n'.join(lst) return '''waf [commands] [options] Main commands (example: ./waf build -j4) %s ''' % ret class OptionsContext(Context.Context): """ Collects custom options from wscript files and parses the command line. Sets the global :py:const:`waflib.Options.commands` and :py:const:`waflib.Options.options` values. """ cmd = 'options' fun = 'options' def __init__(self, **kw): super(OptionsContext, self).__init__(**kw) self.parser = opt_parser(self) """Instance of :py:class:`waflib.Options.opt_parser`""" self.option_groups = {} jobs = self.jobs() p = self.add_option color = os.environ.get('NOCOLOR', '') and 'no' or 'auto' if os.environ.get('CLICOLOR', '') == '0': color = 'no' elif os.environ.get('CLICOLOR_FORCE', '') == '1': color = 'yes' p('-c', '--color', dest='colors', default=color, action='store', help='whether to use colors (yes/no/auto) [default: auto]', choices=('yes', 'no', 'auto')) p('-j', '--jobs', dest='jobs', default=jobs, type='int', help='amount of parallel jobs (%r)' % jobs) p('-k', '--keep', dest='keep', default=0, action='count', help='continue despite errors (-kk to try harder)') p('-v', '--verbose', dest='verbose', default=0, action='count', help='verbosity level -v -vv or -vvv [default: 0]') p('--zones', dest='zones', default='', action='store', help='debugging zones (task_gen, deps, tasks, etc)') p('--profile', dest='profile', default=0, action='store_true', help=optparse.SUPPRESS_HELP) p('--pdb', dest='pdb', default=0, action='store_true', help=optparse.SUPPRESS_HELP) p('-h', '--help', dest='whelp', default=0, action='store_true', help="show this help message and exit") gr = self.add_option_group('Configuration options') self.option_groups['configure options'] = gr gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out') gr.add_option('-t', '--top', action='store', default='', help='src dir for the project', dest='top') gr.add_option('--no-lock-in-run', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_run') gr.add_option('--no-lock-in-out', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_out') gr.add_option('--no-lock-in-top', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_top') default_prefix = getattr(Context.g_module, 'default_prefix', os.environ.get('PREFIX')) if not default_prefix: if Utils.unversioned_sys_platform() == 'win32': d = tempfile.gettempdir() default_prefix = d[0].upper() + d[1:] # win32 preserves the case, but gettempdir does not else: default_prefix = '/usr/local/' gr.add_option('--prefix', dest='prefix', default=default_prefix, help='installation prefix [default: %r]' % default_prefix) gr.add_option('--bindir', dest='bindir', help='bindir') gr.add_option('--libdir', dest='libdir', help='libdir') gr = self.add_option_group('Build and installation options') self.option_groups['build and install options'] = gr gr.add_option('-p', '--progress', dest='progress_bar', default=0, action='count', help= '-p: progress bar; -pp: ide output') gr.add_option('--targets', dest='targets', default='', action='store', help='task generators, e.g. "target1,target2"') gr = self.add_option_group('Step options') self.option_groups['step options'] = gr gr.add_option('--files', dest='files', default='', action='store', help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"') default_destdir = os.environ.get('DESTDIR', '') gr = self.add_option_group('Installation and uninstallation options') self.option_groups['install/uninstall options'] = gr gr.add_option('--destdir', help='installation root [default: %r]' % default_destdir, default=default_destdir, dest='destdir') gr.add_option('-f', '--force', dest='force', default=False, action='store_true', help='force file installation') gr.add_option('--distcheck-args', metavar='ARGS', help='arguments to pass to distcheck', default=None, action='store') def jobs(self): """ Finds the optimal amount of cpu cores to use for parallel jobs. At runtime the options can be obtained from :py:const:`waflib.Options.options` :: from waflib.Options import options njobs = options.jobs :return: the amount of cpu cores :rtype: int """ count = int(os.environ.get('JOBS', 0)) if count < 1: if 'NUMBER_OF_PROCESSORS' in os.environ: # on Windows, use the NUMBER_OF_PROCESSORS environment variable count = int(os.environ.get('NUMBER_OF_PROCESSORS', 1)) else: # on everything else, first try the POSIX sysconf values if hasattr(os, 'sysconf_names'): if 'SC_NPROCESSORS_ONLN' in os.sysconf_names: count = int(os.sysconf('SC_NPROCESSORS_ONLN')) elif 'SC_NPROCESSORS_CONF' in os.sysconf_names: count = int(os.sysconf('SC_NPROCESSORS_CONF')) if not count and os.name not in ('nt', 'java'): try: tmp = self.cmd_and_log(['sysctl', '-n', 'hw.ncpu'], quiet=0) except Errors.WafError: pass else: if re.match('^[0-9]+$', tmp): count = int(tmp) if count < 1: count = 1 elif count > 1024: count = 1024 return count def add_option(self, *k, **kw): """ Wraps ``optparse.add_option``:: def options(ctx): ctx.add_option('-u', '--use', dest='use', default=False, action='store_true', help='a boolean option') :rtype: optparse option object """ return self.parser.add_option(*k, **kw) def add_option_group(self, *k, **kw): """ Wraps ``optparse.add_option_group``:: def options(ctx): gr = ctx.add_option_group('some options') gr.add_option('-u', '--use', dest='use', default=False, action='store_true') :rtype: optparse option group object """ try: gr = self.option_groups[k[0]] except KeyError: gr = self.parser.add_option_group(*k, **kw) self.option_groups[k[0]] = gr return gr def get_option_group(self, opt_str): """ Wraps ``optparse.get_option_group``:: def options(ctx): gr = ctx.get_option_group('configure options') gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out') :rtype: optparse option group object """ try: return self.option_groups[opt_str] except KeyError: for group in self.parser.option_groups: if group.title == opt_str: return group return None def sanitize_path(self, path, cwd=None): if not cwd: cwd = Context.launch_dir p = os.path.expanduser(path) p = os.path.join(cwd, p) p = os.path.normpath(p) p = os.path.abspath(p) return p def parse_cmd_args(self, _args=None, cwd=None, allow_unknown=False): """ Just parse the arguments """ self.parser.allow_unknown = allow_unknown (options, leftover_args) = self.parser.parse_args(args=_args) envvars = [] commands = [] for arg in leftover_args: if '=' in arg: envvars.append(arg) elif arg != 'options': commands.append(arg) for name in 'top out destdir prefix bindir libdir'.split(): # those paths are usually expanded from Context.launch_dir if getattr(options, name, None): path = self.sanitize_path(getattr(options, name), cwd) setattr(options, name, path) return options, commands, envvars def init_module_vars(self, arg_options, arg_commands, arg_envvars): options.__dict__.clear() del commands[:] del envvars[:] options.__dict__.update(arg_options.__dict__) commands.extend(arg_commands) envvars.extend(arg_envvars) for var in envvars: (name, value) = var.split('=', 1) os.environ[name.strip()] = value def init_logs(self, options, commands, envvars): Logs.verbose = options.verbose if options.verbose >= 1: self.load('errcheck') colors = {'yes' : 2, 'auto' : 1, 'no' : 0}[options.colors] Logs.enable_colors(colors) if options.zones: Logs.zones = options.zones.split(',') if not Logs.verbose: Logs.verbose = 1 elif Logs.verbose > 0: Logs.zones = ['runner'] if Logs.verbose > 2: Logs.zones = ['*'] def parse_args(self, _args=None): """ Parses arguments from a list which is not necessarily the command-line. Initializes the module variables options, commands and envvars If help is requested, prints it and exit the application :param _args: arguments :type _args: list of strings """ options, commands, envvars = self.parse_cmd_args() self.init_logs(options, commands, envvars) self.init_module_vars(options, commands, envvars) def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ super(OptionsContext, self).execute() self.parse_args() Utils.alloc_process_pool(options.jobs) ldb-2.0.8/third_party/waf/waflib/Runner.py0000660000000000000000000004001013573675414020425 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Runner.py: Task scheduling and execution """ import heapq, traceback try: from queue import Queue, PriorityQueue except ImportError: from Queue import Queue try: from Queue import PriorityQueue except ImportError: class PriorityQueue(Queue): def _init(self, maxsize): self.maxsize = maxsize self.queue = [] def _put(self, item): heapq.heappush(self.queue, item) def _get(self): return heapq.heappop(self.queue) from waflib import Utils, Task, Errors, Logs GAP = 5 """ Wait for at least ``GAP * njobs`` before trying to enqueue more tasks to run """ class PriorityTasks(object): def __init__(self): self.lst = [] def __len__(self): return len(self.lst) def __iter__(self): return iter(self.lst) def __str__(self): return 'PriorityTasks: [%s]' % '\n '.join(str(x) for x in self.lst) def clear(self): self.lst = [] def append(self, task): heapq.heappush(self.lst, task) def appendleft(self, task): "Deprecated, do not use" heapq.heappush(self.lst, task) def pop(self): return heapq.heappop(self.lst) def extend(self, lst): if self.lst: for x in lst: self.append(x) else: if isinstance(lst, list): self.lst = lst heapq.heapify(lst) else: self.lst = lst.lst class Consumer(Utils.threading.Thread): """ Daemon thread object that executes a task. It shares a semaphore with the coordinator :py:class:`waflib.Runner.Spawner`. There is one instance per task to consume. """ def __init__(self, spawner, task): Utils.threading.Thread.__init__(self) self.task = task """Task to execute""" self.spawner = spawner """Coordinator object""" self.setDaemon(1) self.start() def run(self): """ Processes a single task """ try: if not self.spawner.master.stop: self.spawner.master.process_task(self.task) finally: self.spawner.sem.release() self.spawner.master.out.put(self.task) self.task = None self.spawner = None class Spawner(Utils.threading.Thread): """ Daemon thread that consumes tasks from :py:class:`waflib.Runner.Parallel` producer and spawns a consuming thread :py:class:`waflib.Runner.Consumer` for each :py:class:`waflib.Task.Task` instance. """ def __init__(self, master): Utils.threading.Thread.__init__(self) self.master = master """:py:class:`waflib.Runner.Parallel` producer instance""" self.sem = Utils.threading.Semaphore(master.numjobs) """Bounded semaphore that prevents spawning more than *n* concurrent consumers""" self.setDaemon(1) self.start() def run(self): """ Spawns new consumers to execute tasks by delegating to :py:meth:`waflib.Runner.Spawner.loop` """ try: self.loop() except Exception: # Python 2 prints unnecessary messages when shutting down # we also want to stop the thread properly pass def loop(self): """ Consumes task objects from the producer; ends when the producer has no more task to provide. """ master = self.master while 1: task = master.ready.get() self.sem.acquire() if not master.stop: task.log_display(task.generator.bld) Consumer(self, task) class Parallel(object): """ Schedule the tasks obtained from the build context for execution. """ def __init__(self, bld, j=2): """ The initialization requires a build context reference for computing the total number of jobs. """ self.numjobs = j """ Amount of parallel consumers to use """ self.bld = bld """ Instance of :py:class:`waflib.Build.BuildContext` """ self.outstanding = PriorityTasks() """Heap of :py:class:`waflib.Task.Task` that may be ready to be executed""" self.postponed = PriorityTasks() """Heap of :py:class:`waflib.Task.Task` which are not ready to run for non-DAG reasons""" self.incomplete = set() """List of :py:class:`waflib.Task.Task` waiting for dependent tasks to complete (DAG)""" self.ready = PriorityQueue(0) """List of :py:class:`waflib.Task.Task` ready to be executed by consumers""" self.out = Queue(0) """List of :py:class:`waflib.Task.Task` returned by the task consumers""" self.count = 0 """Amount of tasks that may be processed by :py:class:`waflib.Runner.TaskConsumer`""" self.processed = 0 """Amount of tasks processed""" self.stop = False """Error flag to stop the build""" self.error = [] """Tasks that could not be executed""" self.biter = None """Task iterator which must give groups of parallelizable tasks when calling ``next()``""" self.dirty = False """ Flag that indicates that the build cache must be saved when a task was executed (calls :py:meth:`waflib.Build.BuildContext.store`)""" self.revdeps = Utils.defaultdict(set) """ The reverse dependency graph of dependencies obtained from Task.run_after """ self.spawner = None """ Coordinating daemon thread that spawns thread consumers """ if self.numjobs > 1: self.spawner = Spawner(self) def get_next_task(self): """ Obtains the next Task instance to run :rtype: :py:class:`waflib.Task.Task` """ if not self.outstanding: return None return self.outstanding.pop() def postpone(self, tsk): """ Adds the task to the list :py:attr:`waflib.Runner.Parallel.postponed`. The order is scrambled so as to consume as many tasks in parallel as possible. :param tsk: task instance :type tsk: :py:class:`waflib.Task.Task` """ self.postponed.append(tsk) def refill_task_list(self): """ Pulls a next group of tasks to execute in :py:attr:`waflib.Runner.Parallel.outstanding`. Ensures that all tasks in the current build group are complete before processing the next one. """ while self.count > self.numjobs * GAP: self.get_out() while not self.outstanding: if self.count: self.get_out() if self.outstanding: break elif self.postponed: try: cond = self.deadlock == self.processed except AttributeError: pass else: if cond: # The most common reason is conflicting build order declaration # for example: "X run_after Y" and "Y run_after X" # Another can be changing "run_after" dependencies while the build is running # for example: updating "tsk.run_after" in the "runnable_status" method lst = [] for tsk in self.postponed: deps = [id(x) for x in tsk.run_after if not x.hasrun] lst.append('%s\t-> %r' % (repr(tsk), deps)) if not deps: lst.append('\n task %r dependencies are done, check its *runnable_status*?' % id(tsk)) raise Errors.WafError('Deadlock detected: check the task build order%s' % ''.join(lst)) self.deadlock = self.processed if self.postponed: self.outstanding.extend(self.postponed) self.postponed.clear() elif not self.count: if self.incomplete: for x in self.incomplete: for k in x.run_after: if not k.hasrun: break else: # dependency added after the build started without updating revdeps self.incomplete.remove(x) self.outstanding.append(x) break else: if self.stop or self.error: break raise Errors.WafError('Broken revdeps detected on %r' % self.incomplete) else: tasks = next(self.biter) ready, waiting = self.prio_and_split(tasks) self.outstanding.extend(ready) self.incomplete.update(waiting) self.total = self.bld.total() break def add_more_tasks(self, tsk): """ If a task provides :py:attr:`waflib.Task.Task.more_tasks`, then the tasks contained in that list are added to the current build and will be processed before the next build group. The priorities for dependent tasks are not re-calculated globally :param tsk: task instance :type tsk: :py:attr:`waflib.Task.Task` """ if getattr(tsk, 'more_tasks', None): more = set(tsk.more_tasks) groups_done = set() def iteri(a, b): for x in a: yield x for x in b: yield x # Update the dependency tree # this assumes that task.run_after values were updated for x in iteri(self.outstanding, self.incomplete): for k in x.run_after: if isinstance(k, Task.TaskGroup): if k not in groups_done: groups_done.add(k) for j in k.prev & more: self.revdeps[j].add(k) elif k in more: self.revdeps[k].add(x) ready, waiting = self.prio_and_split(tsk.more_tasks) self.outstanding.extend(ready) self.incomplete.update(waiting) self.total += len(tsk.more_tasks) def mark_finished(self, tsk): def try_unfreeze(x): # DAG ancestors are likely to be in the incomplete set # This assumes that the run_after contents have not changed # after the build starts, else a deadlock may occur if x in self.incomplete: # TODO remove dependencies to free some memory? # x.run_after.remove(tsk) for k in x.run_after: if not k.hasrun: break else: self.incomplete.remove(x) self.outstanding.append(x) if tsk in self.revdeps: for x in self.revdeps[tsk]: if isinstance(x, Task.TaskGroup): x.prev.remove(tsk) if not x.prev: for k in x.next: # TODO necessary optimization? k.run_after.remove(x) try_unfreeze(k) # TODO necessary optimization? x.next = [] else: try_unfreeze(x) del self.revdeps[tsk] if hasattr(tsk, 'semaphore'): sem = tsk.semaphore try: sem.release(tsk) except KeyError: # TODO pass else: while sem.waiting and not sem.is_locked(): # take a frozen task, make it ready to run x = sem.waiting.pop() self._add_task(x) def get_out(self): """ Waits for a Task that task consumers add to :py:attr:`waflib.Runner.Parallel.out` after execution. Adds more Tasks if necessary through :py:attr:`waflib.Runner.Parallel.add_more_tasks`. :rtype: :py:attr:`waflib.Task.Task` """ tsk = self.out.get() if not self.stop: self.add_more_tasks(tsk) self.mark_finished(tsk) self.count -= 1 self.dirty = True return tsk def add_task(self, tsk): """ Enqueue a Task to :py:attr:`waflib.Runner.Parallel.ready` so that consumers can run them. :param tsk: task instance :type tsk: :py:attr:`waflib.Task.Task` """ # TODO change in waf 2.1 self.ready.put(tsk) def _add_task(self, tsk): if hasattr(tsk, 'semaphore'): sem = tsk.semaphore try: sem.acquire(tsk) except IndexError: sem.waiting.add(tsk) return self.count += 1 self.processed += 1 if self.numjobs == 1: tsk.log_display(tsk.generator.bld) try: self.process_task(tsk) finally: self.out.put(tsk) else: self.add_task(tsk) def process_task(self, tsk): """ Processes a task and attempts to stop the build in case of errors """ tsk.process() if tsk.hasrun != Task.SUCCESS: self.error_handler(tsk) def skip(self, tsk): """ Mark a task as skipped/up-to-date """ tsk.hasrun = Task.SKIPPED self.mark_finished(tsk) def cancel(self, tsk): """ Mark a task as failed because of unsatisfiable dependencies """ tsk.hasrun = Task.CANCELED self.mark_finished(tsk) def error_handler(self, tsk): """ Called when a task cannot be executed. The flag :py:attr:`waflib.Runner.Parallel.stop` is set, unless the build is executed with:: $ waf build -k :param tsk: task instance :type tsk: :py:attr:`waflib.Task.Task` """ if not self.bld.keep: self.stop = True self.error.append(tsk) def task_status(self, tsk): """ Obtains the task status to decide whether to run it immediately or not. :return: the exit status, for example :py:attr:`waflib.Task.ASK_LATER` :rtype: integer """ try: return tsk.runnable_status() except Exception: self.processed += 1 tsk.err_msg = traceback.format_exc() if not self.stop and self.bld.keep: self.skip(tsk) if self.bld.keep == 1: # if -k stop on the first exception, if -kk try to go as far as possible if Logs.verbose > 1 or not self.error: self.error.append(tsk) self.stop = True else: if Logs.verbose > 1: self.error.append(tsk) return Task.EXCEPTION tsk.hasrun = Task.EXCEPTION self.error_handler(tsk) return Task.EXCEPTION def start(self): """ Obtains Task instances from the BuildContext instance and adds the ones that need to be executed to :py:class:`waflib.Runner.Parallel.ready` so that the :py:class:`waflib.Runner.Spawner` consumer thread has them executed. Obtains the executed Tasks back from :py:class:`waflib.Runner.Parallel.out` and marks the build as failed by setting the ``stop`` flag. If only one job is used, then executes the tasks one by one, without consumers. """ self.total = self.bld.total() while not self.stop: self.refill_task_list() # consider the next task tsk = self.get_next_task() if not tsk: if self.count: # tasks may add new ones after they are run continue else: # no tasks to run, no tasks running, time to exit break if tsk.hasrun: # if the task is marked as "run", just skip it self.processed += 1 continue if self.stop: # stop immediately after a failure is detected break st = self.task_status(tsk) if st == Task.RUN_ME: self._add_task(tsk) elif st == Task.ASK_LATER: self.postpone(tsk) elif st == Task.SKIP_ME: self.processed += 1 self.skip(tsk) self.add_more_tasks(tsk) elif st == Task.CANCEL_ME: # A dependency problem has occurred, and the # build is most likely run with `waf -k` if Logs.verbose > 1: self.error.append(tsk) self.processed += 1 self.cancel(tsk) # self.count represents the tasks that have been made available to the consumer threads # collect all the tasks after an error else the message may be incomplete while self.error and self.count: self.get_out() self.ready.put(None) if not self.stop: assert not self.count assert not self.postponed assert not self.incomplete def prio_and_split(self, tasks): """ Label input tasks with priority values, and return a pair containing the tasks that are ready to run and the tasks that are necessarily waiting for other tasks to complete. The priority system is really meant as an optional layer for optimization: dependency cycles are found quickly, and builds should be more efficient. A high priority number means that a task is processed first. This method can be overridden to disable the priority system:: def prio_and_split(self, tasks): return tasks, [] :return: A pair of task lists :rtype: tuple """ # to disable: #return tasks, [] for x in tasks: x.visited = 0 reverse = self.revdeps groups_done = set() for x in tasks: for k in x.run_after: if isinstance(k, Task.TaskGroup): if k not in groups_done: groups_done.add(k) for j in k.prev: reverse[j].add(k) else: reverse[k].add(x) # the priority number is not the tree depth def visit(n): if isinstance(n, Task.TaskGroup): return sum(visit(k) for k in n.next) if n.visited == 0: n.visited = 1 if n in reverse: rev = reverse[n] n.prio_order = n.tree_weight + len(rev) + sum(visit(k) for k in rev) else: n.prio_order = n.tree_weight n.visited = 2 elif n.visited == 1: raise Errors.WafError('Dependency cycle found!') return n.prio_order for x in tasks: if x.visited != 0: # must visit all to detect cycles continue try: visit(x) except Errors.WafError: self.debug_cycles(tasks, reverse) ready = [] waiting = [] for x in tasks: for k in x.run_after: if not k.hasrun: waiting.append(x) break else: ready.append(x) return (ready, waiting) def debug_cycles(self, tasks, reverse): tmp = {} for x in tasks: tmp[x] = 0 def visit(n, acc): if isinstance(n, Task.TaskGroup): for k in n.next: visit(k, acc) return if tmp[n] == 0: tmp[n] = 1 for k in reverse.get(n, []): visit(k, [n] + acc) tmp[n] = 2 elif tmp[n] == 1: lst = [] for tsk in acc: lst.append(repr(tsk)) if tsk is n: # exclude prior nodes, we want the minimum cycle break raise Errors.WafError('Task dependency cycle in "run_after" constraints: %s' % ''.join(lst)) for x in tasks: visit(x, []) ldb-2.0.8/third_party/waf/waflib/Scripting.py0000660000000000000000000004021413573675414021124 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) "Module called for configuring, compiling and installing targets" from __future__ import with_statement import os, shlex, shutil, traceback, errno, sys, stat from waflib import Utils, Configure, Logs, Options, ConfigSet, Context, Errors, Build, Node build_dir_override = None no_climb_commands = ['configure'] default_cmd = "build" def waf_entry_point(current_directory, version, wafdir): """ This is the main entry point, all Waf execution starts here. :param current_directory: absolute path representing the current directory :type current_directory: string :param version: version number :type version: string :param wafdir: absolute path representing the directory of the waf library :type wafdir: string """ Logs.init_log() if Context.WAFVERSION != version: Logs.error('Waf script %r and library %r do not match (directory %r)', version, Context.WAFVERSION, wafdir) sys.exit(1) # Store current directory before any chdir Context.waf_dir = wafdir Context.run_dir = Context.launch_dir = current_directory start_dir = current_directory no_climb = os.environ.get('NOCLIMB') if len(sys.argv) > 1: # os.path.join handles absolute paths # if sys.argv[1] is not an absolute path, then it is relative to the current working directory potential_wscript = os.path.join(current_directory, sys.argv[1]) if os.path.basename(potential_wscript) == Context.WSCRIPT_FILE and os.path.isfile(potential_wscript): # need to explicitly normalize the path, as it may contain extra '/.' path = os.path.normpath(os.path.dirname(potential_wscript)) start_dir = os.path.abspath(path) no_climb = True sys.argv.pop(1) ctx = Context.create_context('options') (options, commands, env) = ctx.parse_cmd_args(allow_unknown=True) if options.top: start_dir = Context.run_dir = Context.top_dir = options.top no_climb = True if options.out: Context.out_dir = options.out # if 'configure' is in the commands, do not search any further if not no_climb: for k in no_climb_commands: for y in commands: if y.startswith(k): no_climb = True break # try to find a lock file (if the project was configured) # at the same time, store the first wscript file seen cur = start_dir while cur: try: lst = os.listdir(cur) except OSError: lst = [] Logs.error('Directory %r is unreadable!', cur) if Options.lockfile in lst: env = ConfigSet.ConfigSet() try: env.load(os.path.join(cur, Options.lockfile)) ino = os.stat(cur)[stat.ST_INO] except EnvironmentError: pass else: # check if the folder was not moved for x in (env.run_dir, env.top_dir, env.out_dir): if not x: continue if Utils.is_win32: if cur == x: load = True break else: # if the filesystem features symlinks, compare the inode numbers try: ino2 = os.stat(x)[stat.ST_INO] except OSError: pass else: if ino == ino2: load = True break else: Logs.warn('invalid lock file in %s', cur) load = False if load: Context.run_dir = env.run_dir Context.top_dir = env.top_dir Context.out_dir = env.out_dir break if not Context.run_dir: if Context.WSCRIPT_FILE in lst: Context.run_dir = cur next = os.path.dirname(cur) if next == cur: break cur = next if no_climb: break wscript = os.path.normpath(os.path.join(Context.run_dir, Context.WSCRIPT_FILE)) if not os.path.exists(wscript): if options.whelp: Logs.warn('These are the generic options (no wscript/project found)') ctx.parser.print_help() sys.exit(0) Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)', Context.WSCRIPT_FILE) sys.exit(1) try: os.chdir(Context.run_dir) except OSError: Logs.error('Waf: The folder %r is unreadable', Context.run_dir) sys.exit(1) try: set_main_module(wscript) except Errors.WafError as e: Logs.pprint('RED', e.verbose_msg) Logs.error(str(e)) sys.exit(1) except Exception as e: Logs.error('Waf: The wscript in %r is unreadable', Context.run_dir) traceback.print_exc(file=sys.stdout) sys.exit(2) if options.profile: import cProfile, pstats cProfile.runctx('from waflib import Scripting; Scripting.run_commands()', {}, {}, 'profi.txt') p = pstats.Stats('profi.txt') p.sort_stats('time').print_stats(75) # or 'cumulative' else: try: try: run_commands() except: if options.pdb: import pdb type, value, tb = sys.exc_info() traceback.print_exc() pdb.post_mortem(tb) else: raise except Errors.WafError as e: if Logs.verbose > 1: Logs.pprint('RED', e.verbose_msg) Logs.error(e.msg) sys.exit(1) except SystemExit: raise except Exception as e: traceback.print_exc(file=sys.stdout) sys.exit(2) except KeyboardInterrupt: Logs.pprint('RED', 'Interrupted') sys.exit(68) def set_main_module(file_path): """ Read the main wscript file into :py:const:`waflib.Context.Context.g_module` and bind default functions such as ``init``, ``dist``, ``distclean`` if not defined. Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. :param file_path: absolute path representing the top-level wscript file :type file_path: string """ Context.g_module = Context.load_module(file_path) Context.g_module.root_path = file_path # note: to register the module globally, use the following: # sys.modules['wscript_main'] = g_module def set_def(obj): name = obj.__name__ if not name in Context.g_module.__dict__: setattr(Context.g_module, name, obj) for k in (dist, distclean, distcheck): set_def(k) # add dummy init and shutdown functions if they're not defined if not 'init' in Context.g_module.__dict__: Context.g_module.init = Utils.nada if not 'shutdown' in Context.g_module.__dict__: Context.g_module.shutdown = Utils.nada if not 'options' in Context.g_module.__dict__: Context.g_module.options = Utils.nada def parse_options(): """ Parses the command-line options and initialize the logging system. Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. """ ctx = Context.create_context('options') ctx.execute() if not Options.commands: if isinstance(default_cmd, list): Options.commands.extend(default_cmd) else: Options.commands.append(default_cmd) if Options.options.whelp: ctx.parser.print_help() sys.exit(0) def run_command(cmd_name): """ Executes a single Waf command. Called by :py:func:`waflib.Scripting.run_commands`. :param cmd_name: command to execute, like ``build`` :type cmd_name: string """ ctx = Context.create_context(cmd_name) ctx.log_timer = Utils.Timer() ctx.options = Options.options # provided for convenience ctx.cmd = cmd_name try: ctx.execute() finally: # Issue 1374 ctx.finalize() return ctx def run_commands(): """ Execute the Waf commands that were given on the command-line, and the other options Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization, and executed after :py:func:`waflib.Scripting.parse_options`. """ parse_options() run_command('init') while Options.commands: cmd_name = Options.commands.pop(0) ctx = run_command(cmd_name) Logs.info('%r finished successfully (%s)', cmd_name, ctx.log_timer) run_command('shutdown') ########################################################################################### def distclean_dir(dirname): """ Distclean function called in the particular case when:: top == out :param dirname: absolute path of the folder to clean :type dirname: string """ for (root, dirs, files) in os.walk(dirname): for f in files: if f.endswith(('.o', '.moc', '.exe')): fname = os.path.join(root, f) try: os.remove(fname) except OSError: Logs.warn('Could not remove %r', fname) for x in (Context.DBFILE, 'config.log'): try: os.remove(x) except OSError: pass try: shutil.rmtree(Build.CACHE_DIR) except OSError: pass def distclean(ctx): '''removes build folders and data''' def remove_and_log(k, fun): try: fun(k) except EnvironmentError as e: if e.errno != errno.ENOENT: Logs.warn('Could not remove %r', k) # remove waf cache folders on the top-level if not Options.commands: for k in os.listdir('.'): for x in '.waf-2 waf-2 .waf3-2 waf3-2'.split(): if k.startswith(x): remove_and_log(k, shutil.rmtree) # remove a build folder, if any cur = '.' if ctx.options.no_lock_in_top: cur = ctx.options.out try: lst = os.listdir(cur) except OSError: Logs.warn('Could not read %r', cur) return if Options.lockfile in lst: f = os.path.join(cur, Options.lockfile) try: env = ConfigSet.ConfigSet(f) except EnvironmentError: Logs.warn('Could not read %r', f) return if not env.out_dir or not env.top_dir: Logs.warn('Invalid lock file %r', f) return if env.out_dir == env.top_dir: distclean_dir(env.out_dir) else: remove_and_log(env.out_dir, shutil.rmtree) env_dirs = [env.out_dir] if not ctx.options.no_lock_in_top: env_dirs.append(env.top_dir) if not ctx.options.no_lock_in_run: env_dirs.append(env.run_dir) for k in env_dirs: p = os.path.join(k, Options.lockfile) remove_and_log(p, os.remove) class Dist(Context.Context): '''creates an archive containing the project source code''' cmd = 'dist' fun = 'dist' algo = 'tar.bz2' ext_algo = {} def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ self.recurse([os.path.dirname(Context.g_module.root_path)]) self.archive() def archive(self): """ Creates the source archive. """ import tarfile arch_name = self.get_arch_name() try: self.base_path except AttributeError: self.base_path = self.path node = self.base_path.make_node(arch_name) try: node.delete() except OSError: pass files = self.get_files() if self.algo.startswith('tar.'): tar = tarfile.open(node.abspath(), 'w:' + self.algo.replace('tar.', '')) for x in files: self.add_tar_file(x, tar) tar.close() elif self.algo == 'zip': import zipfile zip = zipfile.ZipFile(node.abspath(), 'w', compression=zipfile.ZIP_DEFLATED) for x in files: archive_name = self.get_base_name() + '/' + x.path_from(self.base_path) zip.write(x.abspath(), archive_name, zipfile.ZIP_DEFLATED) zip.close() else: self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip') try: from hashlib import sha256 except ImportError: digest = '' else: digest = ' (sha256=%r)' % sha256(node.read(flags='rb')).hexdigest() Logs.info('New archive created: %s%s', self.arch_name, digest) def get_tar_path(self, node): """ Return the path to use for a node in the tar archive, the purpose of this is to let subclases resolve symbolic links or to change file names :return: absolute path :rtype: string """ return node.abspath() def add_tar_file(self, x, tar): """ Adds a file to the tar archive. Symlinks are not verified. :param x: file path :param tar: tar file object """ p = self.get_tar_path(x) tinfo = tar.gettarinfo(name=p, arcname=self.get_tar_prefix() + '/' + x.path_from(self.base_path)) tinfo.uid = 0 tinfo.gid = 0 tinfo.uname = 'root' tinfo.gname = 'root' if os.path.isfile(p): with open(p, 'rb') as f: tar.addfile(tinfo, fileobj=f) else: tar.addfile(tinfo) def get_tar_prefix(self): """ Returns the base path for files added into the archive tar file :rtype: string """ try: return self.tar_prefix except AttributeError: return self.get_base_name() def get_arch_name(self): """ Returns the archive file name. Set the attribute *arch_name* to change the default value:: def dist(ctx): ctx.arch_name = 'ctx.tar.bz2' :rtype: string """ try: self.arch_name except AttributeError: self.arch_name = self.get_base_name() + '.' + self.ext_algo.get(self.algo, self.algo) return self.arch_name def get_base_name(self): """ Returns the default name of the main directory in the archive, which is set to *appname-version*. Set the attribute *base_name* to change the default value:: def dist(ctx): ctx.base_name = 'files' :rtype: string """ try: self.base_name except AttributeError: appname = getattr(Context.g_module, Context.APPNAME, 'noname') version = getattr(Context.g_module, Context.VERSION, '1.0') self.base_name = appname + '-' + version return self.base_name def get_excl(self): """ Returns the patterns to exclude for finding the files in the top-level directory. Set the attribute *excl* to change the default value:: def dist(ctx): ctx.excl = 'build **/*.o **/*.class' :rtype: string """ try: return self.excl except AttributeError: self.excl = Node.exclude_regs + ' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' if Context.out_dir: nd = self.root.find_node(Context.out_dir) if nd: self.excl += ' ' + nd.path_from(self.base_path) return self.excl def get_files(self): """ Files to package are searched automatically by :py:func:`waflib.Node.Node.ant_glob`. Set *files* to prevent this behaviour:: def dist(ctx): ctx.files = ctx.path.find_node('wscript') Files are also searched from the directory 'base_path', to change it, set:: def dist(ctx): ctx.base_path = path :rtype: list of :py:class:`waflib.Node.Node` """ try: files = self.files except AttributeError: files = self.base_path.ant_glob('**/*', excl=self.get_excl()) return files def dist(ctx): '''makes a tarball for redistributing the sources''' pass class DistCheck(Dist): """creates an archive with dist, then tries to build it""" fun = 'distcheck' cmd = 'distcheck' def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ self.recurse([os.path.dirname(Context.g_module.root_path)]) self.archive() self.check() def make_distcheck_cmd(self, tmpdir): cfg = [] if Options.options.distcheck_args: cfg = shlex.split(Options.options.distcheck_args) else: cfg = [x for x in sys.argv if x.startswith('-')] cmd = [sys.executable, sys.argv[0], 'configure', 'build', 'install', 'uninstall', '--destdir=' + tmpdir] + cfg return cmd def check(self): """ Creates the archive, uncompresses it and tries to build the project """ import tempfile, tarfile with tarfile.open(self.get_arch_name()) as t: for x in t: t.extract(x) instdir = tempfile.mkdtemp('.inst', self.get_base_name()) cmd = self.make_distcheck_cmd(instdir) ret = Utils.subprocess.Popen(cmd, cwd=self.get_base_name()).wait() if ret: raise Errors.WafError('distcheck failed with code %r' % ret) if os.path.exists(instdir): raise Errors.WafError('distcheck succeeded, but files were left in %s' % instdir) shutil.rmtree(self.get_base_name()) def distcheck(ctx): '''checks if the project compiles (tarball from 'dist')''' pass def autoconfigure(execute_method): """ Decorator that enables context commands to run *configure* as needed. """ def execute(self): """ Wraps :py:func:`waflib.Context.Context.execute` on the context class """ if not Configure.autoconfig: return execute_method(self) env = ConfigSet.ConfigSet() do_config = False try: env.load(os.path.join(Context.top_dir, Options.lockfile)) except EnvironmentError: Logs.warn('Configuring the project') do_config = True else: if env.run_dir != Context.run_dir: do_config = True else: h = 0 for f in env.files: try: h = Utils.h_list((h, Utils.readf(f, 'rb'))) except EnvironmentError: do_config = True break else: do_config = h != env.hash if do_config: cmd = env.config_cmd or 'configure' if Configure.autoconfig == 'clobber': tmp = Options.options.__dict__ launch_dir_tmp = Context.launch_dir if env.options: Options.options.__dict__ = env.options Context.launch_dir = env.launch_dir try: run_command(cmd) finally: Options.options.__dict__ = tmp Context.launch_dir = launch_dir_tmp else: run_command(cmd) run_command(self.cmd) else: return execute_method(self) return execute Build.BuildContext.execute = autoconfigure(Build.BuildContext.execute) ldb-2.0.8/third_party/waf/waflib/Task.py0000660000000000000000000011507613573675414020075 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Tasks represent atomic operations such as processes. """ import os, re, sys, tempfile, traceback from waflib import Utils, Logs, Errors # task states NOT_RUN = 0 """The task was not executed yet""" MISSING = 1 """The task has been executed but the files have not been created""" CRASHED = 2 """The task execution returned a non-zero exit status""" EXCEPTION = 3 """An exception occurred in the task execution""" CANCELED = 4 """A dependency for the task is missing so it was cancelled""" SKIPPED = 8 """The task did not have to be executed""" SUCCESS = 9 """The task was successfully executed""" ASK_LATER = -1 """The task is not ready to be executed""" SKIP_ME = -2 """The task does not need to be executed""" RUN_ME = -3 """The task must be executed""" CANCEL_ME = -4 """The task cannot be executed because of a dependency problem""" COMPILE_TEMPLATE_SHELL = ''' def f(tsk): env = tsk.env gen = tsk.generator bld = gen.bld cwdx = tsk.get_cwd() p = env.get_flat def to_list(xx): if isinstance(xx, str): return [xx] return xx tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s return tsk.exec_command(cmd, cwd=cwdx, env=env.env or None) ''' COMPILE_TEMPLATE_NOSHELL = ''' def f(tsk): env = tsk.env gen = tsk.generator bld = gen.bld cwdx = tsk.get_cwd() def to_list(xx): if isinstance(xx, str): return [xx] return xx def merge(lst1, lst2): if lst1 and lst2: return lst1[:-1] + [lst1[-1] + lst2[0]] + lst2[1:] return lst1 + lst2 lst = [] %s if '' in lst: lst = [x for x in lst if x] tsk.last_cmd = lst return tsk.exec_command(lst, cwd=cwdx, env=env.env or None) ''' COMPILE_TEMPLATE_SIG_VARS = ''' def f(tsk): sig = tsk.generator.bld.hash_env_vars(tsk.env, tsk.vars) tsk.m.update(sig) env = tsk.env gen = tsk.generator bld = gen.bld cwdx = tsk.get_cwd() p = env.get_flat buf = [] %s tsk.m.update(repr(buf).encode()) ''' classes = {} """ The metaclass :py:class:`waflib.Task.store_task_type` stores all class tasks created by user scripts or Waf tools to this dict. It maps class names to class objects. """ class store_task_type(type): """ Metaclass: store the task classes into the dict pointed by the class attribute 'register' which defaults to :py:const:`waflib.Task.classes`, The attribute 'run_str' is compiled into a method 'run' bound to the task class. """ def __init__(cls, name, bases, dict): super(store_task_type, cls).__init__(name, bases, dict) name = cls.__name__ if name != 'evil' and name != 'Task': if getattr(cls, 'run_str', None): # if a string is provided, convert it to a method (f, dvars) = compile_fun(cls.run_str, cls.shell) cls.hcode = Utils.h_cmd(cls.run_str) cls.orig_run_str = cls.run_str # change the name of run_str or it is impossible to subclass with a function cls.run_str = None cls.run = f # process variables cls.vars = list(set(cls.vars + dvars)) cls.vars.sort() if cls.vars: fun = compile_sig_vars(cls.vars) if fun: cls.sig_vars = fun elif getattr(cls, 'run', None) and not 'hcode' in cls.__dict__: # getattr(cls, 'hcode') would look in the upper classes cls.hcode = Utils.h_cmd(cls.run) # be creative getattr(cls, 'register', classes)[name] = cls evil = store_task_type('evil', (object,), {}) "Base class provided to avoid writing a metaclass, so the code can run in python 2.6 and 3.x unmodified" class Task(evil): """ Task objects represents actions to perform such as commands to execute by calling the `run` method. Detecting when to execute a task occurs in the method :py:meth:`waflib.Task.Task.runnable_status`. Detecting which tasks to execute is performed through a hash value returned by :py:meth:`waflib.Task.Task.signature`. The task signature is persistent from build to build. """ vars = [] """ConfigSet variables that should trigger a rebuild (class attribute used for :py:meth:`waflib.Task.Task.sig_vars`)""" always_run = False """Specify whether task instances must always be executed or not (class attribute)""" shell = False """Execute the command with the shell (class attribute)""" color = 'GREEN' """Color for the console display, see :py:const:`waflib.Logs.colors_lst`""" ext_in = [] """File extensions that objects of this task class may use""" ext_out = [] """File extensions that objects of this task class may create""" before = [] """The instances of this class are executed before the instances of classes whose names are in this list""" after = [] """The instances of this class are executed after the instances of classes whose names are in this list""" hcode = Utils.SIG_NIL """String representing an additional hash for the class representation""" keep_last_cmd = False """Whether to keep the last command executed on the instance after execution. This may be useful for certain extensions but it can a lot of memory. """ weight = 0 """Optional weight to tune the priority for task instances. The higher, the earlier. The weight only applies to single task objects.""" tree_weight = 0 """Optional weight to tune the priority of task instances and whole subtrees. The higher, the earlier.""" prio_order = 0 """Priority order set by the scheduler on instances during the build phase. You most likely do not need to set it. """ __slots__ = ('hasrun', 'generator', 'env', 'inputs', 'outputs', 'dep_nodes', 'run_after') def __init__(self, *k, **kw): self.hasrun = NOT_RUN try: self.generator = kw['generator'] except KeyError: self.generator = self self.env = kw['env'] """:py:class:`waflib.ConfigSet.ConfigSet` object (make sure to provide one)""" self.inputs = [] """List of input nodes, which represent the files used by the task instance""" self.outputs = [] """List of output nodes, which represent the files created by the task instance""" self.dep_nodes = [] """List of additional nodes to depend on""" self.run_after = set() """Set of tasks that must be executed before this one""" def __lt__(self, other): return self.priority() > other.priority() def __le__(self, other): return self.priority() >= other.priority() def __gt__(self, other): return self.priority() < other.priority() def __ge__(self, other): return self.priority() <= other.priority() def get_cwd(self): """ :return: current working directory :rtype: :py:class:`waflib.Node.Node` """ bld = self.generator.bld ret = getattr(self, 'cwd', None) or getattr(bld, 'cwd', bld.bldnode) if isinstance(ret, str): if os.path.isabs(ret): ret = bld.root.make_node(ret) else: ret = self.generator.path.make_node(ret) return ret def quote_flag(self, x): """ Surround a process argument by quotes so that a list of arguments can be written to a file :param x: flag :type x: string :return: quoted flag :rtype: string """ old = x if '\\' in x: x = x.replace('\\', '\\\\') if '"' in x: x = x.replace('"', '\\"') if old != x or ' ' in x or '\t' in x or "'" in x: x = '"%s"' % x return x def priority(self): """ Priority of execution; the higher, the earlier :return: the priority value :rtype: a tuple of numeric values """ return (self.weight + self.prio_order, - getattr(self.generator, 'tg_idx_count', 0)) def split_argfile(self, cmd): """ Splits a list of process commands into the executable part and its list of arguments :return: a tuple containing the executable first and then the rest of arguments :rtype: tuple """ return ([cmd[0]], [self.quote_flag(x) for x in cmd[1:]]) def exec_command(self, cmd, **kw): """ Wrapper for :py:meth:`waflib.Context.Context.exec_command`. This version set the current working directory (``build.variant_dir``), applies PATH settings (if self.env.PATH is provided), and can run long commands through a temporary ``@argfile``. :param cmd: process command to execute :type cmd: list of string (best) or string (process will use a shell) :return: the return code :rtype: int Optional parameters: #. cwd: current working directory (Node or string) #. stdout: set to None to prevent waf from capturing the process standard output #. stderr: set to None to prevent waf from capturing the process standard error #. timeout: timeout value (Python 3) """ if not 'cwd' in kw: kw['cwd'] = self.get_cwd() if hasattr(self, 'timeout'): kw['timeout'] = self.timeout if self.env.PATH: env = kw['env'] = dict(kw.get('env') or self.env.env or os.environ) env['PATH'] = self.env.PATH if isinstance(self.env.PATH, str) else os.pathsep.join(self.env.PATH) if hasattr(self, 'stdout'): kw['stdout'] = self.stdout if hasattr(self, 'stderr'): kw['stderr'] = self.stderr if not isinstance(cmd, str): if Utils.is_win32: # win32 compares the resulting length http://support.microsoft.com/kb/830473 too_long = sum([len(arg) for arg in cmd]) + len(cmd) > 8192 else: # non-win32 counts the amount of arguments (200k) too_long = len(cmd) > 200000 if too_long and getattr(self, 'allow_argsfile', True): # Shunt arguments to a temporary file if the command is too long. cmd, args = self.split_argfile(cmd) try: (fd, tmp) = tempfile.mkstemp() os.write(fd, '\r\n'.join(args).encode()) os.close(fd) if Logs.verbose: Logs.debug('argfile: @%r -> %r', tmp, args) return self.generator.bld.exec_command(cmd + ['@' + tmp], **kw) finally: try: os.remove(tmp) except OSError: # anti-virus and indexers can keep files open -_- pass return self.generator.bld.exec_command(cmd, **kw) def process(self): """ Runs the task and handles errors :return: 0 or None if everything is fine :rtype: integer """ # remove the task signature immediately before it is executed # so that the task will be executed again in case of failure try: del self.generator.bld.task_sigs[self.uid()] except KeyError: pass try: ret = self.run() except Exception: self.err_msg = traceback.format_exc() self.hasrun = EXCEPTION else: if ret: self.err_code = ret self.hasrun = CRASHED else: try: self.post_run() except Errors.WafError: pass except Exception: self.err_msg = traceback.format_exc() self.hasrun = EXCEPTION else: self.hasrun = SUCCESS if self.hasrun != SUCCESS and self.scan: # rescan dependencies on next run try: del self.generator.bld.imp_sigs[self.uid()] except KeyError: pass def log_display(self, bld): "Writes the execution status on the context logger" if self.generator.bld.progress_bar == 3: return s = self.display() if s: if bld.logger: logger = bld.logger else: logger = Logs if self.generator.bld.progress_bar == 1: c1 = Logs.colors.cursor_off c2 = Logs.colors.cursor_on logger.info(s, extra={'stream': sys.stderr, 'terminator':'', 'c1': c1, 'c2' : c2}) else: logger.info(s, extra={'terminator':'', 'c1': '', 'c2' : ''}) def display(self): """ Returns an execution status for the console, the progress bar, or the IDE output. :rtype: string """ col1 = Logs.colors(self.color) col2 = Logs.colors.NORMAL master = self.generator.bld.producer def cur(): # the current task position, computed as late as possible return master.processed - master.ready.qsize() if self.generator.bld.progress_bar == 1: return self.generator.bld.progress_line(cur(), master.total, col1, col2) if self.generator.bld.progress_bar == 2: ela = str(self.generator.bld.timer) try: ins = ','.join([n.name for n in self.inputs]) except AttributeError: ins = '' try: outs = ','.join([n.name for n in self.outputs]) except AttributeError: outs = '' return '|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n' % (master.total, cur(), ins, outs, ela) s = str(self) if not s: return None total = master.total n = len(str(total)) fs = '[%%%dd/%%%dd] %%s%%s%%s%%s\n' % (n, n) kw = self.keyword() if kw: kw += ' ' return fs % (cur(), total, kw, col1, s, col2) def hash_constraints(self): """ Identifies a task type for all the constraints relevant for the scheduler: precedence, file production :return: a hash value :rtype: string """ return (tuple(self.before), tuple(self.after), tuple(self.ext_in), tuple(self.ext_out), self.__class__.__name__, self.hcode) def format_error(self): """ Returns an error message to display the build failure reasons :rtype: string """ if Logs.verbose: msg = ': %r\n%r' % (self, getattr(self, 'last_cmd', '')) else: msg = ' (run with -v to display more information)' name = getattr(self.generator, 'name', '') if getattr(self, "err_msg", None): return self.err_msg elif not self.hasrun: return 'task in %r was not executed for some reason: %r' % (name, self) elif self.hasrun == CRASHED: try: return ' -> task in %r failed with exit status %r%s' % (name, self.err_code, msg) except AttributeError: return ' -> task in %r failed%s' % (name, msg) elif self.hasrun == MISSING: return ' -> missing files in %r%s' % (name, msg) elif self.hasrun == CANCELED: return ' -> %r canceled because of missing dependencies' % name else: return 'invalid status for task in %r: %r' % (name, self.hasrun) def colon(self, var1, var2): """ Enable scriptlet expressions of the form ${FOO_ST:FOO} If the first variable (FOO_ST) is empty, then an empty list is returned The results will be slightly different if FOO_ST is a list, for example:: env.FOO = ['p1', 'p2'] env.FOO_ST = '-I%s' # ${FOO_ST:FOO} returns ['-Ip1', '-Ip2'] env.FOO_ST = ['-a', '-b'] # ${FOO_ST:FOO} returns ['-a', '-b', 'p1', '-a', '-b', 'p2'] """ tmp = self.env[var1] if not tmp: return [] if isinstance(var2, str): it = self.env[var2] else: it = var2 if isinstance(tmp, str): return [tmp % x for x in it] else: lst = [] for y in it: lst.extend(tmp) lst.append(y) return lst def __str__(self): "string to display to the user" name = self.__class__.__name__ if self.outputs: if name.endswith(('lib', 'program')) or not self.inputs: node = self.outputs[0] return node.path_from(node.ctx.launch_node()) if not (self.inputs or self.outputs): return self.__class__.__name__ if len(self.inputs) == 1: node = self.inputs[0] return node.path_from(node.ctx.launch_node()) src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs]) tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs]) if self.outputs: sep = ' -> ' else: sep = '' return '%s: %s%s%s' % (self.__class__.__name__, src_str, sep, tgt_str) def keyword(self): "Display keyword used to prettify the console outputs" name = self.__class__.__name__ if name.endswith(('lib', 'program')): return 'Linking' if len(self.inputs) == 1 and len(self.outputs) == 1: return 'Compiling' if not self.inputs: if self.outputs: return 'Creating' else: return 'Running' return 'Processing' def __repr__(self): "for debugging purposes" try: ins = ",".join([x.name for x in self.inputs]) outs = ",".join([x.name for x in self.outputs]) except AttributeError: ins = ",".join([str(x) for x in self.inputs]) outs = ",".join([str(x) for x in self.outputs]) return "".join(['\n\t{task %r: ' % id(self), self.__class__.__name__, " ", ins, " -> ", outs, '}']) def uid(self): """ Returns an identifier used to determine if tasks are up-to-date. Since the identifier will be stored between executions, it must be: - unique for a task: no two tasks return the same value (for a given build context) - the same for a given task instance By default, the node paths, the class name, and the function are used as inputs to compute a hash. The pointer to the object (python built-in 'id') will change between build executions, and must be avoided in such hashes. :return: hash value :rtype: string """ try: return self.uid_ except AttributeError: m = Utils.md5(self.__class__.__name__) up = m.update for x in self.inputs + self.outputs: up(x.abspath()) self.uid_ = m.digest() return self.uid_ def set_inputs(self, inp): """ Appends the nodes to the *inputs* list :param inp: input nodes :type inp: node or list of nodes """ if isinstance(inp, list): self.inputs += inp else: self.inputs.append(inp) def set_outputs(self, out): """ Appends the nodes to the *outputs* list :param out: output nodes :type out: node or list of nodes """ if isinstance(out, list): self.outputs += out else: self.outputs.append(out) def set_run_after(self, task): """ Run this task only after the given *task*. Calling this method from :py:meth:`waflib.Task.Task.runnable_status` may cause build deadlocks; see :py:meth:`waflib.Tools.fc.fc.runnable_status` for details. :param task: task :type task: :py:class:`waflib.Task.Task` """ assert isinstance(task, Task) self.run_after.add(task) def signature(self): """ Task signatures are stored between build executions, they are use to track the changes made to the input nodes (not to the outputs!). The signature hashes data from various sources: * explicit dependencies: files listed in the inputs (list of node objects) :py:meth:`waflib.Task.Task.sig_explicit_deps` * implicit dependencies: list of nodes returned by scanner methods (when present) :py:meth:`waflib.Task.Task.sig_implicit_deps` * hashed data: variables/values read from task.vars/task.env :py:meth:`waflib.Task.Task.sig_vars` If the signature is expected to give a different result, clear the cache kept in ``self.cache_sig``:: from waflib import Task class cls(Task.Task): def signature(self): sig = super(Task.Task, self).signature() delattr(self, 'cache_sig') return super(Task.Task, self).signature() :return: the signature value :rtype: string or bytes """ try: return self.cache_sig except AttributeError: pass self.m = Utils.md5(self.hcode) # explicit deps self.sig_explicit_deps() # env vars self.sig_vars() # implicit deps / scanner results if self.scan: try: self.sig_implicit_deps() except Errors.TaskRescan: return self.signature() ret = self.cache_sig = self.m.digest() return ret def runnable_status(self): """ Returns the Task status :return: a task state in :py:const:`waflib.Task.RUN_ME`, :py:const:`waflib.Task.SKIP_ME`, :py:const:`waflib.Task.CANCEL_ME` or :py:const:`waflib.Task.ASK_LATER`. :rtype: int """ bld = self.generator.bld if bld.is_install < 0: return SKIP_ME for t in self.run_after: if not t.hasrun: return ASK_LATER elif t.hasrun < SKIPPED: # a dependency has an error return CANCEL_ME # first compute the signature try: new_sig = self.signature() except Errors.TaskNotReady: return ASK_LATER # compare the signature to a signature computed previously key = self.uid() try: prev_sig = bld.task_sigs[key] except KeyError: Logs.debug('task: task %r must run: it was never run before or the task code changed', self) return RUN_ME if new_sig != prev_sig: Logs.debug('task: task %r must run: the task signature changed', self) return RUN_ME # compare the signatures of the outputs for node in self.outputs: sig = bld.node_sigs.get(node) if not sig: Logs.debug('task: task %r must run: an output node has no signature', self) return RUN_ME if sig != key: Logs.debug('task: task %r must run: an output node was produced by another task', self) return RUN_ME if not node.exists(): Logs.debug('task: task %r must run: an output node does not exist', self) return RUN_ME return (self.always_run and RUN_ME) or SKIP_ME def post_run(self): """ Called after successful execution to record that the task has run by updating the entry in :py:attr:`waflib.Build.BuildContext.task_sigs`. """ bld = self.generator.bld for node in self.outputs: if not node.exists(): self.hasrun = MISSING self.err_msg = '-> missing file: %r' % node.abspath() raise Errors.WafError(self.err_msg) bld.node_sigs[node] = self.uid() # make sure this task produced the files in question bld.task_sigs[self.uid()] = self.signature() if not self.keep_last_cmd: try: del self.last_cmd except AttributeError: pass def sig_explicit_deps(self): """ Used by :py:meth:`waflib.Task.Task.signature`; it hashes :py:attr:`waflib.Task.Task.inputs` and :py:attr:`waflib.Task.Task.dep_nodes` signatures. """ bld = self.generator.bld upd = self.m.update # the inputs for x in self.inputs + self.dep_nodes: upd(x.get_bld_sig()) # manual dependencies, they can slow down the builds if bld.deps_man: additional_deps = bld.deps_man for x in self.inputs + self.outputs: try: d = additional_deps[x] except KeyError: continue for v in d: try: v = v.get_bld_sig() except AttributeError: if hasattr(v, '__call__'): v = v() # dependency is a function, call it upd(v) def sig_deep_inputs(self): """ Enable rebuilds on input files task signatures. Not used by default. Example: hashes of output programs can be unchanged after being re-linked, despite the libraries being different. This method can thus prevent stale unit test results (waf_unit_test.py). Hashing input file timestamps is another possibility for the implementation. This may cause unnecessary rebuilds when input tasks are frequently executed. Here is an implementation example:: lst = [] for node in self.inputs + self.dep_nodes: st = os.stat(node.abspath()) lst.append(st.st_mtime) lst.append(st.st_size) self.m.update(Utils.h_list(lst)) The downside of the implementation is that it absolutely requires all build directory files to be declared within the current build. """ bld = self.generator.bld lst = [bld.task_sigs[bld.node_sigs[node]] for node in (self.inputs + self.dep_nodes) if node.is_bld()] self.m.update(Utils.h_list(lst)) def sig_vars(self): """ Used by :py:meth:`waflib.Task.Task.signature`; it hashes :py:attr:`waflib.Task.Task.env` variables/values When overriding this method, and if scriptlet expressions are used, make sure to follow the code in :py:meth:`waflib.Task.Task.compile_sig_vars` to enable dependencies on scriptlet results. This method may be replaced on subclasses by the metaclass to force dependencies on scriptlet code. """ sig = self.generator.bld.hash_env_vars(self.env, self.vars) self.m.update(sig) scan = None """ This method, when provided, returns a tuple containing: * a list of nodes corresponding to real files * a list of names for files not found in path_lst For example:: from waflib.Task import Task class mytask(Task): def scan(self, node): return ([], []) The first and second lists in the tuple are stored in :py:attr:`waflib.Build.BuildContext.node_deps` and :py:attr:`waflib.Build.BuildContext.raw_deps` respectively. """ def sig_implicit_deps(self): """ Used by :py:meth:`waflib.Task.Task.signature`; it hashes node signatures obtained by scanning for dependencies (:py:meth:`waflib.Task.Task.scan`). The exception :py:class:`waflib.Errors.TaskRescan` is thrown when a file has changed. In this case, the method :py:meth:`waflib.Task.Task.signature` is called once again, and return here to call :py:meth:`waflib.Task.Task.scan` and searching for dependencies. """ bld = self.generator.bld # get the task signatures from previous runs key = self.uid() prev = bld.imp_sigs.get(key, []) # for issue #379 if prev: try: if prev == self.compute_sig_implicit_deps(): return prev except Errors.TaskNotReady: raise except EnvironmentError: # when a file was renamed, remove the stale nodes (headers in folders without source files) # this will break the order calculation for headers created during the build in the source directory (should be uncommon) # the behaviour will differ when top != out for x in bld.node_deps.get(self.uid(), []): if not x.is_bld() and not x.exists(): try: del x.parent.children[x.name] except KeyError: pass del bld.imp_sigs[key] raise Errors.TaskRescan('rescan') # no previous run or the signature of the dependencies has changed, rescan the dependencies (bld.node_deps[key], bld.raw_deps[key]) = self.scan() if Logs.verbose: Logs.debug('deps: scanner for %s: %r; unresolved: %r', self, bld.node_deps[key], bld.raw_deps[key]) # recompute the signature and return it try: bld.imp_sigs[key] = self.compute_sig_implicit_deps() except EnvironmentError: for k in bld.node_deps.get(self.uid(), []): if not k.exists(): Logs.warn('Dependency %r for %r is missing: check the task declaration and the build order!', k, self) raise def compute_sig_implicit_deps(self): """ Used by :py:meth:`waflib.Task.Task.sig_implicit_deps` for computing the actual hash of the :py:class:`waflib.Node.Node` returned by the scanner. :return: a hash value for the implicit dependencies :rtype: string or bytes """ upd = self.m.update self.are_implicit_nodes_ready() # scanner returns a node that does not have a signature # just *ignore* the error and let them figure out from the compiler output # waf -k behaviour for k in self.generator.bld.node_deps.get(self.uid(), []): upd(k.get_bld_sig()) return self.m.digest() def are_implicit_nodes_ready(self): """ For each node returned by the scanner, see if there is a task that creates it, and infer the build order This has a low performance impact on null builds (1.86s->1.66s) thanks to caching (28s->1.86s) """ bld = self.generator.bld try: cache = bld.dct_implicit_nodes except AttributeError: bld.dct_implicit_nodes = cache = {} # one cache per build group try: dct = cache[bld.current_group] except KeyError: dct = cache[bld.current_group] = {} for tsk in bld.cur_tasks: for x in tsk.outputs: dct[x] = tsk modified = False for x in bld.node_deps.get(self.uid(), []): if x in dct: self.run_after.add(dct[x]) modified = True if modified: for tsk in self.run_after: if not tsk.hasrun: #print "task is not ready..." raise Errors.TaskNotReady('not ready') if sys.hexversion > 0x3000000: def uid(self): try: return self.uid_ except AttributeError: m = Utils.md5(self.__class__.__name__.encode('latin-1', 'xmlcharrefreplace')) up = m.update for x in self.inputs + self.outputs: up(x.abspath().encode('latin-1', 'xmlcharrefreplace')) self.uid_ = m.digest() return self.uid_ uid.__doc__ = Task.uid.__doc__ Task.uid = uid def is_before(t1, t2): """ Returns a non-zero value if task t1 is to be executed before task t2:: t1.ext_out = '.h' t2.ext_in = '.h' t2.after = ['t1'] t1.before = ['t2'] waflib.Task.is_before(t1, t2) # True :param t1: Task object :type t1: :py:class:`waflib.Task.Task` :param t2: Task object :type t2: :py:class:`waflib.Task.Task` """ to_list = Utils.to_list for k in to_list(t2.ext_in): if k in to_list(t1.ext_out): return 1 if t1.__class__.__name__ in to_list(t2.after): return 1 if t2.__class__.__name__ in to_list(t1.before): return 1 return 0 def set_file_constraints(tasks): """ Updates the ``run_after`` attribute of all tasks based on the task inputs and outputs :param tasks: tasks :type tasks: list of :py:class:`waflib.Task.Task` """ ins = Utils.defaultdict(set) outs = Utils.defaultdict(set) for x in tasks: for a in x.inputs: ins[a].add(x) for a in x.dep_nodes: ins[a].add(x) for a in x.outputs: outs[a].add(x) links = set(ins.keys()).intersection(outs.keys()) for k in links: for a in ins[k]: a.run_after.update(outs[k]) class TaskGroup(object): """ Wrap nxm task order constraints into a single object to prevent the creation of large list/set objects This is an optimization """ def __init__(self, prev, next): self.prev = prev self.next = next self.done = False def get_hasrun(self): for k in self.prev: if not k.hasrun: return NOT_RUN return SUCCESS hasrun = property(get_hasrun, None) def set_precedence_constraints(tasks): """ Updates the ``run_after`` attribute of all tasks based on the after/before/ext_out/ext_in attributes :param tasks: tasks :type tasks: list of :py:class:`waflib.Task.Task` """ cstr_groups = Utils.defaultdict(list) for x in tasks: h = x.hash_constraints() cstr_groups[h].append(x) keys = list(cstr_groups.keys()) maxi = len(keys) # this list should be short for i in range(maxi): t1 = cstr_groups[keys[i]][0] for j in range(i + 1, maxi): t2 = cstr_groups[keys[j]][0] # add the constraints based on the comparisons if is_before(t1, t2): a = i b = j elif is_before(t2, t1): a = j b = i else: continue a = cstr_groups[keys[a]] b = cstr_groups[keys[b]] if len(a) < 2 or len(b) < 2: for x in b: x.run_after.update(a) else: group = TaskGroup(set(a), set(b)) for x in b: x.run_after.add(group) def funex(c): """ Compiles a scriptlet expression into a Python function :param c: function to compile :type c: string :return: the function 'f' declared in the input string :rtype: function """ dc = {} exec(c, dc) return dc['f'] re_cond = re.compile(r'(?P\w+)|(?P\|)|(?P&)') re_novar = re.compile(r'^(SRC|TGT)\W+.*?$') reg_act = re.compile(r'(?P\\)|(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})', re.M) def compile_fun_shell(line): """ Creates a compiled function to execute a process through a sub-shell """ extr = [] def repl(match): g = match.group if g('dollar'): return "$" elif g('backslash'): return '\\\\' elif g('subst'): extr.append((g('var'), g('code'))) return "%s" return None line = reg_act.sub(repl, line) or line dvars = [] def add_dvar(x): if x not in dvars: dvars.append(x) def replc(m): # performs substitutions and populates dvars if m.group('and'): return ' and ' elif m.group('or'): return ' or ' else: x = m.group('var') add_dvar(x) return 'env[%r]' % x parm = [] app = parm.append for (var, meth) in extr: if var == 'SRC': if meth: app('tsk.inputs%s' % meth) else: app('" ".join([a.path_from(cwdx) for a in tsk.inputs])') elif var == 'TGT': if meth: app('tsk.outputs%s' % meth) else: app('" ".join([a.path_from(cwdx) for a in tsk.outputs])') elif meth: if meth.startswith(':'): add_dvar(var) m = meth[1:] if m == 'SRC': m = '[a.path_from(cwdx) for a in tsk.inputs]' elif m == 'TGT': m = '[a.path_from(cwdx) for a in tsk.outputs]' elif re_novar.match(m): m = '[tsk.inputs%s]' % m[3:] elif re_novar.match(m): m = '[tsk.outputs%s]' % m[3:] else: add_dvar(m) if m[:3] not in ('tsk', 'gen', 'bld'): m = '%r' % m app('" ".join(tsk.colon(%r, %s))' % (var, m)) elif meth.startswith('?'): # In A?B|C output env.A if one of env.B or env.C is non-empty expr = re_cond.sub(replc, meth[1:]) app('p(%r) if (%s) else ""' % (var, expr)) else: call = '%s%s' % (var, meth) add_dvar(call) app(call) else: add_dvar(var) app("p('%s')" % var) if parm: parm = "%% (%s) " % (',\n\t\t'.join(parm)) else: parm = '' c = COMPILE_TEMPLATE_SHELL % (line, parm) Logs.debug('action: %s', c.strip().splitlines()) return (funex(c), dvars) reg_act_noshell = re.compile(r"(?P\s+)|(?P\$\{(?P\w+)(?P.*?)\})|(?P([^$ \t\n\r\f\v]|\$\$)+)", re.M) def compile_fun_noshell(line): """ Creates a compiled function to execute a process without a sub-shell """ buf = [] dvars = [] merge = False app = buf.append def add_dvar(x): if x not in dvars: dvars.append(x) def replc(m): # performs substitutions and populates dvars if m.group('and'): return ' and ' elif m.group('or'): return ' or ' else: x = m.group('var') add_dvar(x) return 'env[%r]' % x for m in reg_act_noshell.finditer(line): if m.group('space'): merge = False continue elif m.group('text'): app('[%r]' % m.group('text').replace('$$', '$')) elif m.group('subst'): var = m.group('var') code = m.group('code') if var == 'SRC': if code: app('[tsk.inputs%s]' % code) else: app('[a.path_from(cwdx) for a in tsk.inputs]') elif var == 'TGT': if code: app('[tsk.outputs%s]' % code) else: app('[a.path_from(cwdx) for a in tsk.outputs]') elif code: if code.startswith(':'): # a composed variable ${FOO:OUT} add_dvar(var) m = code[1:] if m == 'SRC': m = '[a.path_from(cwdx) for a in tsk.inputs]' elif m == 'TGT': m = '[a.path_from(cwdx) for a in tsk.outputs]' elif re_novar.match(m): m = '[tsk.inputs%s]' % m[3:] elif re_novar.match(m): m = '[tsk.outputs%s]' % m[3:] else: add_dvar(m) if m[:3] not in ('tsk', 'gen', 'bld'): m = '%r' % m app('tsk.colon(%r, %s)' % (var, m)) elif code.startswith('?'): # In A?B|C output env.A if one of env.B or env.C is non-empty expr = re_cond.sub(replc, code[1:]) app('to_list(env[%r] if (%s) else [])' % (var, expr)) else: # plain code such as ${tsk.inputs[0].abspath()} call = '%s%s' % (var, code) add_dvar(call) app('to_list(%s)' % call) else: # a plain variable such as # a plain variable like ${AR} app('to_list(env[%r])' % var) add_dvar(var) if merge: tmp = 'merge(%s, %s)' % (buf[-2], buf[-1]) del buf[-1] buf[-1] = tmp merge = True # next turn buf = ['lst.extend(%s)' % x for x in buf] fun = COMPILE_TEMPLATE_NOSHELL % "\n\t".join(buf) Logs.debug('action: %s', fun.strip().splitlines()) return (funex(fun), dvars) def compile_fun(line, shell=False): """ Parses a string expression such as '${CC} ${SRC} -o ${TGT}' and returns a pair containing: * The function created (compiled) for use as :py:meth:`waflib.Task.Task.run` * The list of variables that must cause rebuilds when *env* data is modified for example:: from waflib.Task import compile_fun compile_fun('cxx', '${CXX} -o ${TGT[0]} ${SRC} -I ${SRC[0].parent.bldpath()}') def build(bld): bld(source='wscript', rule='echo "foo\\${SRC[0].name}\\bar"') The env variables (CXX, ..) on the task must not hold dicts so as to preserve a consistent order. The reserved keywords ``TGT`` and ``SRC`` represent the task input and output nodes """ if isinstance(line, str): if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0: shell = True else: dvars_lst = [] funs_lst = [] for x in line: if isinstance(x, str): fun, dvars = compile_fun(x, shell) dvars_lst += dvars funs_lst.append(fun) else: # assume a function to let through funs_lst.append(x) def composed_fun(task): for x in funs_lst: ret = x(task) if ret: return ret return None return composed_fun, dvars_lst if shell: return compile_fun_shell(line) else: return compile_fun_noshell(line) def compile_sig_vars(vars): """ This method produces a sig_vars method suitable for subclasses that provide scriptlet code in their run_str code. If no such method can be created, this method returns None. The purpose of the sig_vars method returned is to ensures that rebuilds occur whenever the contents of the expression changes. This is the case B below:: import time # case A: regular variables tg = bld(rule='echo ${FOO}') tg.env.FOO = '%s' % time.time() # case B bld(rule='echo ${gen.foo}', foo='%s' % time.time()) :param vars: env variables such as CXXFLAGS or gen.foo :type vars: list of string :return: A sig_vars method relevant for dependencies if adequate, else None :rtype: A function, or None in most cases """ buf = [] for x in sorted(vars): if x[:3] in ('tsk', 'gen', 'bld'): buf.append('buf.append(%s)' % x) if buf: return funex(COMPILE_TEMPLATE_SIG_VARS % '\n\t'.join(buf)) return None def task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[], before=[], after=[], shell=False, scan=None): """ Returns a new task subclass with the function ``run`` compiled from the line given. :param func: method run :type func: string or function :param vars: list of variables to hash :type vars: list of string :param color: color to use :type color: string :param shell: when *func* is a string, enable/disable the use of the shell :type shell: bool :param scan: method scan :type scan: function :rtype: :py:class:`waflib.Task.Task` """ params = { 'vars': vars or [], # function arguments are static, and this one may be modified by the class 'color': color, 'name': name, 'shell': shell, 'scan': scan, } if isinstance(func, str) or isinstance(func, tuple): params['run_str'] = func else: params['run'] = func cls = type(Task)(name, (Task,), params) classes[name] = cls if ext_in: cls.ext_in = Utils.to_list(ext_in) if ext_out: cls.ext_out = Utils.to_list(ext_out) if before: cls.before = Utils.to_list(before) if after: cls.after = Utils.to_list(after) return cls def deep_inputs(cls): """ Task class decorator to enable rebuilds on input files task signatures """ def sig_explicit_deps(self): Task.sig_explicit_deps(self) Task.sig_deep_inputs(self) cls.sig_explicit_deps = sig_explicit_deps return cls TaskBase = Task "Provided for compatibility reasons, TaskBase should not be used" class TaskSemaphore(object): """ Task semaphores provide a simple and efficient way of throttling the amount of a particular task to run concurrently. The throttling value is capped by the amount of maximum jobs, so for example, a `TaskSemaphore(10)` has no effect in a `-j2` build. Task semaphores are typically specified on the task class level:: class compile(waflib.Task.Task): semaphore = waflib.Task.TaskSemaphore(2) run_str = 'touch ${TGT}' Task semaphores are meant to be used by the build scheduler in the main thread, so there are no guarantees of thread safety. """ def __init__(self, num): """ :param num: maximum value of concurrent tasks :type num: int """ self.num = num self.locking = set() self.waiting = set() def is_locked(self): """Returns True if this semaphore cannot be acquired by more tasks""" return len(self.locking) >= self.num def acquire(self, tsk): """ Mark the semaphore as used by the given task (not re-entrant). :param tsk: task object :type tsk: :py:class:`waflib.Task.Task` :raises: :py:class:`IndexError` in case the resource is already acquired """ if self.is_locked(): raise IndexError('Cannot lock more %r' % self.locking) self.locking.add(tsk) def release(self, tsk): """ Mark the semaphore as unused by the given task. :param tsk: task object :type tsk: :py:class:`waflib.Task.Task` :raises: :py:class:`KeyError` in case the resource is not acquired by the task """ self.locking.remove(tsk) ldb-2.0.8/third_party/waf/waflib/TaskGen.py0000660000000000000000000006410013573675414020516 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Task generators The class :py:class:`waflib.TaskGen.task_gen` encapsulates the creation of task objects (low-level code) The instances can have various parameters, but the creation of task nodes (Task.py) is deferred. To achieve this, various methods are called from the method "apply" """ import copy, re, os, functools from waflib import Task, Utils, Logs, Errors, ConfigSet, Node feats = Utils.defaultdict(set) """remember the methods declaring features""" HEADER_EXTS = ['.h', '.hpp', '.hxx', '.hh'] class task_gen(object): """ Instances of this class create :py:class:`waflib.Task.Task` when calling the method :py:meth:`waflib.TaskGen.task_gen.post` from the main thread. A few notes: * The methods to call (*self.meths*) can be specified dynamically (removing, adding, ..) * The 'features' are used to add methods to self.meths and then execute them * The attribute 'path' is a node representing the location of the task generator * The tasks created are added to the attribute *tasks* * The attribute 'idx' is a counter of task generators in the same path """ mappings = Utils.ordered_iter_dict() """Mappings are global file extension mappings that are retrieved in the order of definition""" prec = Utils.defaultdict(set) """Dict that holds the precedence execution rules for task generator methods""" def __init__(self, *k, **kw): """ Task generator objects predefine various attributes (source, target) for possible processing by process_rule (make-like rules) or process_source (extensions, misc methods) Tasks are stored on the attribute 'tasks'. They are created by calling methods listed in ``self.meths`` or referenced in the attribute ``features`` A topological sort is performed to execute the methods in correct order. The extra key/value elements passed in ``kw`` are set as attributes """ self.source = [] self.target = '' self.meths = [] """ List of method names to execute (internal) """ self.features = [] """ List of feature names for bringing new methods in """ self.tasks = [] """ Tasks created are added to this list """ if not 'bld' in kw: # task generators without a build context :-/ self.env = ConfigSet.ConfigSet() self.idx = 0 self.path = None else: self.bld = kw['bld'] self.env = self.bld.env.derive() self.path = kw.get('path', self.bld.path) # by default, emulate chdir when reading scripts # Provide a unique index per folder # This is part of a measure to prevent output file name collisions path = self.path.abspath() try: self.idx = self.bld.idx[path] = self.bld.idx.get(path, 0) + 1 except AttributeError: self.bld.idx = {} self.idx = self.bld.idx[path] = 1 # Record the global task generator count try: self.tg_idx_count = self.bld.tg_idx_count = self.bld.tg_idx_count + 1 except AttributeError: self.tg_idx_count = self.bld.tg_idx_count = 1 for key, val in kw.items(): setattr(self, key, val) def __str__(self): """Debugging helper""" return "" % (self.name, self.path.abspath()) def __repr__(self): """Debugging helper""" lst = [] for x in self.__dict__: if x not in ('env', 'bld', 'compiled_tasks', 'tasks'): lst.append("%s=%s" % (x, repr(getattr(self, x)))) return "bld(%s) in %s" % (", ".join(lst), self.path.abspath()) def get_cwd(self): """ Current working directory for the task generator, defaults to the build directory. This is still used in a few places but it should disappear at some point as the classes define their own working directory. :rtype: :py:class:`waflib.Node.Node` """ return self.bld.bldnode def get_name(self): """ If the attribute ``name`` is not set on the instance, the name is computed from the target name:: def build(bld): x = bld(name='foo') x.get_name() # foo y = bld(target='bar') y.get_name() # bar :rtype: string :return: name of this task generator """ try: return self._name except AttributeError: if isinstance(self.target, list): lst = [str(x) for x in self.target] name = self._name = ','.join(lst) else: name = self._name = str(self.target) return name def set_name(self, name): self._name = name name = property(get_name, set_name) def to_list(self, val): """ Ensures that a parameter is a list, see :py:func:`waflib.Utils.to_list` :type val: string or list of string :param val: input to return as a list :rtype: list """ if isinstance(val, str): return val.split() else: return val def post(self): """ Creates tasks for this task generators. The following operations are performed: #. The body of this method is called only once and sets the attribute ``posted`` #. The attribute ``features`` is used to add more methods in ``self.meths`` #. The methods are sorted by the precedence table ``self.prec`` or `:waflib:attr:waflib.TaskGen.task_gen.prec` #. The methods are then executed in order #. The tasks created are added to :py:attr:`waflib.TaskGen.task_gen.tasks` """ if getattr(self, 'posted', None): return False self.posted = True keys = set(self.meths) keys.update(feats['*']) # add the methods listed in the features self.features = Utils.to_list(self.features) for x in self.features: st = feats[x] if st: keys.update(st) elif not x in Task.classes: Logs.warn('feature %r does not exist - bind at least one method to it?', x) # copy the precedence table prec = {} prec_tbl = self.prec for x in prec_tbl: if x in keys: prec[x] = prec_tbl[x] # elements disconnected tmp = [] for a in keys: for x in prec.values(): if a in x: break else: tmp.append(a) tmp.sort(reverse=True) # topological sort out = [] while tmp: e = tmp.pop() if e in keys: out.append(e) try: nlst = prec[e] except KeyError: pass else: del prec[e] for x in nlst: for y in prec: if x in prec[y]: break else: tmp.append(x) tmp.sort(reverse=True) if prec: buf = ['Cycle detected in the method execution:'] for k, v in prec.items(): buf.append('- %s after %s' % (k, [x for x in v if x in prec])) raise Errors.WafError('\n'.join(buf)) self.meths = out # then we run the methods in order Logs.debug('task_gen: posting %s %d', self, id(self)) for x in out: try: v = getattr(self, x) except AttributeError: raise Errors.WafError('%r is not a valid task generator method' % x) Logs.debug('task_gen: -> %s (%d)', x, id(self)) v() Logs.debug('task_gen: posted %s', self.name) return True def get_hook(self, node): """ Returns the ``@extension`` method to call for a Node of a particular extension. :param node: Input file to process :type node: :py:class:`waflib.Tools.Node.Node` :return: A method able to process the input node by looking at the extension :rtype: function """ name = node.name for k in self.mappings: try: if name.endswith(k): return self.mappings[k] except TypeError: # regexps objects if k.match(name): return self.mappings[k] keys = list(self.mappings.keys()) raise Errors.WafError("File %r has no mapping in %r (load a waf tool?)" % (node, keys)) def create_task(self, name, src=None, tgt=None, **kw): """ Creates task instances. :param name: task class name :type name: string :param src: input nodes :type src: list of :py:class:`waflib.Tools.Node.Node` :param tgt: output nodes :type tgt: list of :py:class:`waflib.Tools.Node.Node` :return: A task object :rtype: :py:class:`waflib.Task.Task` """ task = Task.classes[name](env=self.env.derive(), generator=self) if src: task.set_inputs(src) if tgt: task.set_outputs(tgt) task.__dict__.update(kw) self.tasks.append(task) return task def clone(self, env): """ Makes a copy of a task generator. Once the copy is made, it is necessary to ensure that the it does not create the same output files as the original, or the same files may be compiled several times. :param env: A configuration set :type env: :py:class:`waflib.ConfigSet.ConfigSet` :return: A copy :rtype: :py:class:`waflib.TaskGen.task_gen` """ newobj = self.bld() for x in self.__dict__: if x in ('env', 'bld'): continue elif x in ('path', 'features'): setattr(newobj, x, getattr(self, x)) else: setattr(newobj, x, copy.copy(getattr(self, x))) newobj.posted = False if isinstance(env, str): newobj.env = self.bld.all_envs[env].derive() else: newobj.env = env.derive() return newobj def declare_chain(name='', rule=None, reentrant=None, color='BLUE', ext_in=[], ext_out=[], before=[], after=[], decider=None, scan=None, install_path=None, shell=False): """ Creates a new mapping and a task class for processing files by extension. See Tools/flex.py for an example. :param name: name for the task class :type name: string :param rule: function to execute or string to be compiled in a function :type rule: string or function :param reentrant: re-inject the output file in the process (done automatically, set to 0 to disable) :type reentrant: int :param color: color for the task output :type color: string :param ext_in: execute the task only after the files of such extensions are created :type ext_in: list of string :param ext_out: execute the task only before files of such extensions are processed :type ext_out: list of string :param before: execute instances of this task before classes of the given names :type before: list of string :param after: execute instances of this task after classes of the given names :type after: list of string :param decider: if present, function that returns a list of output file extensions (overrides ext_out for output files, but not for the build order) :type decider: function :param scan: scanner function for the task :type scan: function :param install_path: installation path for the output nodes :type install_path: string """ ext_in = Utils.to_list(ext_in) ext_out = Utils.to_list(ext_out) if not name: name = rule cls = Task.task_factory(name, rule, color=color, ext_in=ext_in, ext_out=ext_out, before=before, after=after, scan=scan, shell=shell) def x_file(self, node): if ext_in: _ext_in = ext_in[0] tsk = self.create_task(name, node) cnt = 0 ext = decider(self, node) if decider else cls.ext_out for x in ext: k = node.change_ext(x, ext_in=_ext_in) tsk.outputs.append(k) if reentrant != None: if cnt < int(reentrant): self.source.append(k) else: # reinject downstream files into the build for y in self.mappings: # ~ nfile * nextensions :-/ if k.name.endswith(y): self.source.append(k) break cnt += 1 if install_path: self.install_task = self.add_install_files(install_to=install_path, install_from=tsk.outputs) return tsk for x in cls.ext_in: task_gen.mappings[x] = x_file return x_file def taskgen_method(func): """ Decorator that registers method as a task generator method. The function must accept a task generator as first parameter:: from waflib.TaskGen import taskgen_method @taskgen_method def mymethod(self): pass :param func: task generator method to add :type func: function :rtype: function """ setattr(task_gen, func.__name__, func) return func def feature(*k): """ Decorator that registers a task generator method that will be executed when the object attribute ``feature`` contains the corresponding key(s):: from waflib.Task import feature @feature('myfeature') def myfunction(self): print('that is my feature!') def build(bld): bld(features='myfeature') :param k: feature names :type k: list of string """ def deco(func): setattr(task_gen, func.__name__, func) for name in k: feats[name].update([func.__name__]) return func return deco def before_method(*k): """ Decorator that registera task generator method which will be executed before the functions of given name(s):: from waflib.TaskGen import feature, before @feature('myfeature') @before_method('fun2') def fun1(self): print('feature 1!') @feature('myfeature') def fun2(self): print('feature 2!') def build(bld): bld(features='myfeature') :param k: method names :type k: list of string """ def deco(func): setattr(task_gen, func.__name__, func) for fun_name in k: task_gen.prec[func.__name__].add(fun_name) return func return deco before = before_method def after_method(*k): """ Decorator that registers a task generator method which will be executed after the functions of given name(s):: from waflib.TaskGen import feature, after @feature('myfeature') @after_method('fun2') def fun1(self): print('feature 1!') @feature('myfeature') def fun2(self): print('feature 2!') def build(bld): bld(features='myfeature') :param k: method names :type k: list of string """ def deco(func): setattr(task_gen, func.__name__, func) for fun_name in k: task_gen.prec[fun_name].add(func.__name__) return func return deco after = after_method def extension(*k): """ Decorator that registers a task generator method which will be invoked during the processing of source files for the extension given:: from waflib import Task class mytask(Task): run_str = 'cp ${SRC} ${TGT}' @extension('.moo') def create_maa_file(self, node): self.create_task('mytask', node, node.change_ext('.maa')) def build(bld): bld(source='foo.moo') """ def deco(func): setattr(task_gen, func.__name__, func) for x in k: task_gen.mappings[x] = func return func return deco @taskgen_method def to_nodes(self, lst, path=None): """ Flatten the input list of string/nodes/lists into a list of nodes. It is used by :py:func:`waflib.TaskGen.process_source` and :py:func:`waflib.TaskGen.process_rule`. It is designed for source files, for folders, see :py:func:`waflib.Tools.ccroot.to_incnodes`: :param lst: input list :type lst: list of string and nodes :param path: path from which to search the nodes (by default, :py:attr:`waflib.TaskGen.task_gen.path`) :type path: :py:class:`waflib.Tools.Node.Node` :rtype: list of :py:class:`waflib.Tools.Node.Node` """ tmp = [] path = path or self.path find = path.find_resource if isinstance(lst, Node.Node): lst = [lst] for x in Utils.to_list(lst): if isinstance(x, str): node = find(x) elif hasattr(x, 'name'): node = x else: tmp.extend(self.to_nodes(x)) continue if not node: raise Errors.WafError('source not found: %r in %r' % (x, self)) tmp.append(node) return tmp @feature('*') def process_source(self): """ Processes each element in the attribute ``source`` by extension. #. The *source* list is converted through :py:meth:`waflib.TaskGen.to_nodes` to a list of :py:class:`waflib.Node.Node` first. #. File extensions are mapped to methods having the signature: ``def meth(self, node)`` by :py:meth:`waflib.TaskGen.extension` #. The method is retrieved through :py:meth:`waflib.TaskGen.task_gen.get_hook` #. When called, the methods may modify self.source to append more source to process #. The mappings can map an extension or a filename (see the code below) """ self.source = self.to_nodes(getattr(self, 'source', [])) for node in self.source: self.get_hook(node)(self, node) @feature('*') @before_method('process_source') def process_rule(self): """ Processes the attribute ``rule``. When present, :py:meth:`waflib.TaskGen.process_source` is disabled:: def build(bld): bld(rule='cp ${SRC} ${TGT}', source='wscript', target='bar.txt') Main attributes processed: * rule: command to execute, it can be a tuple of strings for multiple commands * chmod: permissions for the resulting files (integer value such as Utils.O755) * shell: set to False to execute the command directly (default is True to use a shell) * scan: scanner function * vars: list of variables to trigger rebuilds, such as CFLAGS * cls_str: string to display when executing the task * cls_keyword: label to display when executing the task * cache_rule: by default, try to re-use similar classes, set to False to disable * source: list of Node or string objects representing the source files required by this task * target: list of Node or string objects representing the files that this task creates * cwd: current working directory (Node or string) * stdout: standard output, set to None to prevent waf from capturing the text * stderr: standard error, set to None to prevent waf from capturing the text * timeout: timeout for command execution (Python 3) * always: whether to always run the command (False by default) * deep_inputs: whether the task must depend on the input file tasks too (False by default) """ if not getattr(self, 'rule', None): return # create the task class name = str(getattr(self, 'name', None) or self.target or getattr(self.rule, '__name__', self.rule)) # or we can put the class in a cache for performance reasons try: cache = self.bld.cache_rule_attr except AttributeError: cache = self.bld.cache_rule_attr = {} chmod = getattr(self, 'chmod', None) shell = getattr(self, 'shell', True) color = getattr(self, 'color', 'BLUE') scan = getattr(self, 'scan', None) _vars = getattr(self, 'vars', []) cls_str = getattr(self, 'cls_str', None) cls_keyword = getattr(self, 'cls_keyword', None) use_cache = getattr(self, 'cache_rule', 'True') deep_inputs = getattr(self, 'deep_inputs', False) scan_val = has_deps = hasattr(self, 'deps') if scan: scan_val = id(scan) key = Utils.h_list((name, self.rule, chmod, shell, color, cls_str, cls_keyword, scan_val, _vars, deep_inputs)) cls = None if use_cache: try: cls = cache[key] except KeyError: pass if not cls: rule = self.rule if chmod is not None: def chmod_fun(tsk): for x in tsk.outputs: os.chmod(x.abspath(), tsk.generator.chmod) if isinstance(rule, tuple): rule = list(rule) rule.append(chmod_fun) rule = tuple(rule) else: rule = (rule, chmod_fun) cls = Task.task_factory(name, rule, _vars, shell=shell, color=color) if cls_str: setattr(cls, '__str__', self.cls_str) if cls_keyword: setattr(cls, 'keyword', self.cls_keyword) if deep_inputs: Task.deep_inputs(cls) if scan: cls.scan = self.scan elif has_deps: def scan(self): nodes = [] for x in self.generator.to_list(getattr(self.generator, 'deps', None)): node = self.generator.path.find_resource(x) if not node: self.generator.bld.fatal('Could not find %r (was it declared?)' % x) nodes.append(node) return [nodes, []] cls.scan = scan if use_cache: cache[key] = cls # now create one instance tsk = self.create_task(name) for x in ('after', 'before', 'ext_in', 'ext_out'): setattr(tsk, x, getattr(self, x, [])) if hasattr(self, 'stdout'): tsk.stdout = self.stdout if hasattr(self, 'stderr'): tsk.stderr = self.stderr if getattr(self, 'timeout', None): tsk.timeout = self.timeout if getattr(self, 'always', None): tsk.always_run = True if getattr(self, 'target', None): if isinstance(self.target, str): self.target = self.target.split() if not isinstance(self.target, list): self.target = [self.target] for x in self.target: if isinstance(x, str): tsk.outputs.append(self.path.find_or_declare(x)) else: x.parent.mkdir() # if a node was given, create the required folders tsk.outputs.append(x) if getattr(self, 'install_path', None): self.install_task = self.add_install_files(install_to=self.install_path, install_from=tsk.outputs, chmod=getattr(self, 'chmod', Utils.O644)) if getattr(self, 'source', None): tsk.inputs = self.to_nodes(self.source) # bypass the execution of process_source by setting the source to an empty list self.source = [] if getattr(self, 'cwd', None): tsk.cwd = self.cwd if isinstance(tsk.run, functools.partial): # Python documentation says: "partial objects defined in classes # behave like static methods and do not transform into bound # methods during instance attribute look-up." tsk.run = functools.partial(tsk.run, tsk) @feature('seq') def sequence_order(self): """ Adds a strict sequential constraint between the tasks generated by task generators. It works because task generators are posted in order. It will not post objects which belong to other folders. Example:: bld(features='javac seq') bld(features='jar seq') To start a new sequence, set the attribute seq_start, for example:: obj = bld(features='seq') obj.seq_start = True Note that the method is executed in last position. This is more an example than a widely-used solution. """ if self.meths and self.meths[-1] != 'sequence_order': self.meths.append('sequence_order') return if getattr(self, 'seq_start', None): return # all the tasks previously declared must be run before these if getattr(self.bld, 'prev', None): self.bld.prev.post() for x in self.bld.prev.tasks: for y in self.tasks: y.set_run_after(x) self.bld.prev = self re_m4 = re.compile(r'@(\w+)@', re.M) class subst_pc(Task.Task): """ Creates *.pc* files from *.pc.in*. The task is executed whenever an input variable used in the substitution changes. """ def force_permissions(self): "Private for the time being, we will probably refactor this into run_str=[run1,chmod]" if getattr(self.generator, 'chmod', None): for x in self.outputs: os.chmod(x.abspath(), self.generator.chmod) def run(self): "Substitutes variables in a .in file" if getattr(self.generator, 'is_copy', None): for i, x in enumerate(self.outputs): x.write(self.inputs[i].read('rb'), 'wb') stat = os.stat(self.inputs[i].abspath()) # Preserve mtime of the copy os.utime(self.outputs[i].abspath(), (stat.st_atime, stat.st_mtime)) self.force_permissions() return None if getattr(self.generator, 'fun', None): ret = self.generator.fun(self) if not ret: self.force_permissions() return ret code = self.inputs[0].read(encoding=getattr(self.generator, 'encoding', 'latin-1')) if getattr(self.generator, 'subst_fun', None): code = self.generator.subst_fun(self, code) if code is not None: self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'latin-1')) self.force_permissions() return None # replace all % by %% to prevent errors by % signs code = code.replace('%', '%%') # extract the vars foo into lst and replace @foo@ by %(foo)s lst = [] def repl(match): g = match.group if g(1): lst.append(g(1)) return "%%(%s)s" % g(1) return '' code = getattr(self.generator, 're_m4', re_m4).sub(repl, code) try: d = self.generator.dct except AttributeError: d = {} for x in lst: tmp = getattr(self.generator, x, '') or self.env[x] or self.env[x.upper()] try: tmp = ''.join(tmp) except TypeError: tmp = str(tmp) d[x] = tmp code = code % d self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'latin-1')) self.generator.bld.raw_deps[self.uid()] = lst # make sure the signature is updated try: delattr(self, 'cache_sig') except AttributeError: pass self.force_permissions() def sig_vars(self): """ Compute a hash (signature) of the variables used in the substitution """ bld = self.generator.bld env = self.env upd = self.m.update if getattr(self.generator, 'fun', None): upd(Utils.h_fun(self.generator.fun).encode()) if getattr(self.generator, 'subst_fun', None): upd(Utils.h_fun(self.generator.subst_fun).encode()) # raw_deps: persistent custom values returned by the scanner vars = self.generator.bld.raw_deps.get(self.uid(), []) # hash both env vars and task generator attributes act_sig = bld.hash_env_vars(env, vars) upd(act_sig) lst = [getattr(self.generator, x, '') for x in vars] upd(Utils.h_list(lst)) return self.m.digest() @extension('.pc.in') def add_pcfile(self, node): """ Processes *.pc.in* files to *.pc*. Installs the results to ``${PREFIX}/lib/pkgconfig/`` by default def build(bld): bld(source='foo.pc.in', install_path='${LIBDIR}/pkgconfig/') """ tsk = self.create_task('subst_pc', node, node.change_ext('.pc', '.pc.in')) self.install_task = self.add_install_files( install_to=getattr(self, 'install_path', '${LIBDIR}/pkgconfig/'), install_from=tsk.outputs) class subst(subst_pc): pass @feature('subst') @before_method('process_source', 'process_rule') def process_subst(self): """ Defines a transformation that substitutes the contents of *source* files to *target* files:: def build(bld): bld( features='subst', source='foo.c.in', target='foo.c', install_path='${LIBDIR}/pkgconfig', VAR = 'val' ) The input files are supposed to contain macros of the form *@VAR@*, where *VAR* is an argument of the task generator object. This method overrides the processing by :py:meth:`waflib.TaskGen.process_source`. """ src = Utils.to_list(getattr(self, 'source', [])) if isinstance(src, Node.Node): src = [src] tgt = Utils.to_list(getattr(self, 'target', [])) if isinstance(tgt, Node.Node): tgt = [tgt] if len(src) != len(tgt): raise Errors.WafError('invalid number of source/target for %r' % self) for x, y in zip(src, tgt): if not x or not y: raise Errors.WafError('null source or target for %r' % self) a, b = None, None if isinstance(x, str) and isinstance(y, str) and x == y: a = self.path.find_node(x) b = self.path.get_bld().make_node(y) if not os.path.isfile(b.abspath()): b.parent.mkdir() else: if isinstance(x, str): a = self.path.find_resource(x) elif isinstance(x, Node.Node): a = x if isinstance(y, str): b = self.path.find_or_declare(y) elif isinstance(y, Node.Node): b = y if not a: raise Errors.WafError('could not find %r for %r' % (x, self)) tsk = self.create_task('subst', a, b) for k in ('after', 'before', 'ext_in', 'ext_out'): val = getattr(self, k, None) if val: setattr(tsk, k, val) # paranoid safety measure for the general case foo.in->foo.h with ambiguous dependencies for xt in HEADER_EXTS: if b.name.endswith(xt): tsk.ext_out = tsk.ext_out + ['.h'] break inst_to = getattr(self, 'install_path', None) if inst_to: self.install_task = self.add_install_files(install_to=inst_to, install_from=b, chmod=getattr(self, 'chmod', Utils.O644)) self.source = [] ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py0000660000000000000000000000010713573675414022016 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) ldb-2.0.8/third_party/waf/waflib/Tools/ar.py0000660000000000000000000000117213573675414020664 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) # Ralf Habacker, 2006 (rh) """ The **ar** program creates static libraries. This tool is almost always loaded from others (C, C++, D, etc) for static library support. """ from waflib.Configure import conf @conf def find_ar(conf): """Configuration helper used by C/C++ tools to enable the support for static libraries""" conf.load('ar') def configure(conf): """Finds the ar program and sets the default flags in ``conf.env.ARFLAGS``""" conf.find_program('ar', var='AR') conf.add_os_flags('ARFLAGS') if not conf.env.ARFLAGS: conf.env.ARFLAGS = ['rcs'] ldb-2.0.8/third_party/waf/waflib/Tools/asm.py0000660000000000000000000000525613573675414021051 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2008-2018 (ita) """ Assembly support, used by tools such as gas and nasm To declare targets using assembly:: def configure(conf): conf.load('gcc gas') def build(bld): bld( features='c cstlib asm', source = 'test.S', target = 'asmtest') bld( features='asm asmprogram', source = 'test.S', target = 'asmtest') Support for pure asm programs and libraries should also work:: def configure(conf): conf.load('nasm') conf.find_program('ld', 'ASLINK') def build(bld): bld( features='asm asmprogram', source = 'test.S', target = 'asmtest') """ import re from waflib import Errors, Logs, Task from waflib.Tools.ccroot import link_task, stlink_task from waflib.TaskGen import extension from waflib.Tools import c_preproc re_lines = re.compile( '^[ \t]*(?:%)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef)[ \t]*(.*)\r*$', re.IGNORECASE | re.MULTILINE) class asm_parser(c_preproc.c_parser): def filter_comments(self, node): code = node.read() code = c_preproc.re_nl.sub('', code) code = c_preproc.re_cpp.sub(c_preproc.repl, code) return re_lines.findall(code) class asm(Task.Task): """ Compiles asm files by gas/nasm/yasm/... """ color = 'BLUE' run_str = '${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}' def scan(self): if self.env.ASM_NAME == 'gas': return c_preproc.scan(self) Logs.warn('There is no dependency scanner for Nasm!') return [[], []] elif self.env.ASM_NAME == 'nasm': Logs.warn('The Nasm dependency scanner is incomplete!') try: incn = self.generator.includes_nodes except AttributeError: raise Errors.WafError('%r is missing the "asm" feature' % self.generator) if c_preproc.go_absolute: nodepaths = incn else: nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)] tmp = asm_parser(nodepaths) tmp.start(self.inputs[0], self.env) return (tmp.nodes, tmp.names) @extension('.s', '.S', '.asm', '.ASM', '.spp', '.SPP') def asm_hook(self, node): """ Binds the asm extension to the asm task :param node: input file :type node: :py:class:`waflib.Node.Node` """ return self.create_compiled_task('asm', node) class asmprogram(link_task): "Links object files into a c program" run_str = '${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}' ext_out = ['.bin'] inst_to = '${BINDIR}' class asmshlib(asmprogram): "Links object files into a c shared library" inst_to = '${LIBDIR}' class asmstlib(stlink_task): "Links object files into a c static library" pass # do not remove def configure(conf): conf.env.ASMPATH_ST = '-I%s' ldb-2.0.8/third_party/waf/waflib/Tools/bison.py0000660000000000000000000000224313573675414021374 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # John O'Meara, 2006 # Thomas Nagy 2009-2018 (ita) """ The **bison** program is a code generator which creates C or C++ files. The generated files are compiled into object files. """ from waflib import Task from waflib.TaskGen import extension class bison(Task.Task): """Compiles bison files""" color = 'BLUE' run_str = '${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}' ext_out = ['.h'] # just to make sure @extension('.y', '.yc', '.yy') def big_bison(self, node): """ Creates a bison task, which must be executed from the directory of the output file. """ has_h = '-d' in self.env.BISONFLAGS outs = [] if node.name.endswith('.yc'): outs.append(node.change_ext('.tab.cc')) if has_h: outs.append(node.change_ext('.tab.hh')) else: outs.append(node.change_ext('.tab.c')) if has_h: outs.append(node.change_ext('.tab.h')) tsk = self.create_task('bison', node, outs) tsk.cwd = node.parent.get_bld() # and the c/cxx file must be compiled too self.source.append(outs[0]) def configure(conf): """ Detects the *bison* program """ conf.find_program('bison', var='BISON') conf.env.BISONFLAGS = ['-d'] ldb-2.0.8/third_party/waf/waflib/Tools/c.py0000660000000000000000000000277113573675414020512 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) "Base for c programs/libraries" from waflib import TaskGen, Task from waflib.Tools import c_preproc from waflib.Tools.ccroot import link_task, stlink_task @TaskGen.extension('.c') def c_hook(self, node): "Binds the c file extensions create :py:class:`waflib.Tools.c.c` instances" if not self.env.CC and self.env.CXX: return self.create_compiled_task('cxx', node) return self.create_compiled_task('c', node) class c(Task.Task): "Compiles C files into object files" run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' vars = ['CCDEPS'] # unused variable to depend on, just in case ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] scan = c_preproc.scan class cprogram(link_task): "Links object files into c programs" run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' ext_out = ['.bin'] vars = ['LINKDEPS'] inst_to = '${BINDIR}' class cshlib(cprogram): "Links object files into c shared libraries" inst_to = '${LIBDIR}' class cstlib(stlink_task): "Links object files into a c static libraries" pass # do not remove ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py0000660000000000000000000000675013573675414022214 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2015 (ita) "base for all c/c++ programs and libraries" from waflib import Utils, Errors from waflib.Configure import conf def get_extensions(lst): """ Returns the file extensions for the list of files given as input :param lst: files to process :list lst: list of string or :py:class:`waflib.Node.Node` :return: list of file extensions :rtype: list of string """ ret = [] for x in Utils.to_list(lst): if not isinstance(x, str): x = x.name ret.append(x[x.rfind('.') + 1:]) return ret def sniff_features(**kw): """ Computes and returns the features required for a task generator by looking at the file extensions. This aimed for C/C++ mainly:: snif_features(source=['foo.c', 'foo.cxx'], type='shlib') # returns ['cxx', 'c', 'cxxshlib', 'cshlib'] :param source: source files to process :type source: list of string or :py:class:`waflib.Node.Node` :param type: object type in *program*, *shlib* or *stlib* :type type: string :return: the list of features for a task generator processing the source files :rtype: list of string """ exts = get_extensions(kw['source']) typ = kw['typ'] feats = [] # watch the order, cxx will have the precedence for x in 'cxx cpp c++ cc C'.split(): if x in exts: feats.append('cxx') break if 'c' in exts or 'vala' in exts or 'gs' in exts: feats.append('c') if 's' in exts or 'S' in exts: feats.append('asm') for x in 'f f90 F F90 for FOR'.split(): if x in exts: feats.append('fc') break if 'd' in exts: feats.append('d') if 'java' in exts: feats.append('java') return 'java' if typ in ('program', 'shlib', 'stlib'): will_link = False for x in feats: if x in ('cxx', 'd', 'fc', 'c', 'asm'): feats.append(x + typ) will_link = True if not will_link and not kw.get('features', []): raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?' % kw) return feats def set_features(kw, typ): """ Inserts data in the input dict *kw* based on existing data and on the type of target required (typ). :param kw: task generator parameters :type kw: dict :param typ: type of target :type typ: string """ kw['typ'] = typ kw['features'] = Utils.to_list(kw.get('features', [])) + Utils.to_list(sniff_features(**kw)) @conf def program(bld, *k, **kw): """ Alias for creating programs by looking at the file extensions:: def build(bld): bld.program(source='foo.c', target='app') # equivalent to: # bld(features='c cprogram', source='foo.c', target='app') """ set_features(kw, 'program') return bld(*k, **kw) @conf def shlib(bld, *k, **kw): """ Alias for creating shared libraries by looking at the file extensions:: def build(bld): bld.shlib(source='foo.c', target='app') # equivalent to: # bld(features='c cshlib', source='foo.c', target='app') """ set_features(kw, 'shlib') return bld(*k, **kw) @conf def stlib(bld, *k, **kw): """ Alias for creating static libraries by looking at the file extensions:: def build(bld): bld.stlib(source='foo.cpp', target='app') # equivalent to: # bld(features='cxx cxxstlib', source='foo.cpp', target='app') """ set_features(kw, 'stlib') return bld(*k, **kw) @conf def objects(bld, *k, **kw): """ Alias for creating object files by looking at the file extensions:: def build(bld): bld.objects(source='foo.c', target='app') # equivalent to: # bld(features='c', source='foo.c', target='app') """ set_features(kw, 'objects') return bld(*k, **kw) ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py0000660000000000000000000012016013573675414022030 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ C/C++/D configuration helpers """ from __future__ import with_statement import os, re, shlex from waflib import Build, Utils, Task, Options, Logs, Errors, Runner from waflib.TaskGen import after_method, feature from waflib.Configure import conf WAF_CONFIG_H = 'config.h' """default name for the config.h file""" DEFKEYS = 'define_key' INCKEYS = 'include_key' SNIP_EMPTY_PROGRAM = ''' int main(int argc, char **argv) { (void)argc; (void)argv; return 0; } ''' MACRO_TO_DESTOS = { '__linux__' : 'linux', '__GNU__' : 'gnu', # hurd '__FreeBSD__' : 'freebsd', '__NetBSD__' : 'netbsd', '__OpenBSD__' : 'openbsd', '__sun' : 'sunos', '__hpux' : 'hpux', '__sgi' : 'irix', '_AIX' : 'aix', '__CYGWIN__' : 'cygwin', '__MSYS__' : 'cygwin', '_UWIN' : 'uwin', '_WIN64' : 'win32', '_WIN32' : 'win32', # Note about darwin: this is also tested with 'defined __APPLE__ && defined __MACH__' somewhere below in this file. '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' : 'darwin', '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' : 'darwin', # iphone '__QNX__' : 'qnx', '__native_client__' : 'nacl' # google native client platform } MACRO_TO_DEST_CPU = { '__x86_64__' : 'x86_64', '__amd64__' : 'x86_64', '__i386__' : 'x86', '__ia64__' : 'ia', '__mips__' : 'mips', '__sparc__' : 'sparc', '__alpha__' : 'alpha', '__aarch64__' : 'aarch64', '__thumb__' : 'thumb', '__arm__' : 'arm', '__hppa__' : 'hppa', '__powerpc__' : 'powerpc', '__ppc__' : 'powerpc', '__convex__' : 'convex', '__m68k__' : 'm68k', '__s390x__' : 's390x', '__s390__' : 's390', '__sh__' : 'sh', '__xtensa__' : 'xtensa', } @conf def parse_flags(self, line, uselib_store, env=None, force_static=False, posix=None): """ Parses flags from the input lines, and adds them to the relevant use variables:: def configure(conf): conf.parse_flags('-O3', 'FOO') # conf.env.CXXFLAGS_FOO = ['-O3'] # conf.env.CFLAGS_FOO = ['-O3'] :param line: flags :type line: string :param uselib_store: where to add the flags :type uselib_store: string :param env: config set or conf.env by default :type env: :py:class:`waflib.ConfigSet.ConfigSet` """ assert(isinstance(line, str)) env = env or self.env # Issue 811 and 1371 if posix is None: posix = True if '\\' in line: posix = ('\\ ' in line) or ('\\\\' in line) lex = shlex.shlex(line, posix=posix) lex.whitespace_split = True lex.commenters = '' lst = list(lex) # append_unique is not always possible # for example, apple flags may require both -arch i386 and -arch ppc uselib = uselib_store def app(var, val): env.append_value('%s_%s' % (var, uselib), val) def appu(var, val): env.append_unique('%s_%s' % (var, uselib), val) static = False while lst: x = lst.pop(0) st = x[:2] ot = x[2:] if st == '-I' or st == '/I': if not ot: ot = lst.pop(0) appu('INCLUDES', ot) elif st == '-i': tmp = [x, lst.pop(0)] app('CFLAGS', tmp) app('CXXFLAGS', tmp) elif st == '-D' or (env.CXX_NAME == 'msvc' and st == '/D'): # not perfect but.. if not ot: ot = lst.pop(0) app('DEFINES', ot) elif st == '-l': if not ot: ot = lst.pop(0) prefix = 'STLIB' if (force_static or static) else 'LIB' app(prefix, ot) elif st == '-L': if not ot: ot = lst.pop(0) prefix = 'STLIBPATH' if (force_static or static) else 'LIBPATH' appu(prefix, ot) elif x.startswith('/LIBPATH:'): prefix = 'STLIBPATH' if (force_static or static) else 'LIBPATH' appu(prefix, x.replace('/LIBPATH:', '')) elif x.startswith('-std='): prefix = 'CXXFLAGS' if '++' in x else 'CFLAGS' app(prefix, x) elif x.startswith('+') or x in ('-pthread', '-fPIC', '-fpic', '-fPIE', '-fpie'): app('CFLAGS', x) app('CXXFLAGS', x) app('LINKFLAGS', x) elif x == '-framework': appu('FRAMEWORK', lst.pop(0)) elif x.startswith('-F'): appu('FRAMEWORKPATH', x[2:]) elif x == '-Wl,-rpath' or x == '-Wl,-R': app('RPATH', lst.pop(0).lstrip('-Wl,')) elif x.startswith('-Wl,-R,'): app('RPATH', x[7:]) elif x.startswith('-Wl,-R'): app('RPATH', x[6:]) elif x.startswith('-Wl,-rpath,'): app('RPATH', x[11:]) elif x == '-Wl,-Bstatic' or x == '-Bstatic': static = True elif x == '-Wl,-Bdynamic' or x == '-Bdynamic': static = False elif x.startswith('-Wl') or x in ('-rdynamic', '-pie'): app('LINKFLAGS', x) elif x.startswith(('-m', '-f', '-dynamic', '-O', '-g')): # Adding the -W option breaks python builds on Openindiana app('CFLAGS', x) app('CXXFLAGS', x) elif x.startswith('-bundle'): app('LINKFLAGS', x) elif x.startswith(('-undefined', '-Xlinker')): arg = lst.pop(0) app('LINKFLAGS', [x, arg]) elif x.startswith(('-arch', '-isysroot')): tmp = [x, lst.pop(0)] app('CFLAGS', tmp) app('CXXFLAGS', tmp) app('LINKFLAGS', tmp) elif x.endswith(('.a', '.so', '.dylib', '.lib')): appu('LINKFLAGS', x) # not cool, #762 else: self.to_log('Unhandled flag %r' % x) @conf def validate_cfg(self, kw): """ Searches for the program *pkg-config* if missing, and validates the parameters to pass to :py:func:`waflib.Tools.c_config.exec_cfg`. :param path: the **-config program to use** (default is *pkg-config*) :type path: list of string :param msg: message to display to describe the test executed :type msg: string :param okmsg: message to display when the test is successful :type okmsg: string :param errmsg: message to display in case of error :type errmsg: string """ if not 'path' in kw: if not self.env.PKGCONFIG: self.find_program('pkg-config', var='PKGCONFIG') kw['path'] = self.env.PKGCONFIG # verify that exactly one action is requested s = ('atleast_pkgconfig_version' in kw) + ('modversion' in kw) + ('package' in kw) if s != 1: raise ValueError('exactly one of atleast_pkgconfig_version, modversion and package must be set') if not 'msg' in kw: if 'atleast_pkgconfig_version' in kw: kw['msg'] = 'Checking for pkg-config version >= %r' % kw['atleast_pkgconfig_version'] elif 'modversion' in kw: kw['msg'] = 'Checking for %r version' % kw['modversion'] else: kw['msg'] = 'Checking for %r' %(kw['package']) # let the modversion check set the okmsg to the detected version if not 'okmsg' in kw and not 'modversion' in kw: kw['okmsg'] = 'yes' if not 'errmsg' in kw: kw['errmsg'] = 'not found' # pkg-config version if 'atleast_pkgconfig_version' in kw: pass elif 'modversion' in kw: if not 'uselib_store' in kw: kw['uselib_store'] = kw['modversion'] if not 'define_name' in kw: kw['define_name'] = '%s_VERSION' % Utils.quote_define_name(kw['uselib_store']) else: if not 'uselib_store' in kw: kw['uselib_store'] = Utils.to_list(kw['package'])[0].upper() if not 'define_name' in kw: kw['define_name'] = self.have_define(kw['uselib_store']) @conf def exec_cfg(self, kw): """ Executes ``pkg-config`` or other ``-config`` applications to collect configuration flags: * if atleast_pkgconfig_version is given, check that pkg-config has the version n and return * if modversion is given, then return the module version * else, execute the *-config* program with the *args* and *variables* given, and set the flags on the *conf.env.FLAGS_name* variable :param atleast_pkgconfig_version: minimum pkg-config version to use (disable other tests) :type atleast_pkgconfig_version: string :param package: package name, for example *gtk+-2.0* :type package: string :param uselib_store: if the test is successful, define HAVE\\_*name*. It is also used to define *conf.env.FLAGS_name* variables. :type uselib_store: string :param modversion: if provided, return the version of the given module and define *name*\\_VERSION :type modversion: string :param args: arguments to give to *package* when retrieving flags :type args: list of string :param variables: return the values of particular variables :type variables: list of string :param define_variable: additional variables to define (also in conf.env.PKG_CONFIG_DEFINES) :type define_variable: dict(string: string) """ path = Utils.to_list(kw['path']) env = self.env.env or None if kw.get('pkg_config_path'): if not env: env = dict(self.environ) env['PKG_CONFIG_PATH'] = kw['pkg_config_path'] def define_it(): define_name = kw['define_name'] # by default, add HAVE_X to the config.h, else provide DEFINES_X for use=X if kw.get('global_define', 1): self.define(define_name, 1, False) else: self.env.append_unique('DEFINES_%s' % kw['uselib_store'], "%s=1" % define_name) if kw.get('add_have_to_env', 1): self.env[define_name] = 1 # pkg-config version if 'atleast_pkgconfig_version' in kw: cmd = path + ['--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']] self.cmd_and_log(cmd, env=env) return # single version for a module if 'modversion' in kw: version = self.cmd_and_log(path + ['--modversion', kw['modversion']], env=env).strip() if not 'okmsg' in kw: kw['okmsg'] = version self.define(kw['define_name'], version) return version lst = [] + path defi = kw.get('define_variable') if not defi: defi = self.env.PKG_CONFIG_DEFINES or {} for key, val in defi.items(): lst.append('--define-variable=%s=%s' % (key, val)) static = kw.get('force_static', False) if 'args' in kw: args = Utils.to_list(kw['args']) if '--static' in args or '--static-libs' in args: static = True lst += args # tools like pkgconf expect the package argument after the -- ones -_- lst.extend(Utils.to_list(kw['package'])) # retrieving variables of a module if 'variables' in kw: v_env = kw.get('env', self.env) vars = Utils.to_list(kw['variables']) for v in vars: val = self.cmd_and_log(lst + ['--variable=' + v], env=env).strip() var = '%s_%s' % (kw['uselib_store'], v) v_env[var] = val return # so we assume the command-line will output flags to be parsed afterwards ret = self.cmd_and_log(lst, env=env) define_it() self.parse_flags(ret, kw['uselib_store'], kw.get('env', self.env), force_static=static, posix=kw.get('posix')) return ret @conf def check_cfg(self, *k, **kw): """ Checks for configuration flags using a **-config**-like program (pkg-config, sdl-config, etc). This wraps internal calls to :py:func:`waflib.Tools.c_config.validate_cfg` and :py:func:`waflib.Tools.c_config.exec_cfg` A few examples:: def configure(conf): conf.load('compiler_c') conf.check_cfg(package='glib-2.0', args='--libs --cflags') conf.check_cfg(package='pango') conf.check_cfg(package='pango', uselib_store='MYPANGO', args=['--cflags', '--libs']) conf.check_cfg(package='pango', args=['pango >= 0.1.0', 'pango < 9.9.9', '--cflags', '--libs'], msg="Checking for 'pango 0.1.0'") conf.check_cfg(path='sdl-config', args='--cflags --libs', package='', uselib_store='SDL') conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', package='', uselib_store='OPEN_MPI', mandatory=False) # variables conf.check_cfg(package='gtk+-2.0', variables=['includedir', 'prefix'], uselib_store='FOO') print(conf.env.FOO_includedir) """ self.validate_cfg(kw) if 'msg' in kw: self.start_msg(kw['msg'], **kw) ret = None try: ret = self.exec_cfg(kw) except self.errors.WafError as e: if 'errmsg' in kw: self.end_msg(kw['errmsg'], 'YELLOW', **kw) if Logs.verbose > 1: self.to_log('Command failure: %s' % e) self.fatal('The configuration failed') else: if not ret: ret = True kw['success'] = ret if 'okmsg' in kw: self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) return ret def build_fun(bld): """ Build function that is used for running configuration tests with ``conf.check()`` """ if bld.kw['compile_filename']: node = bld.srcnode.make_node(bld.kw['compile_filename']) node.write(bld.kw['code']) o = bld(features=bld.kw['features'], source=bld.kw['compile_filename'], target='testprog') for k, v in bld.kw.items(): setattr(o, k, v) if not bld.kw.get('quiet'): bld.conf.to_log("==>\n%s\n<==" % bld.kw['code']) @conf def validate_c(self, kw): """ Pre-checks the parameters that will be given to :py:func:`waflib.Configure.run_build` :param compiler: c or cxx (tries to guess what is best) :type compiler: string :param type: cprogram, cshlib, cstlib - not required if *features are given directly* :type type: binary to create :param feature: desired features for the task generator that will execute the test, for example ``cxx cxxstlib`` :type feature: list of string :param fragment: provide a piece of code for the test (default is to let the system create one) :type fragment: string :param uselib_store: define variables after the test is executed (IMPORTANT!) :type uselib_store: string :param use: parameters to use for building (just like the normal *use* keyword) :type use: list of string :param define_name: define to set when the check is over :type define_name: string :param execute: execute the resulting binary :type execute: bool :param define_ret: if execute is set to True, use the execution output in both the define and the return value :type define_ret: bool :param header_name: check for a particular header :type header_name: string :param auto_add_header_name: if header_name was set, add the headers in env.INCKEYS so the next tests will include these headers :type auto_add_header_name: bool """ for x in ('type_name', 'field_name', 'function_name'): if x in kw: Logs.warn('Invalid argument %r in test' % x) if not 'build_fun' in kw: kw['build_fun'] = build_fun if not 'env' in kw: kw['env'] = self.env.derive() env = kw['env'] if not 'compiler' in kw and not 'features' in kw: kw['compiler'] = 'c' if env.CXX_NAME and Task.classes.get('cxx'): kw['compiler'] = 'cxx' if not self.env.CXX: self.fatal('a c++ compiler is required') else: if not self.env.CC: self.fatal('a c compiler is required') if not 'compile_mode' in kw: kw['compile_mode'] = 'c' if 'cxx' in Utils.to_list(kw.get('features', [])) or kw.get('compiler') == 'cxx': kw['compile_mode'] = 'cxx' if not 'type' in kw: kw['type'] = 'cprogram' if not 'features' in kw: if not 'header_name' in kw or kw.get('link_header_test', True): kw['features'] = [kw['compile_mode'], kw['type']] # "c ccprogram" else: kw['features'] = [kw['compile_mode']] else: kw['features'] = Utils.to_list(kw['features']) if not 'compile_filename' in kw: kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '') def to_header(dct): if 'header_name' in dct: dct = Utils.to_list(dct['header_name']) return ''.join(['#include <%s>\n' % x for x in dct]) return '' if 'framework_name' in kw: # OSX, not sure this is used anywhere fwkname = kw['framework_name'] if not 'uselib_store' in kw: kw['uselib_store'] = fwkname.upper() if not kw.get('no_header'): fwk = '%s/%s.h' % (fwkname, fwkname) if kw.get('remove_dot_h'): fwk = fwk[:-2] val = kw.get('header_name', []) kw['header_name'] = Utils.to_list(val) + [fwk] kw['msg'] = 'Checking for framework %s' % fwkname kw['framework'] = fwkname elif 'header_name' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for header %s' % kw['header_name'] l = Utils.to_list(kw['header_name']) assert len(l), 'list of headers in header_name is empty' kw['code'] = to_header(kw) + SNIP_EMPTY_PROGRAM if not 'uselib_store' in kw: kw['uselib_store'] = l[0].upper() if not 'define_name' in kw: kw['define_name'] = self.have_define(l[0]) if 'lib' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for library %s' % kw['lib'] if not 'uselib_store' in kw: kw['uselib_store'] = kw['lib'].upper() if 'stlib' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for static library %s' % kw['stlib'] if not 'uselib_store' in kw: kw['uselib_store'] = kw['stlib'].upper() if 'fragment' in kw: # an additional code fragment may be provided to replace the predefined code # in custom headers kw['code'] = kw['fragment'] if not 'msg' in kw: kw['msg'] = 'Checking for code snippet' if not 'errmsg' in kw: kw['errmsg'] = 'no' for (flagsname,flagstype) in (('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')): if flagsname in kw: if not 'msg' in kw: kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname]) if not 'errmsg' in kw: kw['errmsg'] = 'no' if not 'execute' in kw: kw['execute'] = False if kw['execute']: kw['features'].append('test_exec') kw['chmod'] = Utils.O755 if not 'errmsg' in kw: kw['errmsg'] = 'not found' if not 'okmsg' in kw: kw['okmsg'] = 'yes' if not 'code' in kw: kw['code'] = SNIP_EMPTY_PROGRAM # if there are headers to append automatically to the next tests if self.env[INCKEYS]: kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code'] # in case defines lead to very long command-lines if kw.get('merge_config_header') or env.merge_config_header: kw['code'] = '%s\n\n%s' % (self.get_config_header(), kw['code']) env.DEFINES = [] # modify the copy if not kw.get('success'): kw['success'] = None if 'define_name' in kw: self.undefine(kw['define_name']) if not 'msg' in kw: self.fatal('missing "msg" in conf.check(...)') @conf def post_check(self, *k, **kw): """ Sets the variables after a test executed in :py:func:`waflib.Tools.c_config.check` was run successfully """ is_success = 0 if kw['execute']: if kw['success'] is not None: if kw.get('define_ret'): is_success = kw['success'] else: is_success = (kw['success'] == 0) else: is_success = (kw['success'] == 0) if kw.get('define_name'): comment = kw.get('comment', '') define_name = kw['define_name'] if kw['execute'] and kw.get('define_ret') and isinstance(is_success, str): if kw.get('global_define', 1): self.define(define_name, is_success, quote=kw.get('quote', 1), comment=comment) else: if kw.get('quote', 1): succ = '"%s"' % is_success else: succ = int(is_success) val = '%s=%s' % (define_name, succ) var = 'DEFINES_%s' % kw['uselib_store'] self.env.append_value(var, val) else: if kw.get('global_define', 1): self.define_cond(define_name, is_success, comment=comment) else: var = 'DEFINES_%s' % kw['uselib_store'] self.env.append_value(var, '%s=%s' % (define_name, int(is_success))) # define conf.env.HAVE_X to 1 if kw.get('add_have_to_env', 1): if kw.get('uselib_store'): self.env[self.have_define(kw['uselib_store'])] = 1 elif kw['execute'] and kw.get('define_ret'): self.env[define_name] = is_success else: self.env[define_name] = int(is_success) if 'header_name' in kw: if kw.get('auto_add_header_name'): self.env.append_value(INCKEYS, Utils.to_list(kw['header_name'])) if is_success and 'uselib_store' in kw: from waflib.Tools import ccroot # See get_uselib_vars in ccroot.py _vars = set() for x in kw['features']: if x in ccroot.USELIB_VARS: _vars |= ccroot.USELIB_VARS[x] for k in _vars: x = k.lower() if x in kw: self.env.append_value(k + '_' + kw['uselib_store'], kw[x]) return is_success @conf def check(self, *k, **kw): """ Performs a configuration test by calling :py:func:`waflib.Configure.run_build`. For the complete list of parameters, see :py:func:`waflib.Tools.c_config.validate_c`. To force a specific compiler, pass ``compiler='c'`` or ``compiler='cxx'`` to the list of arguments Besides build targets, complete builds can be given through a build function. All files will be written to a temporary directory:: def build(bld): lib_node = bld.srcnode.make_node('libdir/liblc1.c') lib_node.parent.mkdir() lib_node.write('#include \\nint lib_func(void) { FILE *f = fopen("foo", "r");}\\n', 'w') bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') conf.check(build_fun=build, msg=msg) """ self.validate_c(kw) self.start_msg(kw['msg'], **kw) ret = None try: ret = self.run_build(*k, **kw) except self.errors.ConfigurationError: self.end_msg(kw['errmsg'], 'YELLOW', **kw) if Logs.verbose > 1: raise else: self.fatal('The configuration failed') else: kw['success'] = ret ret = self.post_check(*k, **kw) if not ret: self.end_msg(kw['errmsg'], 'YELLOW', **kw) self.fatal('The configuration failed %r' % ret) else: self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) return ret class test_exec(Task.Task): """ A task that runs programs after they are built. See :py:func:`waflib.Tools.c_config.test_exec_fun`. """ color = 'PINK' def run(self): cmd = [self.inputs[0].abspath()] + getattr(self.generator, 'test_args', []) if getattr(self.generator, 'rpath', None): if getattr(self.generator, 'define_ret', False): self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd) else: self.generator.bld.retval = self.generator.bld.exec_command(cmd) else: env = self.env.env or {} env.update(dict(os.environ)) for var in ('LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'PATH'): env[var] = self.inputs[0].parent.abspath() + os.path.pathsep + env.get(var, '') if getattr(self.generator, 'define_ret', False): self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd, env=env) else: self.generator.bld.retval = self.generator.bld.exec_command(cmd, env=env) @feature('test_exec') @after_method('apply_link') def test_exec_fun(self): """ The feature **test_exec** is used to create a task that will to execute the binary created (link task output) during the build. The exit status will be set on the build context, so only one program may have the feature *test_exec*. This is used by configuration tests:: def configure(conf): conf.check(execute=True) """ self.create_task('test_exec', self.link_task.outputs[0]) @conf def check_cxx(self, *k, **kw): """ Runs a test with a task generator of the form:: conf.check(features='cxx cxxprogram', ...) """ kw['compiler'] = 'cxx' return self.check(*k, **kw) @conf def check_cc(self, *k, **kw): """ Runs a test with a task generator of the form:: conf.check(features='c cprogram', ...) """ kw['compiler'] = 'c' return self.check(*k, **kw) @conf def set_define_comment(self, key, comment): """ Sets a comment that will appear in the configuration header :type key: string :type comment: string """ coms = self.env.DEFINE_COMMENTS if not coms: coms = self.env.DEFINE_COMMENTS = {} coms[key] = comment or '' @conf def get_define_comment(self, key): """ Returns the comment associated to a define :type key: string """ coms = self.env.DEFINE_COMMENTS or {} return coms.get(key, '') @conf def define(self, key, val, quote=True, comment=''): """ Stores a single define and its state into ``conf.env.DEFINES``. The value is cast to an integer (0/1). :param key: define name :type key: string :param val: value :type val: int or string :param quote: enclose strings in quotes (yes by default) :type quote: bool """ assert isinstance(key, str) if not key: return if val is True: val = 1 elif val in (False, None): val = 0 if isinstance(val, int) or isinstance(val, float): s = '%s=%s' else: s = quote and '%s="%s"' or '%s=%s' app = s % (key, str(val)) ban = key + '=' lst = self.env.DEFINES for x in lst: if x.startswith(ban): lst[lst.index(x)] = app break else: self.env.append_value('DEFINES', app) self.env.append_unique(DEFKEYS, key) self.set_define_comment(key, comment) @conf def undefine(self, key, comment=''): """ Removes a global define from ``conf.env.DEFINES`` :param key: define name :type key: string """ assert isinstance(key, str) if not key: return ban = key + '=' lst = [x for x in self.env.DEFINES if not x.startswith(ban)] self.env.DEFINES = lst self.env.append_unique(DEFKEYS, key) self.set_define_comment(key, comment) @conf def define_cond(self, key, val, comment=''): """ Conditionally defines a name:: def configure(conf): conf.define_cond('A', True) # equivalent to: # if val: conf.define('A', 1) # else: conf.undefine('A') :param key: define name :type key: string :param val: value :type val: int or string """ assert isinstance(key, str) if not key: return if val: self.define(key, 1, comment=comment) else: self.undefine(key, comment=comment) @conf def is_defined(self, key): """ Indicates whether a particular define is globally set in ``conf.env.DEFINES``. :param key: define name :type key: string :return: True if the define is set :rtype: bool """ assert key and isinstance(key, str) ban = key + '=' for x in self.env.DEFINES: if x.startswith(ban): return True return False @conf def get_define(self, key): """ Returns the value of an existing define, or None if not found :param key: define name :type key: string :rtype: string """ assert key and isinstance(key, str) ban = key + '=' for x in self.env.DEFINES: if x.startswith(ban): return x[len(ban):] return None @conf def have_define(self, key): """ Returns a variable suitable for command-line or header use by removing invalid characters and prefixing it with ``HAVE_`` :param key: define name :type key: string :return: the input key prefixed by *HAVE_* and substitute any invalid characters. :rtype: string """ return (self.env.HAVE_PAT or 'HAVE_%s') % Utils.quote_define_name(key) @conf def write_config_header(self, configfile='', guard='', top=False, defines=True, headers=False, remove=True, define_prefix=''): """ Writes a configuration header containing defines and includes:: def configure(cnf): cnf.define('A', 1) cnf.write_config_header('config.h') This function only adds include guards (if necessary), consult :py:func:`waflib.Tools.c_config.get_config_header` for details on the body. :param configfile: path to the file to create (relative or absolute) :type configfile: string :param guard: include guard name to add, by default it is computed from the file name :type guard: string :param top: write the configuration header from the build directory (default is from the current path) :type top: bool :param defines: add the defines (yes by default) :type defines: bool :param headers: add #include in the file :type headers: bool :param remove: remove the defines after they are added (yes by default, works like in autoconf) :type remove: bool :type define_prefix: string :param define_prefix: prefix all the defines in the file with a particular prefix """ if not configfile: configfile = WAF_CONFIG_H waf_guard = guard or 'W_%s_WAF' % Utils.quote_define_name(configfile) node = top and self.bldnode or self.path.get_bld() node = node.make_node(configfile) node.parent.mkdir() lst = ['/* WARNING! All changes made to this file will be lost! */\n'] lst.append('#ifndef %s\n#define %s\n' % (waf_guard, waf_guard)) lst.append(self.get_config_header(defines, headers, define_prefix=define_prefix)) lst.append('\n#endif /* %s */\n' % waf_guard) node.write('\n'.join(lst)) # config files must not be removed on "waf clean" self.env.append_unique(Build.CFG_FILES, [node.abspath()]) if remove: for key in self.env[DEFKEYS]: self.undefine(key) self.env[DEFKEYS] = [] @conf def get_config_header(self, defines=True, headers=False, define_prefix=''): """ Creates the contents of a ``config.h`` file from the defines and includes set in conf.env.define_key / conf.env.include_key. No include guards are added. A prelude will be added from the variable env.WAF_CONFIG_H_PRELUDE if provided. This can be used to insert complex macros or include guards:: def configure(conf): conf.env.WAF_CONFIG_H_PRELUDE = '#include \\n' conf.write_config_header('config.h') :param defines: write the defines values :type defines: bool :param headers: write include entries for each element in self.env.INCKEYS :type headers: bool :type define_prefix: string :param define_prefix: prefix all the defines with a particular prefix :return: the contents of a ``config.h`` file :rtype: string """ lst = [] if self.env.WAF_CONFIG_H_PRELUDE: lst.append(self.env.WAF_CONFIG_H_PRELUDE) if headers: for x in self.env[INCKEYS]: lst.append('#include <%s>' % x) if defines: tbl = {} for k in self.env.DEFINES: a, _, b = k.partition('=') tbl[a] = b for k in self.env[DEFKEYS]: caption = self.get_define_comment(k) if caption: caption = ' /* %s */' % caption try: txt = '#define %s%s %s%s' % (define_prefix, k, tbl[k], caption) except KeyError: txt = '/* #undef %s%s */%s' % (define_prefix, k, caption) lst.append(txt) return "\n".join(lst) @conf def cc_add_flags(conf): """ Adds CFLAGS / CPPFLAGS from os.environ to conf.env """ conf.add_os_flags('CPPFLAGS', dup=False) conf.add_os_flags('CFLAGS', dup=False) @conf def cxx_add_flags(conf): """ Adds CXXFLAGS / CPPFLAGS from os.environ to conf.env """ conf.add_os_flags('CPPFLAGS', dup=False) conf.add_os_flags('CXXFLAGS', dup=False) @conf def link_add_flags(conf): """ Adds LINKFLAGS / LDFLAGS from os.environ to conf.env """ conf.add_os_flags('LINKFLAGS', dup=False) conf.add_os_flags('LDFLAGS', dup=False) @conf def cc_load_tools(conf): """ Loads the Waf c extensions """ if not conf.env.DEST_OS: conf.env.DEST_OS = Utils.unversioned_sys_platform() conf.load('c') @conf def cxx_load_tools(conf): """ Loads the Waf c++ extensions """ if not conf.env.DEST_OS: conf.env.DEST_OS = Utils.unversioned_sys_platform() conf.load('cxx') @conf def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): """ Runs the preprocessor to determine the gcc/icc/clang version The variables CC_VERSION, DEST_OS, DEST_BINFMT and DEST_CPU will be set in *conf.env* :raise: :py:class:`waflib.Errors.ConfigurationError` """ cmd = cc + ['-dM', '-E', '-'] env = conf.env.env or None try: out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), env=env) except Errors.WafError: conf.fatal('Could not determine the compiler version %r' % cmd) if gcc: if out.find('__INTEL_COMPILER') >= 0: conf.fatal('The intel compiler pretends to be gcc') if out.find('__GNUC__') < 0 and out.find('__clang__') < 0: conf.fatal('Could not determine the compiler type') if icc and out.find('__INTEL_COMPILER') < 0: conf.fatal('Not icc/icpc') if clang and out.find('__clang__') < 0: conf.fatal('Not clang/clang++') if not clang and out.find('__clang__') >= 0: conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') k = {} if icc or gcc or clang: out = out.splitlines() for line in out: lst = shlex.split(line) if len(lst)>2: key = lst[1] val = lst[2] k[key] = val def isD(var): return var in k # Some documentation is available at http://predef.sourceforge.net # The names given to DEST_OS must match what Utils.unversioned_sys_platform() returns. if not conf.env.DEST_OS: conf.env.DEST_OS = '' for i in MACRO_TO_DESTOS: if isD(i): conf.env.DEST_OS = MACRO_TO_DESTOS[i] break else: if isD('__APPLE__') and isD('__MACH__'): conf.env.DEST_OS = 'darwin' elif isD('__unix__'): # unix must be tested last as it's a generic fallback conf.env.DEST_OS = 'generic' if isD('__ELF__'): conf.env.DEST_BINFMT = 'elf' elif isD('__WINNT__') or isD('__CYGWIN__') or isD('_WIN32'): conf.env.DEST_BINFMT = 'pe' if not conf.env.IMPLIBDIR: conf.env.IMPLIBDIR = conf.env.LIBDIR # for .lib or .dll.a files conf.env.LIBDIR = conf.env.BINDIR elif isD('__APPLE__'): conf.env.DEST_BINFMT = 'mac-o' if not conf.env.DEST_BINFMT: # Infer the binary format from the os name. conf.env.DEST_BINFMT = Utils.destos_to_binfmt(conf.env.DEST_OS) for i in MACRO_TO_DEST_CPU: if isD(i): conf.env.DEST_CPU = MACRO_TO_DEST_CPU[i] break Logs.debug('ccroot: dest platform: ' + ' '.join([conf.env[x] or '?' for x in ('DEST_OS', 'DEST_BINFMT', 'DEST_CPU')])) if icc: ver = k['__INTEL_COMPILER'] conf.env.CC_VERSION = (ver[:-2], ver[-2], ver[-1]) else: if isD('__clang__') and isD('__clang_major__'): conf.env.CC_VERSION = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) else: # older clang versions and gcc conf.env.CC_VERSION = (k['__GNUC__'], k['__GNUC_MINOR__'], k.get('__GNUC_PATCHLEVEL__', '0')) return k @conf def get_xlc_version(conf, cc): """ Returns the Aix compiler version :raise: :py:class:`waflib.Errors.ConfigurationError` """ cmd = cc + ['-qversion'] try: out, err = conf.cmd_and_log(cmd, output=0) except Errors.WafError: conf.fatal('Could not find xlc %r' % cmd) # the intention is to catch the 8.0 in "IBM XL C/C++ Enterprise Edition V8.0 for AIX..." for v in (r"IBM XL C/C\+\+.* V(?P\d*)\.(?P\d*)",): version_re = re.compile(v, re.I).search match = version_re(out or err) if match: k = match.groupdict() conf.env.CC_VERSION = (k['major'], k['minor']) break else: conf.fatal('Could not determine the XLC version.') @conf def get_suncc_version(conf, cc): """ Returns the Sun compiler version :raise: :py:class:`waflib.Errors.ConfigurationError` """ cmd = cc + ['-V'] try: out, err = conf.cmd_and_log(cmd, output=0) except Errors.WafError as e: # Older versions of the compiler exit with non-zero status when reporting their version if not (hasattr(e, 'returncode') and hasattr(e, 'stdout') and hasattr(e, 'stderr')): conf.fatal('Could not find suncc %r' % cmd) out = e.stdout err = e.stderr version = (out or err) version = version.splitlines()[0] # cc: Sun C 5.10 SunOS_i386 2009/06/03 # cc: Studio 12.5 Sun C++ 5.14 SunOS_sparc Beta 2015/11/17 # cc: WorkShop Compilers 5.0 98/12/15 C 5.0 version_re = re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P\d*)\.(?P\d*)', re.I).search match = version_re(version) if match: k = match.groupdict() conf.env.CC_VERSION = (k['major'], k['minor']) else: conf.fatal('Could not determine the suncc version.') # ============ the --as-needed flag should added during the configuration, not at runtime ========= @conf def add_as_needed(self): """ Adds ``--as-needed`` to the *LINKFLAGS* On some platforms, it is a default flag. In some cases (e.g., in NS-3) it is necessary to explicitly disable this feature with `-Wl,--no-as-needed` flag. """ if self.env.DEST_BINFMT == 'elf' and 'gcc' in (self.env.CXX_NAME, self.env.CC_NAME): self.env.append_unique('LINKFLAGS', '-Wl,--as-needed') # ============ parallel configuration class cfgtask(Task.Task): """ A task that executes build configuration tests (calls conf.check) Make sure to use locks if concurrent access to the same conf.env data is necessary. """ def __init__(self, *k, **kw): Task.Task.__init__(self, *k, **kw) self.run_after = set() def display(self): return '' def runnable_status(self): for x in self.run_after: if not x.hasrun: return Task.ASK_LATER return Task.RUN_ME def uid(self): return Utils.SIG_NIL def signature(self): return Utils.SIG_NIL def run(self): conf = self.conf bld = Build.BuildContext(top_dir=conf.srcnode.abspath(), out_dir=conf.bldnode.abspath()) bld.env = conf.env bld.init_dirs() bld.in_msg = 1 # suppress top-level start_msg bld.logger = self.logger bld.multicheck_task = self args = self.args try: if 'func' in args: bld.test(build_fun=args['func'], msg=args.get('msg', ''), okmsg=args.get('okmsg', ''), errmsg=args.get('errmsg', ''), ) else: args['multicheck_mandatory'] = args.get('mandatory', True) args['mandatory'] = True try: bld.check(**args) finally: args['mandatory'] = args['multicheck_mandatory'] except Exception: return 1 def process(self): Task.Task.process(self) if 'msg' in self.args: with self.generator.bld.multicheck_lock: self.conf.start_msg(self.args['msg']) if self.hasrun == Task.NOT_RUN: self.conf.end_msg('test cancelled', 'YELLOW') elif self.hasrun != Task.SUCCESS: self.conf.end_msg(self.args.get('errmsg', 'no'), 'YELLOW') else: self.conf.end_msg(self.args.get('okmsg', 'yes'), 'GREEN') @conf def multicheck(self, *k, **kw): """ Runs configuration tests in parallel; results are printed sequentially at the end of the build but each test must provide its own msg value to display a line:: def test_build(ctx): ctx.in_msg = True # suppress console outputs ctx.check_large_file(mandatory=False) conf.multicheck( {'header_name':'stdio.h', 'msg':'... stdio', 'uselib_store':'STDIO', 'global_define':False}, {'header_name':'xyztabcd.h', 'msg':'... optional xyztabcd.h', 'mandatory': False}, {'header_name':'stdlib.h', 'msg':'... stdlib', 'okmsg': 'aye', 'errmsg': 'nope'}, {'func': test_build, 'msg':'... testing an arbitrary build function', 'okmsg':'ok'}, msg = 'Checking for headers in parallel', mandatory = True, # mandatory tests raise an error at the end run_all_tests = True, # try running all tests ) The configuration tests may modify the values in conf.env in any order, and the define values can affect configuration tests being executed. It is hence recommended to provide `uselib_store` values with `global_define=False` to prevent such issues. """ self.start_msg(kw.get('msg', 'Executing %d configuration tests' % len(k)), **kw) # Force a copy so that threads append to the same list at least # no order is guaranteed, but the values should not disappear at least for var in ('DEFINES', DEFKEYS): self.env.append_value(var, []) self.env.DEFINE_COMMENTS = self.env.DEFINE_COMMENTS or {} # define a task object that will execute our tests class par(object): def __init__(self): self.keep = False self.task_sigs = {} self.progress_bar = 0 def total(self): return len(tasks) def to_log(self, *k, **kw): return bld = par() bld.keep = kw.get('run_all_tests', True) bld.imp_sigs = {} tasks = [] id_to_task = {} for dct in k: x = Task.classes['cfgtask'](bld=bld, env=None) tasks.append(x) x.args = dct x.bld = bld x.conf = self x.args = dct # bind a logger that will keep the info in memory x.logger = Logs.make_mem_logger(str(id(x)), self.logger) if 'id' in dct: id_to_task[dct['id']] = x # second pass to set dependencies with after_test/before_test for x in tasks: for key in Utils.to_list(x.args.get('before_tests', [])): tsk = id_to_task[key] if not tsk: raise ValueError('No test named %r' % key) tsk.run_after.add(x) for key in Utils.to_list(x.args.get('after_tests', [])): tsk = id_to_task[key] if not tsk: raise ValueError('No test named %r' % key) x.run_after.add(tsk) def it(): yield tasks while 1: yield [] bld.producer = p = Runner.Parallel(bld, Options.options.jobs) bld.multicheck_lock = Utils.threading.Lock() p.biter = it() self.end_msg('started') p.start() # flush the logs in order into the config.log for x in tasks: x.logger.memhandler.flush() self.start_msg('-> processing test results') if p.error: for x in p.error: if getattr(x, 'err_msg', None): self.to_log(x.err_msg) self.end_msg('fail', color='RED') raise Errors.WafError('There is an error in the library, read config.log for more information') failure_count = 0 for x in tasks: if x.hasrun not in (Task.SUCCESS, Task.NOT_RUN): failure_count += 1 if failure_count: self.end_msg(kw.get('errmsg', '%s test failed' % failure_count), color='YELLOW', **kw) else: self.end_msg('all ok', **kw) for x in tasks: if x.hasrun != Task.SUCCESS: if x.args.get('mandatory', True): self.fatal(kw.get('fatalmsg') or 'One of the tests has failed, read config.log for more information') @conf def check_gcc_o_space(self, mode='c'): if int(self.env.CC_VERSION[0]) > 4: # this is for old compilers return self.env.stash() if mode == 'c': self.env.CCLNK_TGT_F = ['-o', ''] elif mode == 'cxx': self.env.CXXLNK_TGT_F = ['-o', ''] features = '%s %sshlib' % (mode, mode) try: self.check(msg='Checking if the -o link must be split from arguments', fragment=SNIP_EMPTY_PROGRAM, features=features) except self.errors.ConfigurationError: self.env.revert() else: self.env.commit() ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py0000660000000000000000000001332613573675414021401 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy 2008-2018 (ita) """ MacOSX related tools """ import os, shutil, platform from waflib import Task, Utils from waflib.TaskGen import taskgen_method, feature, after_method, before_method app_info = ''' CFBundlePackageType APPL CFBundleGetInfoString Created by Waf CFBundleSignature ???? NOTE THIS IS A GENERATED FILE, DO NOT MODIFY CFBundleExecutable {app_name} ''' """ plist template """ @feature('c', 'cxx') def set_macosx_deployment_target(self): """ see WAF issue 285 and also and also http://trac.macports.org/ticket/17059 """ if self.env.MACOSX_DEPLOYMENT_TARGET: os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env.MACOSX_DEPLOYMENT_TARGET elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ: if Utils.unversioned_sys_platform() == 'darwin': os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2]) @taskgen_method def create_bundle_dirs(self, name, out): """ Creates bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp` """ dir = out.parent.find_or_declare(name) dir.mkdir() macos = dir.find_or_declare(['Contents', 'MacOS']) macos.mkdir() return dir def bundle_name_for_output(out): name = out.name k = name.rfind('.') if k >= 0: name = name[:k] + '.app' else: name = name + '.app' return name @feature('cprogram', 'cxxprogram') @after_method('apply_link') def create_task_macapp(self): """ To compile an executable into a Mac application (a .app), set its *mac_app* attribute:: def build(bld): bld.shlib(source='a.c', target='foo', mac_app=True) To force *all* executables to be transformed into Mac applications:: def build(bld): bld.env.MACAPP = True bld.shlib(source='a.c', target='foo') """ if self.env.MACAPP or getattr(self, 'mac_app', False): out = self.link_task.outputs[0] name = bundle_name_for_output(out) dir = self.create_bundle_dirs(name, out) n1 = dir.find_or_declare(['Contents', 'MacOS', out.name]) self.apptask = self.create_task('macapp', self.link_task.outputs, n1) inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/MacOS/' % name self.add_install_files(install_to=inst_to, install_from=n1, chmod=Utils.O755) if getattr(self, 'mac_files', None): # this only accepts files; they will be installed as seen from mac_files_root mac_files_root = getattr(self, 'mac_files_root', None) if isinstance(mac_files_root, str): mac_files_root = self.path.find_node(mac_files_root) if not mac_files_root: self.bld.fatal('Invalid mac_files_root %r' % self.mac_files_root) res_dir = n1.parent.parent.make_node('Resources') inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name for node in self.to_nodes(self.mac_files): relpath = node.path_from(mac_files_root or node.parent) self.create_task('macapp', node, res_dir.make_node(relpath)) self.add_install_as(install_to=os.path.join(inst_to, relpath), install_from=node) if getattr(self.bld, 'is_install', None): # disable regular binary installation self.install_task.hasrun = Task.SKIP_ME @feature('cprogram', 'cxxprogram') @after_method('apply_link') def create_task_macplist(self): """ Creates a :py:class:`waflib.Tools.c_osx.macplist` instance. """ if self.env.MACAPP or getattr(self, 'mac_app', False): out = self.link_task.outputs[0] name = bundle_name_for_output(out) dir = self.create_bundle_dirs(name, out) n1 = dir.find_or_declare(['Contents', 'Info.plist']) self.plisttask = plisttask = self.create_task('macplist', [], n1) plisttask.context = { 'app_name': self.link_task.outputs[0].name, 'env': self.env } plist_ctx = getattr(self, 'plist_context', None) if (plist_ctx): plisttask.context.update(plist_ctx) if getattr(self, 'mac_plist', False): node = self.path.find_resource(self.mac_plist) if node: plisttask.inputs.append(node) else: plisttask.code = self.mac_plist else: plisttask.code = app_info inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/' % name self.add_install_files(install_to=inst_to, install_from=n1) @feature('cshlib', 'cxxshlib') @before_method('apply_link', 'propagate_uselib_vars') def apply_bundle(self): """ To make a bundled shared library (a ``.bundle``), set the *mac_bundle* attribute:: def build(bld): bld.shlib(source='a.c', target='foo', mac_bundle = True) To force *all* executables to be transformed into bundles:: def build(bld): bld.env.MACBUNDLE = True bld.shlib(source='a.c', target='foo') """ if self.env.MACBUNDLE or getattr(self, 'mac_bundle', False): self.env.LINKFLAGS_cshlib = self.env.LINKFLAGS_cxxshlib = [] # disable the '-dynamiclib' flag self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN use = self.use = self.to_list(getattr(self, 'use', [])) if not 'MACBUNDLE' in use: use.append('MACBUNDLE') app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources'] class macapp(Task.Task): """ Creates mac applications """ color = 'PINK' def run(self): self.outputs[0].parent.mkdir() shutil.copy2(self.inputs[0].srcpath(), self.outputs[0].abspath()) class macplist(Task.Task): """ Creates plist files """ color = 'PINK' ext_in = ['.bin'] def run(self): if getattr(self, 'code', None): txt = self.code else: txt = self.inputs[0].read() context = getattr(self, 'context', {}) txt = txt.format(**context) self.outputs[0].write(txt) ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py0000660000000000000000000006606513573675414022252 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) """ C/C++ preprocessor for finding dependencies Reasons for using the Waf preprocessor by default #. Some c/c++ extensions (Qt) require a custom preprocessor for obtaining the dependencies (.moc files) #. Not all compilers provide .d files for obtaining the dependencies (portability) #. A naive file scanner will not catch the constructs such as "#include foo()" #. A naive file scanner will catch unnecessary dependencies (change an unused header -> recompile everything) Regarding the speed concerns: * the preprocessing is performed only when files must be compiled * the macros are evaluated only for #if/#elif/#include * system headers are not scanned by default Now if you do not want the Waf preprocessor, the tool +gccdeps* uses the .d files produced during the compilation to track the dependencies (useful when used with the boost libraries). It only works with gcc >= 4.4 though. A dumb preprocessor is also available in the tool *c_dumbpreproc* """ # TODO: more varargs, pragma once import re, string, traceback from waflib import Logs, Utils, Errors class PreprocError(Errors.WafError): pass FILE_CACHE_SIZE = 100000 LINE_CACHE_SIZE = 100000 POPFILE = '-' "Constant representing a special token used in :py:meth:`waflib.Tools.c_preproc.c_parser.start` iteration to switch to a header read previously" recursion_limit = 150 "Limit on the amount of files to read in the dependency scanner" go_absolute = False "Set to True to track headers on files in /usr/include, else absolute paths are ignored (but it becomes very slow)" standard_includes = ['/usr/local/include', '/usr/include'] if Utils.is_win32: standard_includes = [] use_trigraphs = 0 """Apply trigraph rules (False by default)""" # obsolete, do not use strict_quotes = 0 g_optrans = { 'not':'!', 'not_eq':'!', 'and':'&&', 'and_eq':'&=', 'or':'||', 'or_eq':'|=', 'xor':'^', 'xor_eq':'^=', 'bitand':'&', 'bitor':'|', 'compl':'~', } """Operators such as and/or/xor for c++. Set an empty dict to disable.""" # ignore #warning and #error re_lines = re.compile( '^[ \t]*(?:#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$', re.IGNORECASE | re.MULTILINE) """Match #include lines""" re_mac = re.compile(r"^[a-zA-Z_]\w*") """Match macro definitions""" re_fun = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]') """Match macro functions""" re_pragma_once = re.compile(r'^\s*once\s*', re.IGNORECASE) """Match #pragma once statements""" re_nl = re.compile('\\\\\r*\n', re.MULTILINE) """Match newlines""" re_cpp = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE ) """Filter C/C++ comments""" trig_def = [('??'+a, b) for a, b in zip("=-/!'()<>", r'#~\|^[]{}')] """Trigraph definitions""" chr_esc = {'0':0, 'a':7, 'b':8, 't':9, 'n':10, 'f':11, 'v':12, 'r':13, '\\':92, "'":39} """Escape characters""" NUM = 'i' """Number token""" OP = 'O' """Operator token""" IDENT = 'T' """Identifier token""" STR = 's' """String token""" CHAR = 'c' """Character token""" tok_types = [NUM, STR, IDENT, OP] """Token types""" exp_types = [ r"""0[xX](?P[a-fA-F0-9]+)(?P[uUlL]*)|L*?'(?P(\\.|[^\\'])+)'|(?P\d+)[Ee](?P[+-]*?\d+)(?P[fFlL]*)|(?P\d*\.\d+)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P\d+\.\d*)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P0*)(?P\d+)(?P[uUlL]*)""", r'L?"([^"\\]|\\.)*"', r'[a-zA-Z_]\w*', r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]', ] """Expression types""" re_clexer = re.compile('|'.join(["(?P<%s>%s)" % (name, part) for name, part in zip(tok_types, exp_types)]), re.M) """Match expressions into tokens""" accepted = 'a' """Parser state is *accepted*""" ignored = 'i' """Parser state is *ignored*, for example preprocessor lines in an #if 0 block""" undefined = 'u' """Parser state is *undefined* at the moment""" skipped = 's' """Parser state is *skipped*, for example preprocessor lines in a #elif 0 block""" def repl(m): """Replace function used with :py:attr:`waflib.Tools.c_preproc.re_cpp`""" s = m.group() if s[0] == '/': return ' ' return s prec = {} """ Operator precedence rules required for parsing expressions of the form:: #if 1 && 2 != 0 """ ops = ['* / %', '+ -', '<< >>', '< <= >= >', '== !=', '& | ^', '&& ||', ','] for x, syms in enumerate(ops): for u in syms.split(): prec[u] = x def reduce_nums(val_1, val_2, val_op): """ Apply arithmetic rules to compute a result :param val1: input parameter :type val1: int or string :param val2: input parameter :type val2: int or string :param val_op: C operator in *+*, */*, *-*, etc :type val_op: string :rtype: int """ #print val_1, val_2, val_op # now perform the operation, make certain a and b are numeric try: a = 0 + val_1 except TypeError: a = int(val_1) try: b = 0 + val_2 except TypeError: b = int(val_2) d = val_op if d == '%': c = a % b elif d=='+': c = a + b elif d=='-': c = a - b elif d=='*': c = a * b elif d=='/': c = a / b elif d=='^': c = a ^ b elif d=='==': c = int(a == b) elif d=='|' or d == 'bitor': c = a | b elif d=='||' or d == 'or' : c = int(a or b) elif d=='&' or d == 'bitand': c = a & b elif d=='&&' or d == 'and': c = int(a and b) elif d=='!=' or d == 'not_eq': c = int(a != b) elif d=='^' or d == 'xor': c = int(a^b) elif d=='<=': c = int(a <= b) elif d=='<': c = int(a < b) elif d=='>': c = int(a > b) elif d=='>=': c = int(a >= b) elif d=='<<': c = a << b elif d=='>>': c = a >> b else: c = 0 return c def get_num(lst): """ Try to obtain a number from a list of tokens. The token types are defined in :py:attr:`waflib.Tools.ccroot.tok_types`. :param lst: list of preprocessor tokens :type lst: list of tuple (tokentype, value) :return: a pair containing the number and the rest of the list :rtype: tuple(value, list) """ if not lst: raise PreprocError('empty list for get_num') (p, v) = lst[0] if p == OP: if v == '(': count_par = 1 i = 1 while i < len(lst): (p, v) = lst[i] if p == OP: if v == ')': count_par -= 1 if count_par == 0: break elif v == '(': count_par += 1 i += 1 else: raise PreprocError('rparen expected %r' % lst) (num, _) = get_term(lst[1:i]) return (num, lst[i+1:]) elif v == '+': return get_num(lst[1:]) elif v == '-': num, lst = get_num(lst[1:]) return (reduce_nums('-1', num, '*'), lst) elif v == '!': num, lst = get_num(lst[1:]) return (int(not int(num)), lst) elif v == '~': num, lst = get_num(lst[1:]) return (~ int(num), lst) else: raise PreprocError('Invalid op token %r for get_num' % lst) elif p == NUM: return v, lst[1:] elif p == IDENT: # all macros should have been replaced, remaining identifiers eval to 0 return 0, lst[1:] else: raise PreprocError('Invalid token %r for get_num' % lst) def get_term(lst): """ Evaluate an expression recursively, for example:: 1+1+1 -> 2+1 -> 3 :param lst: list of tokens :type lst: list of tuple(token, value) :return: the value and the remaining tokens :rtype: value, list """ if not lst: raise PreprocError('empty list for get_term') num, lst = get_num(lst) if not lst: return (num, []) (p, v) = lst[0] if p == OP: if v == ',': # skip return get_term(lst[1:]) elif v == '?': count_par = 0 i = 1 while i < len(lst): (p, v) = lst[i] if p == OP: if v == ')': count_par -= 1 elif v == '(': count_par += 1 elif v == ':': if count_par == 0: break i += 1 else: raise PreprocError('rparen expected %r' % lst) if int(num): return get_term(lst[1:i]) else: return get_term(lst[i+1:]) else: num2, lst = get_num(lst[1:]) if not lst: # no more tokens to process num2 = reduce_nums(num, num2, v) return get_term([(NUM, num2)] + lst) # operator precedence p2, v2 = lst[0] if p2 != OP: raise PreprocError('op expected %r' % lst) if prec[v2] >= prec[v]: num2 = reduce_nums(num, num2, v) return get_term([(NUM, num2)] + lst) else: num3, lst = get_num(lst[1:]) num3 = reduce_nums(num2, num3, v2) return get_term([(NUM, num), (p, v), (NUM, num3)] + lst) raise PreprocError('cannot reduce %r' % lst) def reduce_eval(lst): """ Take a list of tokens and output true or false for #if/#elif conditions. :param lst: a list of tokens :type lst: list of tuple(token, value) :return: a token :rtype: tuple(NUM, int) """ num, lst = get_term(lst) return (NUM, num) def stringize(lst): """ Merge a list of tokens into a string :param lst: a list of tokens :type lst: list of tuple(token, value) :rtype: string """ lst = [str(v2) for (p2, v2) in lst] return "".join(lst) def paste_tokens(t1, t2): """ Token pasting works between identifiers, particular operators, and identifiers and numbers:: a ## b -> ab > ## = -> >= a ## 2 -> a2 :param t1: token :type t1: tuple(type, value) :param t2: token :type t2: tuple(type, value) """ p1 = None if t1[0] == OP and t2[0] == OP: p1 = OP elif t1[0] == IDENT and (t2[0] == IDENT or t2[0] == NUM): p1 = IDENT elif t1[0] == NUM and t2[0] == NUM: p1 = NUM if not p1: raise PreprocError('tokens do not make a valid paste %r and %r' % (t1, t2)) return (p1, t1[1] + t2[1]) def reduce_tokens(lst, defs, ban=[]): """ Replace the tokens in lst, using the macros provided in defs, and a list of macros that cannot be re-applied :param lst: list of tokens :type lst: list of tuple(token, value) :param defs: macro definitions :type defs: dict :param ban: macros that cannot be substituted (recursion is not allowed) :type ban: list of string :return: the new list of tokens :rtype: value, list """ i = 0 while i < len(lst): (p, v) = lst[i] if p == IDENT and v == "defined": del lst[i] if i < len(lst): (p2, v2) = lst[i] if p2 == IDENT: if v2 in defs: lst[i] = (NUM, 1) else: lst[i] = (NUM, 0) elif p2 == OP and v2 == '(': del lst[i] (p2, v2) = lst[i] del lst[i] # remove the ident, and change the ) for the value if v2 in defs: lst[i] = (NUM, 1) else: lst[i] = (NUM, 0) else: raise PreprocError('Invalid define expression %r' % lst) elif p == IDENT and v in defs: if isinstance(defs[v], str): a, b = extract_macro(defs[v]) defs[v] = b macro_def = defs[v] to_add = macro_def[1] if isinstance(macro_def[0], list): # macro without arguments del lst[i] accu = to_add[:] reduce_tokens(accu, defs, ban+[v]) for tmp in accu: lst.insert(i, tmp) i += 1 else: # collect the arguments for the funcall args = [] del lst[i] if i >= len(lst): raise PreprocError('expected ( after %r (got nothing)' % v) (p2, v2) = lst[i] if p2 != OP or v2 != '(': raise PreprocError('expected ( after %r' % v) del lst[i] one_param = [] count_paren = 0 while i < len(lst): p2, v2 = lst[i] del lst[i] if p2 == OP and count_paren == 0: if v2 == '(': one_param.append((p2, v2)) count_paren += 1 elif v2 == ')': if one_param: args.append(one_param) break elif v2 == ',': if not one_param: raise PreprocError('empty param in funcall %r' % v) args.append(one_param) one_param = [] else: one_param.append((p2, v2)) else: one_param.append((p2, v2)) if v2 == '(': count_paren += 1 elif v2 == ')': count_paren -= 1 else: raise PreprocError('malformed macro') # substitute the arguments within the define expression accu = [] arg_table = macro_def[0] j = 0 while j < len(to_add): (p2, v2) = to_add[j] if p2 == OP and v2 == '#': # stringize is for arguments only if j+1 < len(to_add) and to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: toks = args[arg_table[to_add[j+1][1]]] accu.append((STR, stringize(toks))) j += 1 else: accu.append((p2, v2)) elif p2 == OP and v2 == '##': # token pasting, how can man invent such a complicated system? if accu and j+1 < len(to_add): # we have at least two tokens t1 = accu[-1] if to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: toks = args[arg_table[to_add[j+1][1]]] if toks: accu[-1] = paste_tokens(t1, toks[0]) #(IDENT, accu[-1][1] + toks[0][1]) accu.extend(toks[1:]) else: # error, case "a##" accu.append((p2, v2)) accu.extend(toks) elif to_add[j+1][0] == IDENT and to_add[j+1][1] == '__VA_ARGS__': # first collect the tokens va_toks = [] st = len(macro_def[0]) pt = len(args) for x in args[pt-st+1:]: va_toks.extend(x) va_toks.append((OP, ',')) if va_toks: va_toks.pop() # extra comma if len(accu)>1: (p3, v3) = accu[-1] (p4, v4) = accu[-2] if v3 == '##': # remove the token paste accu.pop() if v4 == ',' and pt < st: # remove the comma accu.pop() accu += va_toks else: accu[-1] = paste_tokens(t1, to_add[j+1]) j += 1 else: # Invalid paste, case "##a" or "b##" accu.append((p2, v2)) elif p2 == IDENT and v2 in arg_table: toks = args[arg_table[v2]] reduce_tokens(toks, defs, ban+[v]) accu.extend(toks) else: accu.append((p2, v2)) j += 1 reduce_tokens(accu, defs, ban+[v]) for x in range(len(accu)-1, -1, -1): lst.insert(i, accu[x]) i += 1 def eval_macro(lst, defs): """ Reduce the tokens by :py:func:`waflib.Tools.c_preproc.reduce_tokens` and try to return a 0/1 result by :py:func:`waflib.Tools.c_preproc.reduce_eval`. :param lst: list of tokens :type lst: list of tuple(token, value) :param defs: macro definitions :type defs: dict :rtype: int """ reduce_tokens(lst, defs, []) if not lst: raise PreprocError('missing tokens to evaluate') if lst: p, v = lst[0] if p == IDENT and v not in defs: raise PreprocError('missing macro %r' % lst) p, v = reduce_eval(lst) return int(v) != 0 def extract_macro(txt): """ Process a macro definition of the form:: #define f(x, y) x * y into a function or a simple macro without arguments :param txt: expression to exact a macro definition from :type txt: string :return: a tuple containing the name, the list of arguments and the replacement :rtype: tuple(string, [list, list]) """ t = tokenize(txt) if re_fun.search(txt): p, name = t[0] p, v = t[1] if p != OP: raise PreprocError('expected (') i = 1 pindex = 0 params = {} prev = '(' while 1: i += 1 p, v = t[i] if prev == '(': if p == IDENT: params[v] = pindex pindex += 1 prev = p elif p == OP and v == ')': break else: raise PreprocError('unexpected token (3)') elif prev == IDENT: if p == OP and v == ',': prev = v elif p == OP and v == ')': break else: raise PreprocError('comma or ... expected') elif prev == ',': if p == IDENT: params[v] = pindex pindex += 1 prev = p elif p == OP and v == '...': raise PreprocError('not implemented (1)') else: raise PreprocError('comma or ... expected (2)') elif prev == '...': raise PreprocError('not implemented (2)') else: raise PreprocError('unexpected else') #~ print (name, [params, t[i+1:]]) return (name, [params, t[i+1:]]) else: (p, v) = t[0] if len(t) > 1: return (v, [[], t[1:]]) else: # empty define, assign an empty token return (v, [[], [('T','')]]) re_include = re.compile(r'^\s*(<(?:.*)>|"(?:.*)")') def extract_include(txt, defs): """ Process a line in the form:: #include foo :param txt: include line to process :type txt: string :param defs: macro definitions :type defs: dict :return: the file name :rtype: string """ m = re_include.search(txt) if m: txt = m.group(1) return txt[0], txt[1:-1] # perform preprocessing and look at the result, it must match an include toks = tokenize(txt) reduce_tokens(toks, defs, ['waf_include']) if not toks: raise PreprocError('could not parse include %r' % txt) if len(toks) == 1: if toks[0][0] == STR: return '"', toks[0][1] else: if toks[0][1] == '<' and toks[-1][1] == '>': ret = '<', stringize(toks).lstrip('<').rstrip('>') return ret raise PreprocError('could not parse include %r' % txt) def parse_char(txt): """ Parse a c character :param txt: character to parse :type txt: string :return: a character literal :rtype: string """ if not txt: raise PreprocError('attempted to parse a null char') if txt[0] != '\\': return ord(txt) c = txt[1] if c == 'x': if len(txt) == 4 and txt[3] in string.hexdigits: return int(txt[2:], 16) return int(txt[2:], 16) elif c.isdigit(): if c == '0' and len(txt)==2: return 0 for i in 3, 2, 1: if len(txt) > i and txt[1:1+i].isdigit(): return (1+i, int(txt[1:1+i], 8)) else: try: return chr_esc[c] except KeyError: raise PreprocError('could not parse char literal %r' % txt) def tokenize(s): """ Convert a string into a list of tokens (shlex.split does not apply to c/c++/d) :param s: input to tokenize :type s: string :return: a list of tokens :rtype: list of tuple(token, value) """ return tokenize_private(s)[:] # force a copy of the results def tokenize_private(s): ret = [] for match in re_clexer.finditer(s): m = match.group for name in tok_types: v = m(name) if v: if name == IDENT: if v in g_optrans: name = OP elif v.lower() == "true": v = 1 name = NUM elif v.lower() == "false": v = 0 name = NUM elif name == NUM: if m('oct'): v = int(v, 8) elif m('hex'): v = int(m('hex'), 16) elif m('n0'): v = m('n0') else: v = m('char') if v: v = parse_char(v) else: v = m('n2') or m('n4') elif name == OP: if v == '%:': v = '#' elif v == '%:%:': v = '##' elif name == STR: # remove the quotes around the string v = v[1:-1] ret.append((name, v)) break return ret def format_defines(lst): ret = [] for y in lst: if y: pos = y.find('=') if pos == -1: # "-DFOO" should give "#define FOO 1" ret.append(y) elif pos > 0: # all others are assumed to be -DX=Y ret.append('%s %s' % (y[:pos], y[pos+1:])) else: raise ValueError('Invalid define expression %r' % y) return ret class c_parser(object): """ Used by :py:func:`waflib.Tools.c_preproc.scan` to parse c/h files. Note that by default, only project headers are parsed. """ def __init__(self, nodepaths=None, defines=None): self.lines = [] """list of lines read""" if defines is None: self.defs = {} else: self.defs = dict(defines) # make a copy self.state = [] self.count_files = 0 self.currentnode_stack = [] self.nodepaths = nodepaths or [] """Include paths""" self.nodes = [] """List of :py:class:`waflib.Node.Node` found so far""" self.names = [] """List of file names that could not be matched by any file""" self.curfile = '' """Current file""" self.ban_includes = set() """Includes that must not be read (#pragma once)""" self.listed = set() """Include nodes/names already listed to avoid duplicates in self.nodes/self.names""" def cached_find_resource(self, node, filename): """ Find a file from the input directory :param node: directory :type node: :py:class:`waflib.Node.Node` :param filename: header to find :type filename: string :return: the node if found, or None :rtype: :py:class:`waflib.Node.Node` """ try: cache = node.ctx.preproc_cache_node except AttributeError: cache = node.ctx.preproc_cache_node = Utils.lru_cache(FILE_CACHE_SIZE) key = (node, filename) try: return cache[key] except KeyError: ret = node.find_resource(filename) if ret: if getattr(ret, 'children', None): ret = None elif ret.is_child_of(node.ctx.bldnode): tmp = node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode)) if tmp and getattr(tmp, 'children', None): ret = None cache[key] = ret return ret def tryfind(self, filename, kind='"', env=None): """ Try to obtain a node from the filename based from the include paths. Will add the node found to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` or the file name to :py:attr:`waflib.Tools.c_preproc.c_parser.names` if no corresponding file is found. Called by :py:attr:`waflib.Tools.c_preproc.c_parser.start`. :param filename: header to find :type filename: string :return: the node if found :rtype: :py:class:`waflib.Node.Node` """ if filename.endswith('.moc'): # we could let the qt4 module use a subclass, but then the function "scan" below must be duplicated # in the qt4 and in the qt5 classes. So we have two lines here and it is sufficient. self.names.append(filename) return None self.curfile = filename found = None if kind == '"': if env.MSVC_VERSION: for n in reversed(self.currentnode_stack): found = self.cached_find_resource(n, filename) if found: break else: found = self.cached_find_resource(self.currentnode_stack[-1], filename) if not found: for n in self.nodepaths: found = self.cached_find_resource(n, filename) if found: break listed = self.listed if found and not found in self.ban_includes: if found not in listed: listed.add(found) self.nodes.append(found) self.addlines(found) else: if filename not in listed: listed.add(filename) self.names.append(filename) return found def filter_comments(self, node): """ Filter the comments from a c/h file, and return the preprocessor lines. The regexps :py:attr:`waflib.Tools.c_preproc.re_cpp`, :py:attr:`waflib.Tools.c_preproc.re_nl` and :py:attr:`waflib.Tools.c_preproc.re_lines` are used internally. :return: the preprocessor directives as a list of (keyword, line) :rtype: a list of string pairs """ # return a list of tuples : keyword, line code = node.read() if use_trigraphs: for (a, b) in trig_def: code = code.split(a).join(b) code = re_nl.sub('', code) code = re_cpp.sub(repl, code) return re_lines.findall(code) def parse_lines(self, node): try: cache = node.ctx.preproc_cache_lines except AttributeError: cache = node.ctx.preproc_cache_lines = Utils.lru_cache(LINE_CACHE_SIZE) try: return cache[node] except KeyError: cache[node] = lines = self.filter_comments(node) lines.append((POPFILE, '')) lines.reverse() return lines def addlines(self, node): """ Add the lines from a header in the list of preprocessor lines to parse :param node: header :type node: :py:class:`waflib.Node.Node` """ self.currentnode_stack.append(node.parent) self.count_files += 1 if self.count_files > recursion_limit: # issue #812 raise PreprocError('recursion limit exceeded') if Logs.verbose: Logs.debug('preproc: reading file %r', node) try: lines = self.parse_lines(node) except EnvironmentError: raise PreprocError('could not read the file %r' % node) except Exception: if Logs.verbose > 0: Logs.error('parsing %r failed %s', node, traceback.format_exc()) else: self.lines.extend(lines) def start(self, node, env): """ Preprocess a source file to obtain the dependencies, which are accumulated to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` and :py:attr:`waflib.Tools.c_preproc.c_parser.names`. :param node: source file :type node: :py:class:`waflib.Node.Node` :param env: config set containing additional defines to take into account :type env: :py:class:`waflib.ConfigSet.ConfigSet` """ Logs.debug('preproc: scanning %s (in %s)', node.name, node.parent.name) self.current_file = node self.addlines(node) # macros may be defined on the command-line, so they must be parsed as if they were part of the file if env.DEFINES: lst = format_defines(env.DEFINES) lst.reverse() self.lines.extend([('define', x) for x in lst]) while self.lines: (token, line) = self.lines.pop() if token == POPFILE: self.count_files -= 1 self.currentnode_stack.pop() continue try: state = self.state # make certain we define the state if we are about to enter in an if block if token[:2] == 'if': state.append(undefined) elif token == 'endif': state.pop() # skip lines when in a dead 'if' branch, wait for the endif if token[0] != 'e': if skipped in self.state or ignored in self.state: continue if token == 'if': ret = eval_macro(tokenize(line), self.defs) if ret: state[-1] = accepted else: state[-1] = ignored elif token == 'ifdef': m = re_mac.match(line) if m and m.group() in self.defs: state[-1] = accepted else: state[-1] = ignored elif token == 'ifndef': m = re_mac.match(line) if m and m.group() in self.defs: state[-1] = ignored else: state[-1] = accepted elif token == 'include' or token == 'import': (kind, inc) = extract_include(line, self.defs) self.current_file = self.tryfind(inc, kind, env) if token == 'import': self.ban_includes.add(self.current_file) elif token == 'elif': if state[-1] == accepted: state[-1] = skipped elif state[-1] == ignored: if eval_macro(tokenize(line), self.defs): state[-1] = accepted elif token == 'else': if state[-1] == accepted: state[-1] = skipped elif state[-1] == ignored: state[-1] = accepted elif token == 'define': try: self.defs[self.define_name(line)] = line except AttributeError: raise PreprocError('Invalid define line %r' % line) elif token == 'undef': m = re_mac.match(line) if m and m.group() in self.defs: self.defs.__delitem__(m.group()) #print "undef %s" % name elif token == 'pragma': if re_pragma_once.match(line.lower()): self.ban_includes.add(self.current_file) except Exception as e: if Logs.verbose: Logs.debug('preproc: line parsing failed (%s): %s %s', e, line, traceback.format_exc()) def define_name(self, line): """ :param line: define line :type line: string :rtype: string :return: the define name """ return re_mac.match(line).group() def scan(task): """ Get the dependencies using a c/c++ preprocessor, this is required for finding dependencies of the kind:: #include some_macro() This function is bound as a task method on :py:class:`waflib.Tools.c.c` and :py:class:`waflib.Tools.cxx.cxx` for example """ try: incn = task.generator.includes_nodes except AttributeError: raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": ' % task.generator) if go_absolute: nodepaths = incn + [task.generator.bld.root.find_dir(x) for x in standard_includes] else: nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)] tmp = c_parser(nodepaths) tmp.start(task.inputs[0], task.env) return (tmp.nodes, tmp.names) ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py0000660000000000000000000001357013573675414021733 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2016-2018 (ita) """ Various configuration tests. """ from waflib import Task from waflib.Configure import conf from waflib.TaskGen import feature, before_method, after_method LIB_CODE = ''' #ifdef _MSC_VER #define testEXPORT __declspec(dllexport) #else #define testEXPORT #endif testEXPORT int lib_func(void) { return 9; } ''' MAIN_CODE = ''' #ifdef _MSC_VER #define testEXPORT __declspec(dllimport) #else #define testEXPORT #endif testEXPORT int lib_func(void); int main(int argc, char **argv) { (void)argc; (void)argv; return !(lib_func() == 9); } ''' @feature('link_lib_test') @before_method('process_source') def link_lib_test_fun(self): """ The configuration test :py:func:`waflib.Configure.run_build` declares a unique task generator, so we need to create other task generators from here to check if the linker is able to link libraries. """ def write_test_file(task): task.outputs[0].write(task.generator.code) rpath = [] if getattr(self, 'add_rpath', False): rpath = [self.bld.path.get_bld().abspath()] mode = self.mode m = '%s %s' % (mode, mode) ex = self.test_exec and 'test_exec' or '' bld = self.bld bld(rule=write_test_file, target='test.' + mode, code=LIB_CODE) bld(rule=write_test_file, target='main.' + mode, code=MAIN_CODE) bld(features='%sshlib' % m, source='test.' + mode, target='test') bld(features='%sprogram %s' % (m, ex), source='main.' + mode, target='app', use='test', rpath=rpath) @conf def check_library(self, mode=None, test_exec=True): """ Checks if libraries can be linked with the current linker. Uses :py:func:`waflib.Tools.c_tests.link_lib_test_fun`. :param mode: c or cxx or d :type mode: string """ if not mode: mode = 'c' if self.env.CXX: mode = 'cxx' self.check( compile_filename = [], features = 'link_lib_test', msg = 'Checking for libraries', mode = mode, test_exec = test_exec) ######################################################################################## INLINE_CODE = ''' typedef int foo_t; static %s foo_t static_foo () {return 0; } %s foo_t foo () { return 0; } ''' INLINE_VALUES = ['inline', '__inline__', '__inline'] @conf def check_inline(self, **kw): """ Checks for the right value for inline macro. Define INLINE_MACRO to 1 if the define is found. If the inline macro is not 'inline', add a define to the ``config.h`` (#define inline __inline__) :param define_name: define INLINE_MACRO by default to 1 if the macro is defined :type define_name: string :param features: by default *c* or *cxx* depending on the compiler present :type features: list of string """ self.start_msg('Checking for inline') if not 'define_name' in kw: kw['define_name'] = 'INLINE_MACRO' if not 'features' in kw: if self.env.CXX: kw['features'] = ['cxx'] else: kw['features'] = ['c'] for x in INLINE_VALUES: kw['fragment'] = INLINE_CODE % (x, x) try: self.check(**kw) except self.errors.ConfigurationError: continue else: self.end_msg(x) if x != 'inline': self.define('inline', x, quote=False) return x self.fatal('could not use inline functions') ######################################################################################## LARGE_FRAGMENT = '''#include int main(int argc, char **argv) { (void)argc; (void)argv; return !(sizeof(off_t) >= 8); } ''' @conf def check_large_file(self, **kw): """ Checks for large file support and define the macro HAVE_LARGEFILE The test is skipped on win32 systems (DEST_BINFMT == pe). :param define_name: define to set, by default *HAVE_LARGEFILE* :type define_name: string :param execute: execute the test (yes by default) :type execute: bool """ if not 'define_name' in kw: kw['define_name'] = 'HAVE_LARGEFILE' if not 'execute' in kw: kw['execute'] = True if not 'features' in kw: if self.env.CXX: kw['features'] = ['cxx', 'cxxprogram'] else: kw['features'] = ['c', 'cprogram'] kw['fragment'] = LARGE_FRAGMENT kw['msg'] = 'Checking for large file support' ret = True try: if self.env.DEST_BINFMT != 'pe': ret = self.check(**kw) except self.errors.ConfigurationError: pass else: if ret: return True kw['msg'] = 'Checking for -D_FILE_OFFSET_BITS=64' kw['defines'] = ['_FILE_OFFSET_BITS=64'] try: ret = self.check(**kw) except self.errors.ConfigurationError: pass else: self.define('_FILE_OFFSET_BITS', 64) return ret self.fatal('There is no support for large files') ######################################################################################## ENDIAN_FRAGMENT = ''' short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; ''' class grep_for_endianness(Task.Task): """ Task that reads a binary and tries to determine the endianness """ color = 'PINK' def run(self): txt = self.inputs[0].read(flags='rb').decode('latin-1') if txt.find('LiTTleEnDian') > -1: self.generator.tmp.append('little') elif txt.find('BIGenDianSyS') > -1: self.generator.tmp.append('big') else: return -1 @feature('grep_for_endianness') @after_method('process_source') def grep_for_endianness_fun(self): """ Used by the endianness configuration test """ self.create_task('grep_for_endianness', self.compiled_tasks[0].outputs[0]) @conf def check_endianness(self): """ Executes a configuration test to determine the endianness """ tmp = [] def check_msg(self): return tmp[0] self.check(fragment=ENDIAN_FRAGMENT, features='c grep_for_endianness', msg='Checking for endianness', define='ENDIANNESS', tmp=tmp, okmsg=check_msg, confcache=None) return tmp[0] ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py0000660000000000000000000006322413573675414021561 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Classes and methods shared by tools providing support for C-like language such as C/C++/D/Assembly/Go (this support module is almost never used alone). """ import os, re from waflib import Task, Utils, Node, Errors, Logs from waflib.TaskGen import after_method, before_method, feature, taskgen_method, extension from waflib.Tools import c_aliases, c_preproc, c_config, c_osx, c_tests from waflib.Configure import conf SYSTEM_LIB_PATHS = ['/usr/lib64', '/usr/lib', '/usr/local/lib64', '/usr/local/lib'] USELIB_VARS = Utils.defaultdict(set) """ Mapping for features to :py:class:`waflib.ConfigSet.ConfigSet` variables. See :py:func:`waflib.Tools.ccroot.propagate_uselib_vars`. """ USELIB_VARS['c'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CCDEPS', 'CFLAGS', 'ARCH']) USELIB_VARS['cxx'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CXXDEPS', 'CXXFLAGS', 'ARCH']) USELIB_VARS['d'] = set(['INCLUDES', 'DFLAGS']) USELIB_VARS['includes'] = set(['INCLUDES', 'FRAMEWORKPATH', 'ARCH']) USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) USELIB_VARS['cstlib'] = USELIB_VARS['cxxstlib'] = set(['ARFLAGS', 'LINKDEPS']) USELIB_VARS['dprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) USELIB_VARS['dshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) USELIB_VARS['dstlib'] = set(['ARFLAGS', 'LINKDEPS']) USELIB_VARS['asm'] = set(['ASFLAGS']) # ================================================================================================= @taskgen_method def create_compiled_task(self, name, node): """ Create the compilation task: c, cxx, asm, etc. The output node is created automatically (object file with a typical **.o** extension). The task is appended to the list *compiled_tasks* which is then used by :py:func:`waflib.Tools.ccroot.apply_link` :param name: name of the task class :type name: string :param node: the file to compile :type node: :py:class:`waflib.Node.Node` :return: The task created :rtype: :py:class:`waflib.Task.Task` """ out = '%s.%d.o' % (node.name, self.idx) task = self.create_task(name, node, node.parent.find_or_declare(out)) try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] return task @taskgen_method def to_incnodes(self, inlst): """ Task generator method provided to convert a list of string/nodes into a list of includes folders. The paths are assumed to be relative to the task generator path, except if they begin by **#** in which case they are searched from the top-level directory (``bld.srcnode``). The folders are simply assumed to be existing. The node objects in the list are returned in the output list. The strings are converted into node objects if possible. The node is searched from the source directory, and if a match is found, the equivalent build directory is created and added to the returned list too. When a folder cannot be found, it is ignored. :param inlst: list of folders :type inlst: space-delimited string or a list of string/nodes :rtype: list of :py:class:`waflib.Node.Node` :return: list of include folders as nodes """ lst = [] seen = set() for x in self.to_list(inlst): if x in seen or not x: continue seen.add(x) # with a real lot of targets, it is sometimes interesting to cache the results below if isinstance(x, Node.Node): lst.append(x) else: if os.path.isabs(x): lst.append(self.bld.root.make_node(x) or x) else: if x[0] == '#': p = self.bld.bldnode.make_node(x[1:]) v = self.bld.srcnode.make_node(x[1:]) else: p = self.path.get_bld().make_node(x) v = self.path.make_node(x) if p.is_child_of(self.bld.bldnode): p.mkdir() lst.append(p) lst.append(v) return lst @feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') @after_method('propagate_uselib_vars', 'process_source') def apply_incpaths(self): """ Task generator method that processes the attribute *includes*:: tg = bld(features='includes', includes='.') The folders only need to be relative to the current directory, the equivalent build directory is added automatically (for headers created in the build directory). This enables using a build directory or not (``top == out``). This method will add a list of nodes read by :py:func:`waflib.Tools.ccroot.to_incnodes` in ``tg.env.INCPATHS``, and the list of include paths in ``tg.env.INCLUDES``. """ lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env.INCLUDES) self.includes_nodes = lst cwd = self.get_cwd() self.env.INCPATHS = [x.path_from(cwd) for x in lst] class link_task(Task.Task): """ Base class for all link tasks. A task generator is supposed to have at most one link task bound in the attribute *link_task*. See :py:func:`waflib.Tools.ccroot.apply_link`. .. inheritance-diagram:: waflib.Tools.ccroot.stlink_task waflib.Tools.c.cprogram waflib.Tools.c.cshlib waflib.Tools.cxx.cxxstlib waflib.Tools.cxx.cxxprogram waflib.Tools.cxx.cxxshlib waflib.Tools.d.dprogram waflib.Tools.d.dshlib waflib.Tools.d.dstlib waflib.Tools.ccroot.fake_shlib waflib.Tools.ccroot.fake_stlib waflib.Tools.asm.asmprogram waflib.Tools.asm.asmshlib waflib.Tools.asm.asmstlib """ color = 'YELLOW' weight = 3 """Try to process link tasks as early as possible""" inst_to = None """Default installation path for the link task outputs, or None to disable""" chmod = Utils.O755 """Default installation mode for the link task outputs""" def add_target(self, target): """ Process the *target* attribute to add the platform-specific prefix/suffix such as *.so* or *.exe*. The settings are retrieved from ``env.clsname_PATTERN`` """ if isinstance(target, str): base = self.generator.path if target.startswith('#'): # for those who like flat structures target = target[1:] base = self.generator.bld.bldnode pattern = self.env[self.__class__.__name__ + '_PATTERN'] if not pattern: pattern = '%s' folder, name = os.path.split(target) if self.__class__.__name__.find('shlib') > 0 and getattr(self.generator, 'vnum', None): nums = self.generator.vnum.split('.') if self.env.DEST_BINFMT == 'pe': # include the version in the dll file name, # the import lib file name stays unversioned. name = name + '-' + nums[0] elif self.env.DEST_OS == 'openbsd': pattern = '%s.%s' % (pattern, nums[0]) if len(nums) >= 2: pattern += '.%s' % nums[1] if folder: tmp = folder + os.sep + pattern % name else: tmp = pattern % name target = base.find_or_declare(tmp) self.set_outputs(target) def exec_command(self, *k, **kw): ret = super(link_task, self).exec_command(*k, **kw) if not ret and self.env.DO_MANIFEST: ret = self.exec_mf() return ret def exec_mf(self): """ Create manifest files for VS-like compilers (msvc, ifort, ...) """ if not self.env.MT: return 0 manifest = None for out_node in self.outputs: if out_node.name.endswith('.manifest'): manifest = out_node.abspath() break else: # Should never get here. If we do, it means the manifest file was # never added to the outputs list, thus we don't have a manifest file # to embed, so we just return. return 0 # embedding mode. Different for EXE's and DLL's. # see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx mode = '' for x in Utils.to_list(self.generator.features): if x in ('cprogram', 'cxxprogram', 'fcprogram', 'fcprogram_test'): mode = 1 elif x in ('cshlib', 'cxxshlib', 'fcshlib'): mode = 2 Logs.debug('msvc: embedding manifest in mode %r', mode) lst = [] + self.env.MT lst.extend(Utils.to_list(self.env.MTFLAGS)) lst.extend(['-manifest', manifest]) lst.append('-outputresource:%s;%s' % (self.outputs[0].abspath(), mode)) return super(link_task, self).exec_command(lst) class stlink_task(link_task): """ Base for static link tasks, which use *ar* most of the time. The target is always removed before being written. """ run_str = '${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}' chmod = Utils.O644 """Default installation mode for the static libraries""" def rm_tgt(cls): old = cls.run def wrap(self): try: os.remove(self.outputs[0].abspath()) except OSError: pass return old(self) setattr(cls, 'run', wrap) rm_tgt(stlink_task) @feature('skip_stlib_link_deps') @before_method('process_use') def apply_skip_stlib_link_deps(self): """ This enables an optimization in the :py:func:wafilb.Tools.ccroot.processes_use: method that skips dependency and link flag optimizations for targets that generate static libraries (via the :py:class:Tools.ccroot.stlink_task task). The actual behavior is implemented in :py:func:wafilb.Tools.ccroot.processes_use: method so this feature only tells waf to enable the new behavior. """ self.env.SKIP_STLIB_LINK_DEPS = True @feature('c', 'cxx', 'd', 'fc', 'asm') @after_method('process_source') def apply_link(self): """ Collect the tasks stored in ``compiled_tasks`` (created by :py:func:`waflib.Tools.ccroot.create_compiled_task`), and use the outputs for a new instance of :py:class:`waflib.Tools.ccroot.link_task`. The class to use is the first link task matching a name from the attribute *features*, for example:: def build(bld): tg = bld(features='cxx cxxprogram cprogram', source='main.c', target='app') will create the task ``tg.link_task`` as a new instance of :py:class:`waflib.Tools.cxx.cxxprogram` """ for x in self.features: if x == 'cprogram' and 'cxx' in self.features: # limited compat x = 'cxxprogram' elif x == 'cshlib' and 'cxx' in self.features: x = 'cxxshlib' if x in Task.classes: if issubclass(Task.classes[x], link_task): link = x break else: return objs = [t.outputs[0] for t in getattr(self, 'compiled_tasks', [])] self.link_task = self.create_task(link, objs) self.link_task.add_target(self.target) # remember that the install paths are given by the task generators try: inst_to = self.install_path except AttributeError: inst_to = self.link_task.inst_to if inst_to: # install a copy of the node list we have at this moment (implib not added) self.install_task = self.add_install_files( install_to=inst_to, install_from=self.link_task.outputs[:], chmod=self.link_task.chmod, task=self.link_task) @taskgen_method def use_rec(self, name, **kw): """ Processes the ``use`` keyword recursively. This method is kind of private and only meant to be used from ``process_use`` """ if name in self.tmp_use_not or name in self.tmp_use_seen: return try: y = self.bld.get_tgen_by_name(name) except Errors.WafError: self.uselib.append(name) self.tmp_use_not.add(name) return self.tmp_use_seen.append(name) y.post() # bind temporary attributes on the task generator y.tmp_use_objects = objects = kw.get('objects', True) y.tmp_use_stlib = stlib = kw.get('stlib', True) try: link_task = y.link_task except AttributeError: y.tmp_use_var = '' else: objects = False if not isinstance(link_task, stlink_task): stlib = False y.tmp_use_var = 'LIB' else: y.tmp_use_var = 'STLIB' p = self.tmp_use_prec for x in self.to_list(getattr(y, 'use', [])): if self.env["STLIB_" + x]: continue try: p[x].append(name) except KeyError: p[x] = [name] self.use_rec(x, objects=objects, stlib=stlib) @feature('c', 'cxx', 'd', 'use', 'fc') @before_method('apply_incpaths', 'propagate_uselib_vars') @after_method('apply_link', 'process_source') def process_use(self): """ Process the ``use`` attribute which contains a list of task generator names:: def build(bld): bld.shlib(source='a.c', target='lib1') bld.program(source='main.c', target='app', use='lib1') See :py:func:`waflib.Tools.ccroot.use_rec`. """ use_not = self.tmp_use_not = set() self.tmp_use_seen = [] # we would like an ordered set use_prec = self.tmp_use_prec = {} self.uselib = self.to_list(getattr(self, 'uselib', [])) self.includes = self.to_list(getattr(self, 'includes', [])) names = self.to_list(getattr(self, 'use', [])) for x in names: self.use_rec(x) for x in use_not: if x in use_prec: del use_prec[x] # topological sort out = self.tmp_use_sorted = [] tmp = [] for x in self.tmp_use_seen: for k in use_prec.values(): if x in k: break else: tmp.append(x) while tmp: e = tmp.pop() out.append(e) try: nlst = use_prec[e] except KeyError: pass else: del use_prec[e] for x in nlst: for y in use_prec: if x in use_prec[y]: break else: tmp.append(x) if use_prec: raise Errors.WafError('Cycle detected in the use processing %r' % use_prec) out.reverse() link_task = getattr(self, 'link_task', None) for x in out: y = self.bld.get_tgen_by_name(x) var = y.tmp_use_var if var and link_task: if self.env.SKIP_STLIB_LINK_DEPS and isinstance(link_task, stlink_task): # If the skip_stlib_link_deps feature is enabled then we should # avoid adding lib deps to the stlink_task instance. pass elif var == 'LIB' or y.tmp_use_stlib or x in names: self.env.append_value(var, [y.target[y.target.rfind(os.sep) + 1:]]) self.link_task.dep_nodes.extend(y.link_task.outputs) tmp_path = y.link_task.outputs[0].parent.path_from(self.get_cwd()) self.env.append_unique(var + 'PATH', [tmp_path]) else: if y.tmp_use_objects: self.add_objects_from_tgen(y) if getattr(y, 'export_includes', None): # self.includes may come from a global variable #2035 self.includes = self.includes + y.to_incnodes(y.export_includes) if getattr(y, 'export_defines', None): self.env.append_value('DEFINES', self.to_list(y.export_defines)) # and finally, add the use variables (no recursion needed) for x in names: try: y = self.bld.get_tgen_by_name(x) except Errors.WafError: if not self.env['STLIB_' + x] and not x in self.uselib: self.uselib.append(x) else: for k in self.to_list(getattr(y, 'use', [])): if not self.env['STLIB_' + k] and not k in self.uselib: self.uselib.append(k) @taskgen_method def accept_node_to_link(self, node): """ PRIVATE INTERNAL USE ONLY """ return not node.name.endswith('.pdb') @taskgen_method def add_objects_from_tgen(self, tg): """ Add the objects from the depending compiled tasks as link task inputs. Some objects are filtered: for instance, .pdb files are added to the compiled tasks but not to the link tasks (to avoid errors) PRIVATE INTERNAL USE ONLY """ try: link_task = self.link_task except AttributeError: pass else: for tsk in getattr(tg, 'compiled_tasks', []): for x in tsk.outputs: if self.accept_node_to_link(x): link_task.inputs.append(x) @taskgen_method def get_uselib_vars(self): """ :return: the *uselib* variables associated to the *features* attribute (see :py:attr:`waflib.Tools.ccroot.USELIB_VARS`) :rtype: list of string """ _vars = set() for x in self.features: if x in USELIB_VARS: _vars |= USELIB_VARS[x] return _vars @feature('c', 'cxx', 'd', 'fc', 'javac', 'cs', 'uselib', 'asm') @after_method('process_use') def propagate_uselib_vars(self): """ Process uselib variables for adding flags. For example, the following target:: def build(bld): bld.env.AFLAGS_aaa = ['bar'] from waflib.Tools.ccroot import USELIB_VARS USELIB_VARS['aaa'] = ['AFLAGS'] tg = bld(features='aaa', aflags='test') The *aflags* attribute will be processed and this method will set:: tg.env.AFLAGS = ['bar', 'test'] """ _vars = self.get_uselib_vars() env = self.env app = env.append_value feature_uselib = self.features + self.to_list(getattr(self, 'uselib', [])) for var in _vars: y = var.lower() val = getattr(self, y, []) if val: app(var, self.to_list(val)) for x in feature_uselib: val = env['%s_%s' % (var, x)] if val: app(var, val) # ============ the code above must not know anything about import libs ========== @feature('cshlib', 'cxxshlib', 'fcshlib') @after_method('apply_link') def apply_implib(self): """ Handle dlls and their import libs on Windows-like systems. A ``.dll.a`` file called *import library* is generated. It must be installed as it is required for linking the library. """ if not self.env.DEST_BINFMT == 'pe': return dll = self.link_task.outputs[0] if isinstance(self.target, Node.Node): name = self.target.name else: name = os.path.split(self.target)[1] implib = self.env.implib_PATTERN % name implib = dll.parent.find_or_declare(implib) self.env.append_value('LINKFLAGS', self.env.IMPLIB_ST % implib.bldpath()) self.link_task.outputs.append(implib) if getattr(self, 'defs', None) and self.env.DEST_BINFMT == 'pe': node = self.path.find_resource(self.defs) if not node: raise Errors.WafError('invalid def file %r' % self.defs) if self.env.def_PATTERN: self.env.append_value('LINKFLAGS', self.env.def_PATTERN % node.path_from(self.get_cwd())) self.link_task.dep_nodes.append(node) else: # gcc for windows takes *.def file as input without any special flag self.link_task.inputs.append(node) # where to put the import library if getattr(self, 'install_task', None): try: # user has given a specific installation path for the import library inst_to = self.install_path_implib except AttributeError: try: # user has given an installation path for the main library, put the import library in it inst_to = self.install_path except AttributeError: # else, put the library in BINDIR and the import library in LIBDIR inst_to = '${IMPLIBDIR}' self.install_task.install_to = '${BINDIR}' if not self.env.IMPLIBDIR: self.env.IMPLIBDIR = self.env.LIBDIR self.implib_install_task = self.add_install_files(install_to=inst_to, install_from=implib, chmod=self.link_task.chmod, task=self.link_task) # ============ the code above must not know anything about vnum processing on unix platforms ========= re_vnum = re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$') @feature('cshlib', 'cxxshlib', 'dshlib', 'fcshlib', 'vnum') @after_method('apply_link', 'propagate_uselib_vars') def apply_vnum(self): """ Enforce version numbering on shared libraries. The valid version numbers must have either zero or two dots:: def build(bld): bld.shlib(source='a.c', target='foo', vnum='14.15.16') In this example on Linux platform, ``libfoo.so`` is installed as ``libfoo.so.14.15.16``, and the following symbolic links are created: * ``libfoo.so → libfoo.so.14.15.16`` * ``libfoo.so.14 → libfoo.so.14.15.16`` By default, the library will be assigned SONAME ``libfoo.so.14``, effectively declaring ABI compatibility between all minor and patch releases for the major version of the library. When necessary, the compatibility can be explicitly defined using `cnum` parameter: def build(bld): bld.shlib(source='a.c', target='foo', vnum='14.15.16', cnum='14.15') In this case, the assigned SONAME will be ``libfoo.so.14.15`` with ABI compatibility only between path releases for a specific major and minor version of the library. On OS X platform, install-name parameter will follow the above logic for SONAME with exception that it also specifies an absolute path (based on install_path) of the library. """ if not getattr(self, 'vnum', '') or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'): return link = self.link_task if not re_vnum.match(self.vnum): raise Errors.WafError('Invalid vnum %r for target %r' % (self.vnum, getattr(self, 'name', self))) nums = self.vnum.split('.') node = link.outputs[0] cnum = getattr(self, 'cnum', str(nums[0])) cnums = cnum.split('.') if len(cnums)>len(nums) or nums[0:len(cnums)] != cnums: raise Errors.WafError('invalid compatibility version %s' % cnum) libname = node.name if libname.endswith('.dylib'): name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum) name2 = libname.replace('.dylib', '.%s.dylib' % cnum) else: name3 = libname + '.' + self.vnum name2 = libname + '.' + cnum # add the so name for the ld linker - to disable, just unset env.SONAME_ST if self.env.SONAME_ST: v = self.env.SONAME_ST % name2 self.env.append_value('LINKFLAGS', v.split()) # the following task is just to enable execution from the build dir :-/ if self.env.DEST_OS != 'openbsd': outs = [node.parent.make_node(name3)] if name2 != name3: outs.append(node.parent.make_node(name2)) self.create_task('vnum', node, outs) if getattr(self, 'install_task', None): self.install_task.hasrun = Task.SKIPPED self.install_task.no_errcheck_out = True path = self.install_task.install_to if self.env.DEST_OS == 'openbsd': libname = self.link_task.outputs[0].name t1 = self.add_install_as(install_to='%s/%s' % (path, libname), install_from=node, chmod=self.link_task.chmod) self.vnum_install_task = (t1,) else: t1 = self.add_install_as(install_to=path + os.sep + name3, install_from=node, chmod=self.link_task.chmod) t3 = self.add_symlink_as(install_to=path + os.sep + libname, install_from=name3) if name2 != name3: t2 = self.add_symlink_as(install_to=path + os.sep + name2, install_from=name3) self.vnum_install_task = (t1, t2, t3) else: self.vnum_install_task = (t1, t3) if '-dynamiclib' in self.env.LINKFLAGS: # this requires after(propagate_uselib_vars) try: inst_to = self.install_path except AttributeError: inst_to = self.link_task.inst_to if inst_to: p = Utils.subst_vars(inst_to, self.env) path = os.path.join(p, name2) self.env.append_value('LINKFLAGS', ['-install_name', path]) self.env.append_value('LINKFLAGS', '-Wl,-compatibility_version,%s' % cnum) self.env.append_value('LINKFLAGS', '-Wl,-current_version,%s' % self.vnum) class vnum(Task.Task): """ Create the symbolic links for a versioned shared library. Instances are created by :py:func:`waflib.Tools.ccroot.apply_vnum` """ color = 'CYAN' ext_in = ['.bin'] def keyword(self): return 'Symlinking' def run(self): for x in self.outputs: path = x.abspath() try: os.remove(path) except OSError: pass try: os.symlink(self.inputs[0].name, path) except OSError: return 1 class fake_shlib(link_task): """ Task used for reading a system library and adding the dependency on it """ def runnable_status(self): for t in self.run_after: if not t.hasrun: return Task.ASK_LATER return Task.SKIP_ME class fake_stlib(stlink_task): """ Task used for reading a system library and adding the dependency on it """ def runnable_status(self): for t in self.run_after: if not t.hasrun: return Task.ASK_LATER return Task.SKIP_ME @conf def read_shlib(self, name, paths=[], export_includes=[], export_defines=[]): """ Read a system shared library, enabling its use as a local library. Will trigger a rebuild if the file changes:: def build(bld): bld.read_shlib('m') bld.program(source='main.c', use='m') """ return self(name=name, features='fake_lib', lib_paths=paths, lib_type='shlib', export_includes=export_includes, export_defines=export_defines) @conf def read_stlib(self, name, paths=[], export_includes=[], export_defines=[]): """ Read a system static library, enabling a use as a local library. Will trigger a rebuild if the file changes. """ return self(name=name, features='fake_lib', lib_paths=paths, lib_type='stlib', export_includes=export_includes, export_defines=export_defines) lib_patterns = { 'shlib' : ['lib%s.so', '%s.so', 'lib%s.dylib', 'lib%s.dll', '%s.dll'], 'stlib' : ['lib%s.a', '%s.a', 'lib%s.dll', '%s.dll', 'lib%s.lib', '%s.lib'], } @feature('fake_lib') def process_lib(self): """ Find the location of a foreign library. Used by :py:class:`waflib.Tools.ccroot.read_shlib` and :py:class:`waflib.Tools.ccroot.read_stlib`. """ node = None names = [x % self.name for x in lib_patterns[self.lib_type]] for x in self.lib_paths + [self.path] + SYSTEM_LIB_PATHS: if not isinstance(x, Node.Node): x = self.bld.root.find_node(x) or self.path.find_node(x) if not x: continue for y in names: node = x.find_node(y) if node: try: Utils.h_file(node.abspath()) except EnvironmentError: raise ValueError('Could not read %r' % y) break else: continue break else: raise Errors.WafError('could not find library %r' % self.name) self.link_task = self.create_task('fake_%s' % self.lib_type, [], [node]) self.target = self.name class fake_o(Task.Task): def runnable_status(self): return Task.SKIP_ME @extension('.o', '.obj') def add_those_o_files(self, node): tsk = self.create_task('fake_o', [], node) try: self.compiled_tasks.append(tsk) except AttributeError: self.compiled_tasks = [tsk] @feature('fake_obj') @before_method('process_source') def process_objs(self): """ Puts object files in the task generator outputs """ for node in self.to_nodes(self.source): self.add_those_o_files(node) self.source = [] @conf def read_object(self, obj): """ Read an object file, enabling injection in libs/programs. Will trigger a rebuild if the file changes. :param obj: object file path, as string or Node """ if not isinstance(obj, self.path.__class__): obj = self.path.find_resource(obj) return self(features='fake_obj', source=obj, name=obj.name) @feature('cxxprogram', 'cprogram') @after_method('apply_link', 'process_use') def set_full_paths_hpux(self): """ On hp-ux, extend the libpaths and static library paths to absolute paths """ if self.env.DEST_OS != 'hp-ux': return base = self.bld.bldnode.abspath() for var in ['LIBPATH', 'STLIBPATH']: lst = [] for x in self.env[var]: if x.startswith('/'): lst.append(x) else: lst.append(os.path.normpath(os.path.join(base, x))) self.env[var] = lst ldb-2.0.8/third_party/waf/waflib/Tools/clang.py0000660000000000000000000000115713573675414021351 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Krzysztof Kosiński 2014 """ Detect the Clang C compiler """ from waflib.Tools import ccroot, ar, gcc from waflib.Configure import conf @conf def find_clang(conf): """ Finds the program clang and executes it to ensure it really is clang """ cc = conf.find_program('clang', var='CC') conf.get_cc_version(cc, clang=True) conf.env.CC_NAME = 'clang' def configure(conf): conf.find_clang() conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gcc_common_flags() conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py0000660000000000000000000000121013573675414021717 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy 2009-2018 (ita) """ Detect the Clang++ C++ compiler """ from waflib.Tools import ccroot, ar, gxx from waflib.Configure import conf @conf def find_clangxx(conf): """ Finds the program clang++, and executes it to ensure it really is clang++ """ cxx = conf.find_program('clang++', var='CXX') conf.get_cc_version(cxx, clang=True) conf.env.CXX_NAME = 'clang' def configure(conf): conf.find_clangxx() conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gxx_common_flags() conf.gxx_modifier_platform() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py0000660000000000000000000000611513573675414022400 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Matthias Jahn jahn dôt matthias ât freenet dôt de, 2007 (pmarat) """ Try to detect a C compiler from the list of supported compilers (gcc, msvc, etc):: def options(opt): opt.load('compiler_c') def configure(cnf): cnf.load('compiler_c') def build(bld): bld.program(source='main.c', target='app') The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_c.c_compiler`. To register a new C compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: from waflib.Tools.compiler_c import c_compiler c_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] def options(opt): opt.load('compiler_c') def configure(cnf): cnf.load('compiler_c') def build(bld): bld.program(source='main.c', target='app') Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: $ CC=clang waf configure """ import re from waflib.Tools import ccroot from waflib import Utils from waflib.Logs import debug c_compiler = { 'win32': ['msvc', 'gcc', 'clang'], 'cygwin': ['gcc'], 'darwin': ['clang', 'gcc'], 'aix': ['xlc', 'gcc', 'clang'], 'linux': ['gcc', 'clang', 'icc'], 'sunos': ['suncc', 'gcc'], 'irix': ['gcc', 'irixcc'], 'hpux': ['gcc'], 'osf1V': ['gcc'], 'gnu': ['gcc', 'clang'], 'java': ['gcc', 'msvc', 'clang', 'icc'], 'default':['clang', 'gcc'], } """ Dict mapping platform names to Waf tools finding specific C compilers:: from waflib.Tools.compiler_c import c_compiler c_compiler['linux'] = ['gcc', 'icc', 'suncc'] """ def default_compilers(): build_platform = Utils.unversioned_sys_platform() possible_compiler_list = c_compiler.get(build_platform, c_compiler['default']) return ' '.join(possible_compiler_list) def configure(conf): """ Detects a suitable C compiler :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found """ try: test_for_compiler = conf.options.check_c_compiler or default_compilers() except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_c')") for compiler in re.split('[ ,]+', test_for_compiler): conf.env.stash() conf.start_msg('Checking for %r (C compiler)' % compiler) try: conf.load(compiler) except conf.errors.ConfigurationError as e: conf.env.revert() conf.end_msg(False) debug('compiler_c: %r', e) else: if conf.env.CC: conf.end_msg(conf.env.get_flat('CC')) conf.env.COMPILER_CC = compiler conf.env.commit() break conf.env.revert() conf.end_msg(False) else: conf.fatal('could not configure a C compiler!') def options(opt): """ This is how to provide compiler preferences on the command-line:: $ waf configure --check-c-compiler=gcc """ test_for_compiler = default_compilers() opt.load_special_tools('c_*.py', ban=['c_dumbpreproc.py']) cc_compiler_opts = opt.add_option_group('Configuration options') cc_compiler_opts.add_option('--check-c-compiler', default=None, help='list of C compilers to try [%s]' % test_for_compiler, dest="check_c_compiler") for x in test_for_compiler.split(): opt.load('%s' % x) ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py0000660000000000000000000000620413573675414022757 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Matthias Jahn jahn dôt matthias ât freenet dôt de 2007 (pmarat) """ Try to detect a C++ compiler from the list of supported compilers (g++, msvc, etc):: def options(opt): opt.load('compiler_cxx') def configure(cnf): cnf.load('compiler_cxx') def build(bld): bld.program(source='main.cpp', target='app') The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_cxx.cxx_compiler`. To register a new C++ compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: from waflib.Tools.compiler_cxx import cxx_compiler cxx_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] def options(opt): opt.load('compiler_cxx') def configure(cnf): cnf.load('compiler_cxx') def build(bld): bld.program(source='main.c', target='app') Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: $ CXX=clang waf configure """ import re from waflib.Tools import ccroot from waflib import Utils from waflib.Logs import debug cxx_compiler = { 'win32': ['msvc', 'g++', 'clang++'], 'cygwin': ['g++'], 'darwin': ['clang++', 'g++'], 'aix': ['xlc++', 'g++', 'clang++'], 'linux': ['g++', 'clang++', 'icpc'], 'sunos': ['sunc++', 'g++'], 'irix': ['g++'], 'hpux': ['g++'], 'osf1V': ['g++'], 'gnu': ['g++', 'clang++'], 'java': ['g++', 'msvc', 'clang++', 'icpc'], 'default': ['clang++', 'g++'] } """ Dict mapping the platform names to Waf tools finding specific C++ compilers:: from waflib.Tools.compiler_cxx import cxx_compiler cxx_compiler['linux'] = ['gxx', 'icpc', 'suncxx'] """ def default_compilers(): build_platform = Utils.unversioned_sys_platform() possible_compiler_list = cxx_compiler.get(build_platform, cxx_compiler['default']) return ' '.join(possible_compiler_list) def configure(conf): """ Detects a suitable C++ compiler :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found """ try: test_for_compiler = conf.options.check_cxx_compiler or default_compilers() except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_cxx')") for compiler in re.split('[ ,]+', test_for_compiler): conf.env.stash() conf.start_msg('Checking for %r (C++ compiler)' % compiler) try: conf.load(compiler) except conf.errors.ConfigurationError as e: conf.env.revert() conf.end_msg(False) debug('compiler_cxx: %r', e) else: if conf.env.CXX: conf.end_msg(conf.env.get_flat('CXX')) conf.env.COMPILER_CXX = compiler conf.env.commit() break conf.env.revert() conf.end_msg(False) else: conf.fatal('could not configure a C++ compiler!') def options(opt): """ This is how to provide compiler preferences on the command-line:: $ waf configure --check-cxx-compiler=gxx """ test_for_compiler = default_compilers() opt.load_special_tools('cxx_*.py') cxx_compiler_opts = opt.add_option_group('Configuration options') cxx_compiler_opts.add_option('--check-cxx-compiler', default=None, help='list of C++ compilers to try [%s]' % test_for_compiler, dest="check_cxx_compiler") for x in test_for_compiler.split(): opt.load('%s' % x) ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py0000660000000000000000000000433113573675414022377 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2007 (dv) # Thomas Nagy, 2016-2018 (ita) """ Try to detect a D compiler from the list of supported compilers:: def options(opt): opt.load('compiler_d') def configure(cnf): cnf.load('compiler_d') def build(bld): bld.program(source='main.d', target='app') Only three D compilers are really present at the moment: * gdc * dmd, the ldc compiler having a very similar command-line interface * ldc2 """ import re from waflib import Utils, Logs d_compiler = { 'default' : ['gdc', 'dmd', 'ldc2'] } """ Dict mapping the platform names to lists of names of D compilers to try, in order of preference:: from waflib.Tools.compiler_d import d_compiler d_compiler['default'] = ['gdc', 'dmd', 'ldc2'] """ def default_compilers(): build_platform = Utils.unversioned_sys_platform() possible_compiler_list = d_compiler.get(build_platform, d_compiler['default']) return ' '.join(possible_compiler_list) def configure(conf): """ Detects a suitable D compiler :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found """ try: test_for_compiler = conf.options.check_d_compiler or default_compilers() except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_d')") for compiler in re.split('[ ,]+', test_for_compiler): conf.env.stash() conf.start_msg('Checking for %r (D compiler)' % compiler) try: conf.load(compiler) except conf.errors.ConfigurationError as e: conf.env.revert() conf.end_msg(False) Logs.debug('compiler_d: %r', e) else: if conf.env.D: conf.end_msg(conf.env.get_flat('D')) conf.env.COMPILER_D = compiler conf.env.commit() break conf.env.revert() conf.end_msg(False) else: conf.fatal('could not configure a D compiler!') def options(opt): """ This is how to provide compiler preferences on the command-line:: $ waf configure --check-d-compiler=dmd """ test_for_compiler = default_compilers() d_compiler_opts = opt.add_option_group('Configuration options') d_compiler_opts.add_option('--check-d-compiler', default=None, help='list of D compilers to try [%s]' % test_for_compiler, dest='check_d_compiler') for x in test_for_compiler.split(): opt.load('%s' % x) ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py0000660000000000000000000000416213573675414022546 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 import re from waflib import Utils, Logs from waflib.Tools import fc fc_compiler = { 'win32' : ['gfortran','ifort'], 'darwin' : ['gfortran', 'g95', 'ifort'], 'linux' : ['gfortran', 'g95', 'ifort'], 'java' : ['gfortran', 'g95', 'ifort'], 'default': ['gfortran'], 'aix' : ['gfortran'] } """ Dict mapping the platform names to lists of names of Fortran compilers to try, in order of preference:: from waflib.Tools.compiler_c import c_compiler c_compiler['linux'] = ['gfortran', 'g95', 'ifort'] """ def default_compilers(): build_platform = Utils.unversioned_sys_platform() possible_compiler_list = fc_compiler.get(build_platform, fc_compiler['default']) return ' '.join(possible_compiler_list) def configure(conf): """ Detects a suitable Fortran compiler :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found """ try: test_for_compiler = conf.options.check_fortran_compiler or default_compilers() except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_fc')") for compiler in re.split('[ ,]+', test_for_compiler): conf.env.stash() conf.start_msg('Checking for %r (Fortran compiler)' % compiler) try: conf.load(compiler) except conf.errors.ConfigurationError as e: conf.env.revert() conf.end_msg(False) Logs.debug('compiler_fortran: %r', e) else: if conf.env.FC: conf.end_msg(conf.env.get_flat('FC')) conf.env.COMPILER_FORTRAN = compiler conf.env.commit() break conf.env.revert() conf.end_msg(False) else: conf.fatal('could not configure a Fortran compiler!') def options(opt): """ This is how to provide compiler preferences on the command-line:: $ waf configure --check-fortran-compiler=ifort """ test_for_compiler = default_compilers() opt.load_special_tools('fc_*.py') fortran_compiler_opts = opt.add_option_group('Configuration options') fortran_compiler_opts.add_option('--check-fortran-compiler', default=None, help='list of Fortran compiler to try [%s]' % test_for_compiler, dest="check_fortran_compiler") for x in test_for_compiler.split(): opt.load('%s' % x) ldb-2.0.8/third_party/waf/waflib/Tools/cs.py0000660000000000000000000001437513573675414020700 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) """ C# support. A simple example:: def configure(conf): conf.load('cs') def build(bld): bld(features='cs', source='main.cs', gen='foo') Note that the configuration may compile C# snippets:: FRAG = ''' namespace Moo { public class Test { public static int Main(string[] args) { return 0; } } }''' def configure(conf): conf.check(features='cs', fragment=FRAG, compile_filename='test.cs', gen='test.exe', bintype='exe', csflags=['-pkg:gtk-sharp-2.0'], msg='Checking for Gtksharp support') """ from waflib import Utils, Task, Options, Errors from waflib.TaskGen import before_method, after_method, feature from waflib.Tools import ccroot from waflib.Configure import conf ccroot.USELIB_VARS['cs'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES']) ccroot.lib_patterns['csshlib'] = ['%s'] @feature('cs') @before_method('process_source') def apply_cs(self): """ Create a C# task bound to the attribute *cs_task*. There can be only one C# task by task generator. """ cs_nodes = [] no_nodes = [] for x in self.to_nodes(self.source): if x.name.endswith('.cs'): cs_nodes.append(x) else: no_nodes.append(x) self.source = no_nodes bintype = getattr(self, 'bintype', self.gen.endswith('.dll') and 'library' or 'exe') self.cs_task = tsk = self.create_task('mcs', cs_nodes, self.path.find_or_declare(self.gen)) tsk.env.CSTYPE = '/target:%s' % bintype tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath() self.env.append_value('CSFLAGS', '/platform:%s' % getattr(self, 'platform', 'anycpu')) inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}') if inst_to: # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644) self.install_task = self.add_install_files(install_to=inst_to, install_from=self.cs_task.outputs[:], chmod=mod) @feature('cs') @after_method('apply_cs') def use_cs(self): """ C# applications honor the **use** keyword:: def build(bld): bld(features='cs', source='My.cs', bintype='library', gen='my.dll', name='mylib') bld(features='cs', source='Hi.cs', includes='.', bintype='exe', gen='hi.exe', use='mylib', name='hi') """ names = self.to_list(getattr(self, 'use', [])) get = self.bld.get_tgen_by_name for x in names: try: y = get(x) except Errors.WafError: self.env.append_value('CSFLAGS', '/reference:%s' % x) continue y.post() tsk = getattr(y, 'cs_task', None) or getattr(y, 'link_task', None) if not tsk: self.bld.fatal('cs task has no link task for use %r' % self) self.cs_task.dep_nodes.extend(tsk.outputs) # dependency self.cs_task.set_run_after(tsk) # order (redundant, the order is inferred from the nodes inputs/outputs) self.env.append_value('CSFLAGS', '/reference:%s' % tsk.outputs[0].abspath()) @feature('cs') @after_method('apply_cs', 'use_cs') def debug_cs(self): """ The C# targets may create .mdb or .pdb files:: def build(bld): bld(features='cs', source='My.cs', bintype='library', gen='my.dll', csdebug='full') # csdebug is a value in (True, 'full', 'pdbonly') """ csdebug = getattr(self, 'csdebug', self.env.CSDEBUG) if not csdebug: return node = self.cs_task.outputs[0] if self.env.CS_NAME == 'mono': out = node.parent.find_or_declare(node.name + '.mdb') else: out = node.change_ext('.pdb') self.cs_task.outputs.append(out) if getattr(self, 'install_task', None): self.pdb_install_task = self.add_install_files( install_to=self.install_task.install_to, install_from=out) if csdebug == 'pdbonly': val = ['/debug+', '/debug:pdbonly'] elif csdebug == 'full': val = ['/debug+', '/debug:full'] else: val = ['/debug-'] self.env.append_value('CSFLAGS', val) @feature('cs') @after_method('debug_cs') def doc_cs(self): """ The C# targets may create .xml documentation files:: def build(bld): bld(features='cs', source='My.cs', bintype='library', gen='my.dll', csdoc=True) # csdoc is a boolean value """ csdoc = getattr(self, 'csdoc', self.env.CSDOC) if not csdoc: return node = self.cs_task.outputs[0] out = node.change_ext('.xml') self.cs_task.outputs.append(out) if getattr(self, 'install_task', None): self.doc_install_task = self.add_install_files( install_to=self.install_task.install_to, install_from=out) self.env.append_value('CSFLAGS', '/doc:%s' % out.abspath()) class mcs(Task.Task): """ Compile C# files """ color = 'YELLOW' run_str = '${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' def split_argfile(self, cmd): inline = [cmd[0]] infile = [] for x in cmd[1:]: # csc doesn't want /noconfig in @file if x.lower() == '/noconfig': inline.append(x) else: infile.append(self.quote_flag(x)) return (inline, infile) def configure(conf): """ Find a C# compiler, set the variable MCS for the compiler and CS_NAME (mono or csc) """ csc = getattr(Options.options, 'cscbinary', None) if csc: conf.env.MCS = csc conf.find_program(['csc', 'mcs', 'gmcs'], var='MCS') conf.env.ASS_ST = '/r:%s' conf.env.RES_ST = '/resource:%s' conf.env.CS_NAME = 'csc' if str(conf.env.MCS).lower().find('mcs') > -1: conf.env.CS_NAME = 'mono' def options(opt): """ Add a command-line option for the configuration:: $ waf configure --with-csc-binary=/foo/bar/mcs """ opt.add_option('--with-csc-binary', type='string', dest='cscbinary') class fake_csshlib(Task.Task): """ Task used for reading a foreign .net assembly and adding the dependency on it """ color = 'YELLOW' inst_to = None def runnable_status(self): return Task.SKIP_ME @conf def read_csshlib(self, name, paths=[]): """ Read a foreign .net assembly for the *use* system:: def build(bld): bld.read_csshlib('ManagedLibrary.dll', paths=[bld.env.mylibrarypath]) bld(features='cs', source='Hi.cs', bintype='exe', gen='hi.exe', use='ManagedLibrary.dll') :param name: Name of the library :type name: string :param paths: Folders in which the library may be found :type paths: list of string :return: A task generator having the feature *fake_lib* which will call :py:func:`waflib.Tools.ccroot.process_lib` :rtype: :py:class:`waflib.TaskGen.task_gen` """ return self(name=name, features='fake_lib', lib_paths=paths, lib_type='csshlib') ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py0000660000000000000000000000312613573675414021065 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) "Base for c++ programs and libraries" from waflib import TaskGen, Task from waflib.Tools import c_preproc from waflib.Tools.ccroot import link_task, stlink_task @TaskGen.extension('.cpp','.cc','.cxx','.C','.c++') def cxx_hook(self, node): "Binds c++ file extensions to create :py:class:`waflib.Tools.cxx.cxx` instances" return self.create_compiled_task('cxx', node) if not '.c' in TaskGen.task_gen.mappings: TaskGen.task_gen.mappings['.c'] = TaskGen.task_gen.mappings['.cpp'] class cxx(Task.Task): "Compiles C++ files into object files" run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' vars = ['CXXDEPS'] # unused variable to depend on, just in case ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] scan = c_preproc.scan class cxxprogram(link_task): "Links object files into c++ programs" run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' vars = ['LINKDEPS'] ext_out = ['.bin'] inst_to = '${BINDIR}' class cxxshlib(cxxprogram): "Links object files into c++ shared libraries" inst_to = '${LIBDIR}' class cxxstlib(stlink_task): "Links object files into c++ static libraries" pass # do not remove ldb-2.0.8/third_party/waf/waflib/Tools/d.py0000660000000000000000000000570613573675414020514 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2007 (dv) # Thomas Nagy, 2007-2018 (ita) from waflib import Utils, Task, Errors from waflib.TaskGen import taskgen_method, feature, extension from waflib.Tools import d_scan, d_config from waflib.Tools.ccroot import link_task, stlink_task class d(Task.Task): "Compile a d file into an object file" color = 'GREEN' run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}' scan = d_scan.scan class d_with_header(d): "Compile a d file and generate a header" run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}' class d_header(Task.Task): "Compile d headers" color = 'BLUE' run_str = '${D} ${D_HEADER} ${SRC}' class dprogram(link_task): "Link object files into a d program" run_str = '${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}' inst_to = '${BINDIR}' class dshlib(dprogram): "Link object files into a d shared library" inst_to = '${LIBDIR}' class dstlib(stlink_task): "Link object files into a d static library" pass # do not remove @extension('.d', '.di', '.D') def d_hook(self, node): """ Compile *D* files. To get .di files as well as .o files, set the following:: def build(bld): bld.program(source='foo.d', target='app', generate_headers=True) """ ext = Utils.destos_to_binfmt(self.env.DEST_OS) == 'pe' and 'obj' or 'o' out = '%s.%d.%s' % (node.name, self.idx, ext) def create_compiled_task(self, name, node): task = self.create_task(name, node, node.parent.find_or_declare(out)) try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] return task if getattr(self, 'generate_headers', None): tsk = create_compiled_task(self, 'd_with_header', node) tsk.outputs.append(node.change_ext(self.env.DHEADER_ext)) else: tsk = create_compiled_task(self, 'd', node) return tsk @taskgen_method def generate_header(self, filename): """ See feature request #104:: def build(bld): tg = bld.program(source='foo.d', target='app') tg.generate_header('blah.d') # is equivalent to: #tg = bld.program(source='foo.d', target='app', header_lst='blah.d') :param filename: header to create :type filename: string """ try: self.header_lst.append([filename, self.install_path]) except AttributeError: self.header_lst = [[filename, self.install_path]] @feature('d') def process_header(self): """ Process the attribute 'header_lst' to create the d header compilation tasks:: def build(bld): bld.program(source='foo.d', target='app', header_lst='blah.d') """ for i in getattr(self, 'header_lst', []): node = self.path.find_resource(i[0]) if not node: raise Errors.WafError('file %r not found on d obj' % i[0]) self.create_task('d_header', node, node.change_ext('.di')) ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py0000660000000000000000000000260713573675414022036 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2016-2018 (ita) from waflib import Utils from waflib.Configure import conf @conf def d_platform_flags(self): """ Sets the extensions dll/so for d programs and libraries """ v = self.env if not v.DEST_OS: v.DEST_OS = Utils.unversioned_sys_platform() binfmt = Utils.destos_to_binfmt(self.env.DEST_OS) if binfmt == 'pe': v.dprogram_PATTERN = '%s.exe' v.dshlib_PATTERN = 'lib%s.dll' v.dstlib_PATTERN = 'lib%s.a' elif binfmt == 'mac-o': v.dprogram_PATTERN = '%s' v.dshlib_PATTERN = 'lib%s.dylib' v.dstlib_PATTERN = 'lib%s.a' else: v.dprogram_PATTERN = '%s' v.dshlib_PATTERN = 'lib%s.so' v.dstlib_PATTERN = 'lib%s.a' DLIB = ''' version(D_Version2) { import std.stdio; int main() { writefln("phobos2"); return 0; } } else { version(Tango) { import tango.stdc.stdio; int main() { printf("tango"); return 0; } } else { import std.stdio; int main() { writefln("phobos1"); return 0; } } } ''' """Detection string for the D standard library""" @conf def check_dlibrary(self, execute=True): """ Detects the kind of standard library that comes with the compiler, and sets conf.env.DLIBRARY to tango, phobos1 or phobos2 """ ret = self.check_cc(features='d dprogram', fragment=DLIB, compile_filename='test.d', execute=execute, define_ret=True) if execute: self.env.DLIBRARY = ret.strip() ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py0000660000000000000000000001170013573675414021507 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2016-2018 (ita) """ Provide a scanner for finding dependencies on d files """ import re from waflib import Utils def filter_comments(filename): """ :param filename: d file name :type filename: string :rtype: list :return: a list of characters """ txt = Utils.readf(filename) i = 0 buf = [] max = len(txt) begin = 0 while i < max: c = txt[i] if c == '"' or c == "'": # skip a string or character literal buf.append(txt[begin:i]) delim = c i += 1 while i < max: c = txt[i] if c == delim: break elif c == '\\': # skip the character following backslash i += 1 i += 1 i += 1 begin = i elif c == '/': # try to replace a comment with whitespace buf.append(txt[begin:i]) i += 1 if i == max: break c = txt[i] if c == '+': # eat nesting /+ +/ comment i += 1 nesting = 1 c = None while i < max: prev = c c = txt[i] if prev == '/' and c == '+': nesting += 1 c = None elif prev == '+' and c == '/': nesting -= 1 if nesting == 0: break c = None i += 1 elif c == '*': # eat /* */ comment i += 1 c = None while i < max: prev = c c = txt[i] if prev == '*' and c == '/': break i += 1 elif c == '/': # eat // comment i += 1 while i < max and txt[i] != '\n': i += 1 else: # no comment begin = i - 1 continue i += 1 begin = i buf.append(' ') else: i += 1 buf.append(txt[begin:]) return buf class d_parser(object): """ Parser for d files """ def __init__(self, env, incpaths): #self.code = '' #self.module = '' #self.imports = [] self.allnames = [] self.re_module = re.compile(r"module\s+([^;]+)") self.re_import = re.compile(r"import\s+([^;]+)") self.re_import_bindings = re.compile("([^:]+):(.*)") self.re_import_alias = re.compile("[^=]+=(.+)") self.env = env self.nodes = [] self.names = [] self.incpaths = incpaths def tryfind(self, filename): """ Search file a file matching an module/import directive :param filename: file to read :type filename: string """ found = 0 for n in self.incpaths: found = n.find_resource(filename.replace('.', '/') + '.d') if found: self.nodes.append(found) self.waiting.append(found) break if not found: if not filename in self.names: self.names.append(filename) def get_strings(self, code): """ :param code: d code to parse :type code: string :return: the modules that the code uses :rtype: a list of match objects """ #self.imports = [] self.module = '' lst = [] # get the module name (if present) mod_name = self.re_module.search(code) if mod_name: self.module = re.sub(r'\s+', '', mod_name.group(1)) # strip all whitespaces # go through the code, have a look at all import occurrences # first, lets look at anything beginning with "import" and ending with ";" import_iterator = self.re_import.finditer(code) if import_iterator: for import_match in import_iterator: import_match_str = re.sub(r'\s+', '', import_match.group(1)) # strip all whitespaces # does this end with an import bindings declaration? # (import bindings always terminate the list of imports) bindings_match = self.re_import_bindings.match(import_match_str) if bindings_match: import_match_str = bindings_match.group(1) # if so, extract the part before the ":" (since the module declaration(s) is/are located there) # split the matching string into a bunch of strings, separated by a comma matches = import_match_str.split(',') for match in matches: alias_match = self.re_import_alias.match(match) if alias_match: # is this an alias declaration? (alias = module name) if so, extract the module name match = alias_match.group(1) lst.append(match) return lst def start(self, node): """ The parsing starts here :param node: input file :type node: :py:class:`waflib.Node.Node` """ self.waiting = [node] # while the stack is not empty, add the dependencies while self.waiting: nd = self.waiting.pop(0) self.iter(nd) def iter(self, node): """ Find all the modules that a file depends on, uses :py:meth:`waflib.Tools.d_scan.d_parser.tryfind` to process dependent files :param node: input file :type node: :py:class:`waflib.Node.Node` """ path = node.abspath() # obtain the absolute path code = "".join(filter_comments(path)) # read the file and filter the comments names = self.get_strings(code) # obtain the import strings for x in names: # optimization if x in self.allnames: continue self.allnames.append(x) # for each name, see if it is like a node or not self.tryfind(x) def scan(self): "look for .d/.di used by a d file" env = self.env gruik = d_parser(env, self.generator.includes_nodes) node = self.inputs[0] gruik.start(node) nodes = gruik.nodes names = gruik.names return (nodes, names) ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py0000660000000000000000000000401613573675414021217 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Ali Sabil, 2007 """ Compiles dbus files with **dbus-binding-tool** Typical usage:: def options(opt): opt.load('compiler_c dbus') def configure(conf): conf.load('compiler_c dbus') def build(bld): tg = bld.program( includes = '.', source = bld.path.ant_glob('*.c'), target = 'gnome-hello') tg.add_dbus_file('test.xml', 'test_prefix', 'glib-server') """ from waflib import Task, Errors from waflib.TaskGen import taskgen_method, before_method @taskgen_method def add_dbus_file(self, filename, prefix, mode): """ Adds a dbus file to the list of dbus files to process. Store them in the attribute *dbus_lst*. :param filename: xml file to compile :type filename: string :param prefix: dbus binding tool prefix (--prefix=prefix) :type prefix: string :param mode: dbus binding tool mode (--mode=mode) :type mode: string """ if not hasattr(self, 'dbus_lst'): self.dbus_lst = [] if not 'process_dbus' in self.meths: self.meths.append('process_dbus') self.dbus_lst.append([filename, prefix, mode]) @before_method('process_source') def process_dbus(self): """ Processes the dbus files stored in the attribute *dbus_lst* to create :py:class:`waflib.Tools.dbus.dbus_binding_tool` instances. """ for filename, prefix, mode in getattr(self, 'dbus_lst', []): node = self.path.find_resource(filename) if not node: raise Errors.WafError('file not found ' + filename) tsk = self.create_task('dbus_binding_tool', node, node.change_ext('.h')) tsk.env.DBUS_BINDING_TOOL_PREFIX = prefix tsk.env.DBUS_BINDING_TOOL_MODE = mode class dbus_binding_tool(Task.Task): """ Compiles a dbus file """ color = 'BLUE' ext_out = ['.h'] run_str = '${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}' shell = True # temporary workaround for #795 def configure(conf): """ Detects the program dbus-binding-tool and sets ``conf.env.DBUS_BINDING_TOOL`` """ conf.find_program('dbus-binding-tool', var='DBUS_BINDING_TOOL') ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py0000660000000000000000000000353013573675414021026 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2007 (dv) # Thomas Nagy, 2008-2018 (ita) import sys from waflib.Tools import ar, d from waflib.Configure import conf @conf def find_dmd(conf): """ Finds the program *dmd*, *dmd2*, or *ldc* and set the variable *D* """ conf.find_program(['dmd', 'dmd2', 'ldc'], var='D') # make sure that we're dealing with dmd1, dmd2, or ldc(1) out = conf.cmd_and_log(conf.env.D + ['--help']) if out.find("D Compiler v") == -1: out = conf.cmd_and_log(conf.env.D + ['-version']) if out.find("based on DMD v1.") == -1: conf.fatal("detected compiler is not dmd/ldc") @conf def common_flags_ldc(conf): """ Sets the D flags required by *ldc* """ v = conf.env v.DFLAGS = ['-d-version=Posix'] v.LINKFLAGS = [] v.DFLAGS_dshlib = ['-relocation-model=pic'] @conf def common_flags_dmd(conf): """ Set the flags required by *dmd* or *dmd2* """ v = conf.env v.D_SRC_F = ['-c'] v.D_TGT_F = '-of%s' v.D_LINKER = v.D v.DLNK_SRC_F = '' v.DLNK_TGT_F = '-of%s' v.DINC_ST = '-I%s' v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' v.DSTLIB_ST = v.DSHLIB_ST = '-L-l%s' v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L-L%s' v.LINKFLAGS_dprogram= ['-quiet'] v.DFLAGS_dshlib = ['-fPIC'] v.LINKFLAGS_dshlib = ['-L-shared'] v.DHEADER_ext = '.di' v.DFLAGS_d_with_header = ['-H', '-Hf'] v.D_HDR_F = '%s' def configure(conf): """ Configuration for *dmd*, *dmd2*, and *ldc* """ conf.find_dmd() if sys.platform == 'win32': out = conf.cmd_and_log(conf.env.D + ['--help']) if out.find('D Compiler v2.') > -1: conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead') conf.load('ar') conf.load('d') conf.common_flags_dmd() conf.d_platform_flags() if str(conf.env.D).find('ldc') > -1: conf.common_flags_ldc() ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py0000660000000000000000000001722213573675414022053 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 (ita) """ Common mistakes highlighting. There is a performance impact, so this tool is only loaded when running ``waf -v`` """ typos = { 'feature':'features', 'sources':'source', 'targets':'target', 'include':'includes', 'export_include':'export_includes', 'define':'defines', 'importpath':'includes', 'installpath':'install_path', 'iscopy':'is_copy', 'uses':'use', } meths_typos = ['__call__', 'program', 'shlib', 'stlib', 'objects'] import sys from waflib import Logs, Build, Node, Task, TaskGen, ConfigSet, Errors, Utils from waflib.Tools import ccroot def check_same_targets(self): mp = Utils.defaultdict(list) uids = {} def check_task(tsk): if not isinstance(tsk, Task.Task): return if hasattr(tsk, 'no_errcheck_out'): return for node in tsk.outputs: mp[node].append(tsk) try: uids[tsk.uid()].append(tsk) except KeyError: uids[tsk.uid()] = [tsk] for g in self.groups: for tg in g: try: for tsk in tg.tasks: check_task(tsk) except AttributeError: # raised if not a task generator, which should be uncommon check_task(tg) dupe = False for (k, v) in mp.items(): if len(v) > 1: dupe = True msg = '* Node %r is created more than once%s. The task generators are:' % (k, Logs.verbose == 1 and " (full message on 'waf -v -v')" or "") Logs.error(msg) for x in v: if Logs.verbose > 1: Logs.error(' %d. %r', 1 + v.index(x), x.generator) else: Logs.error(' %d. %r in %r', 1 + v.index(x), x.generator.name, getattr(x.generator, 'path', None)) Logs.error('If you think that this is an error, set no_errcheck_out on the task instance') if not dupe: for (k, v) in uids.items(): if len(v) > 1: Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid') tg_details = tsk.generator.name if Logs.verbose > 2: tg_details = tsk.generator for tsk in v: Logs.error(' - object %r (%r) defined in %r', tsk.__class__.__name__, tsk, tg_details) def check_invalid_constraints(self): feat = set() for x in list(TaskGen.feats.values()): feat.union(set(x)) for (x, y) in TaskGen.task_gen.prec.items(): feat.add(x) feat.union(set(y)) ext = set() for x in TaskGen.task_gen.mappings.values(): ext.add(x.__name__) invalid = ext & feat if invalid: Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method', list(invalid)) # the build scripts have been read, so we can check for invalid after/before attributes on task classes for cls in list(Task.classes.values()): if sys.hexversion > 0x3000000 and issubclass(cls, Task.Task) and isinstance(cls.hcode, str): raise Errors.WafError('Class %r has hcode value %r of type , expecting (use Utils.h_cmd() ?)' % (cls, cls.hcode)) for x in ('before', 'after'): for y in Utils.to_list(getattr(cls, x, [])): if not Task.classes.get(y): Logs.error('Erroneous order constraint %r=%r on task class %r', x, y, cls.__name__) if getattr(cls, 'rule', None): Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")', cls.__name__) def replace(m): """ Replaces existing BuildContext methods to verify parameter names, for example ``bld(source=)`` has no ending *s* """ oldcall = getattr(Build.BuildContext, m) def call(self, *k, **kw): ret = oldcall(self, *k, **kw) for x in typos: if x in kw: if x == 'iscopy' and 'subst' in getattr(self, 'features', ''): continue Logs.error('Fix the typo %r -> %r on %r', x, typos[x], ret) return ret setattr(Build.BuildContext, m, call) def enhance_lib(): """ Modifies existing classes and methods to enable error verification """ for m in meths_typos: replace(m) # catch '..' in ant_glob patterns def ant_glob(self, *k, **kw): if k: lst = Utils.to_list(k[0]) for pat in lst: sp = pat.split('/') if '..' in sp: Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'", k[0]) if '.' in sp: Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'", k[0]) return self.old_ant_glob(*k, **kw) Node.Node.old_ant_glob = Node.Node.ant_glob Node.Node.ant_glob = ant_glob # catch ant_glob on build folders def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True, quiet=False): if remove: try: if self.is_child_of(self.ctx.bldnode) and not quiet: quiet = True Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False', self) except AttributeError: pass return self.old_ant_iter(accept, maxdepth, pats, dir, src, remove, quiet) Node.Node.old_ant_iter = Node.Node.ant_iter Node.Node.ant_iter = ant_iter # catch conflicting ext_in/ext_out/before/after declarations old = Task.is_before def is_before(t1, t2): ret = old(t1, t2) if ret and old(t2, t1): Logs.error('Contradictory order constraints in classes %r %r', t1, t2) return ret Task.is_before = is_before # check for bld(feature='cshlib') where no 'c' is given - this can be either a mistake or on purpose # so we only issue a warning def check_err_features(self): lst = self.to_list(self.features) if 'shlib' in lst: Logs.error('feature shlib -> cshlib, dshlib or cxxshlib') for x in ('c', 'cxx', 'd', 'fc'): if not x in lst and lst and lst[0] in [x+y for y in ('program', 'shlib', 'stlib')]: Logs.error('%r features is probably missing %r', self, x) TaskGen.feature('*')(check_err_features) # check for erroneous order constraints def check_err_order(self): if not hasattr(self, 'rule') and not 'subst' in Utils.to_list(self.features): for x in ('before', 'after', 'ext_in', 'ext_out'): if hasattr(self, x): Logs.warn('Erroneous order constraint %r on non-rule based task generator %r', x, self) else: for x in ('before', 'after'): for y in self.to_list(getattr(self, x, [])): if not Task.classes.get(y): Logs.error('Erroneous order constraint %s=%r on %r (no such class)', x, y, self) TaskGen.feature('*')(check_err_order) # check for @extension used with @feature/@before_method/@after_method def check_compile(self): check_invalid_constraints(self) try: ret = self.orig_compile() finally: check_same_targets(self) return ret Build.BuildContext.orig_compile = Build.BuildContext.compile Build.BuildContext.compile = check_compile # check for invalid build groups #914 def use_rec(self, name, **kw): try: y = self.bld.get_tgen_by_name(name) except Errors.WafError: pass else: idx = self.bld.get_group_idx(self) odx = self.bld.get_group_idx(y) if odx > idx: msg = "Invalid 'use' across build groups:" if Logs.verbose > 1: msg += '\n target %r\n uses:\n %r' % (self, y) else: msg += " %r uses %r (try 'waf -v -v' for the full error)" % (self.name, name) raise Errors.WafError(msg) self.orig_use_rec(name, **kw) TaskGen.task_gen.orig_use_rec = TaskGen.task_gen.use_rec TaskGen.task_gen.use_rec = use_rec # check for env.append def _getattr(self, name, default=None): if name == 'append' or name == 'add': raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique') elif name == 'prepend': raise Errors.WafError('env.prepend does not exist: use env.prepend_value') if name in self.__slots__: return super(ConfigSet.ConfigSet, self).__getattr__(name, default) else: return self[name] ConfigSet.ConfigSet.__getattr__ = _getattr def options(opt): """ Error verification can be enabled by default (not just on ``waf -v``) by adding to the user script options """ enhance_lib() ldb-2.0.8/third_party/waf/waflib/Tools/fc.py0000660000000000000000000001512513573675414020655 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # DC 2008 # Thomas Nagy 2016-2018 (ita) """ Fortran support """ from waflib import Utils, Task, Errors from waflib.Tools import ccroot, fc_config, fc_scan from waflib.TaskGen import extension from waflib.Configure import conf ccroot.USELIB_VARS['fc'] = set(['FCFLAGS', 'DEFINES', 'INCLUDES', 'FCPPFLAGS']) ccroot.USELIB_VARS['fcprogram_test'] = ccroot.USELIB_VARS['fcprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) ccroot.USELIB_VARS['fcshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) ccroot.USELIB_VARS['fcstlib'] = set(['ARFLAGS', 'LINKDEPS']) @extension('.f','.F','.f90','.F90','.for','.FOR','.f95','.F95','.f03','.F03','.f08','.F08') def fc_hook(self, node): "Binds the Fortran file extensions create :py:class:`waflib.Tools.fc.fc` instances" return self.create_compiled_task('fc', node) @conf def modfile(conf, name): """ Turns a module name into the right module file name. Defaults to all lower case. """ if name.find(':') >= 0: # Depending on a submodule! separator = conf.env.FC_SUBMOD_SEPARATOR or '@' # Ancestors of the submodule will be prefixed to the # submodule name, separated by a colon. modpath = name.split(':') # Only the ancestor (actual) module and the submodule name # will be used for the filename. modname = modpath[0] + separator + modpath[-1] suffix = conf.env.FC_SUBMOD_SUFFIX or '.smod' else: modname = name suffix = '.mod' return {'lower' :modname.lower() + suffix.lower(), 'lower.MOD' :modname.lower() + suffix.upper(), 'UPPER.mod' :modname.upper() + suffix.lower(), 'UPPER' :modname.upper() + suffix.upper()}[conf.env.FC_MOD_CAPITALIZATION or 'lower'] def get_fortran_tasks(tsk): """ Obtains all fortran tasks from the same build group. Those tasks must not have the attribute 'nomod' or 'mod_fortran_done' :return: a list of :py:class:`waflib.Tools.fc.fc` instances """ bld = tsk.generator.bld tasks = bld.get_tasks_group(bld.get_group_idx(tsk.generator)) return [x for x in tasks if isinstance(x, fc) and not getattr(x, 'nomod', None) and not getattr(x, 'mod_fortran_done', None)] class fc(Task.Task): """ Fortran tasks can only run when all fortran tasks in a current task group are ready to be executed This may cause a deadlock if some fortran task is waiting for something that cannot happen (circular dependency) Should this ever happen, set the 'nomod=True' on those tasks instances to break the loop """ color = 'GREEN' run_str = '${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()} ${FCPPFLAGS}' vars = ["FORTRANMODPATHFLAG"] def scan(self): """Fortran dependency scanner""" tmp = fc_scan.fortran_parser(self.generator.includes_nodes) tmp.task = self tmp.start(self.inputs[0]) return (tmp.nodes, tmp.names) def runnable_status(self): """ Sets the mod file outputs and the dependencies on the mod files over all Fortran tasks executed by the main thread so there are no concurrency issues """ if getattr(self, 'mod_fortran_done', None): return super(fc, self).runnable_status() # now, if we reach this part it is because this fortran task is the first in the list bld = self.generator.bld # obtain the fortran tasks lst = get_fortran_tasks(self) # disable this method for other tasks for tsk in lst: tsk.mod_fortran_done = True # wait for all the .f tasks to be ready for execution # and ensure that the scanners are called at least once for tsk in lst: ret = tsk.runnable_status() if ret == Task.ASK_LATER: # we have to wait for one of the other fortran tasks to be ready # this may deadlock if there are dependencies between fortran tasks # but this should not happen (we are setting them here!) for x in lst: x.mod_fortran_done = None return Task.ASK_LATER ins = Utils.defaultdict(set) outs = Utils.defaultdict(set) # the .mod files to create for tsk in lst: key = tsk.uid() for x in bld.raw_deps[key]: if x.startswith('MOD@'): name = bld.modfile(x.replace('MOD@', '')) node = bld.srcnode.find_or_declare(name) tsk.set_outputs(node) outs[node].add(tsk) # the .mod files to use for tsk in lst: key = tsk.uid() for x in bld.raw_deps[key]: if x.startswith('USE@'): name = bld.modfile(x.replace('USE@', '')) node = bld.srcnode.find_resource(name) if node and node not in tsk.outputs: if not node in bld.node_deps[key]: bld.node_deps[key].append(node) ins[node].add(tsk) # if the intersection matches, set the order for k in ins.keys(): for a in ins[k]: a.run_after.update(outs[k]) for x in outs[k]: self.generator.bld.producer.revdeps[x].add(a) # the scanner cannot output nodes, so we have to set them # ourselves as task.dep_nodes (additional input nodes) tmp = [] for t in outs[k]: tmp.extend(t.outputs) a.dep_nodes.extend(tmp) a.dep_nodes.sort(key=lambda x: x.abspath()) # the task objects have changed: clear the signature cache for tsk in lst: try: delattr(tsk, 'cache_sig') except AttributeError: pass return super(fc, self).runnable_status() class fcprogram(ccroot.link_task): """Links Fortran programs""" color = 'YELLOW' run_str = '${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB} ${LDFLAGS}' inst_to = '${BINDIR}' class fcshlib(fcprogram): """Links Fortran libraries""" inst_to = '${LIBDIR}' class fcstlib(ccroot.stlink_task): """Links Fortran static libraries (uses ar by default)""" pass # do not remove the pass statement class fcprogram_test(fcprogram): """Custom link task to obtain compiler outputs for Fortran configuration tests""" def runnable_status(self): """This task is always executed""" ret = super(fcprogram_test, self).runnable_status() if ret == Task.SKIP_ME: ret = Task.RUN_ME return ret def exec_command(self, cmd, **kw): """Stores the compiler std our/err onto the build context, to bld.out + bld.err""" bld = self.generator.bld kw['shell'] = isinstance(cmd, str) kw['stdout'] = kw['stderr'] = Utils.subprocess.PIPE kw['cwd'] = self.get_cwd() bld.out = bld.err = '' bld.to_log('command: %s\n' % cmd) kw['output'] = 0 try: (bld.out, bld.err) = bld.cmd_and_log(cmd, **kw) except Errors.WafError: return -1 if bld.out: bld.to_log('out: %s\n' % bld.out) if bld.err: bld.to_log('err: %s\n' % bld.err) ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py0000660000000000000000000003324213573675414022202 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # DC 2008 # Thomas Nagy 2016-2018 (ita) """ Fortran configuration helpers """ import re, os, sys, shlex from waflib.Configure import conf from waflib.TaskGen import feature, before_method FC_FRAGMENT = ' program main\n end program main\n' FC_FRAGMENT2 = ' PROGRAM MAIN\n END\n' # what's the actual difference between these? @conf def fc_flags(conf): """ Defines common fortran configuration flags and file extensions """ v = conf.env v.FC_SRC_F = [] v.FC_TGT_F = ['-c', '-o'] v.FCINCPATH_ST = '-I%s' v.FCDEFINES_ST = '-D%s' if not v.LINK_FC: v.LINK_FC = v.FC v.FCLNK_SRC_F = [] v.FCLNK_TGT_F = ['-o'] v.FCFLAGS_fcshlib = ['-fpic'] v.LINKFLAGS_fcshlib = ['-shared'] v.fcshlib_PATTERN = 'lib%s.so' v.fcstlib_PATTERN = 'lib%s.a' v.FCLIB_ST = '-l%s' v.FCLIBPATH_ST = '-L%s' v.FCSTLIB_ST = '-l%s' v.FCSTLIBPATH_ST = '-L%s' v.FCSTLIB_MARKER = '-Wl,-Bstatic' v.FCSHLIB_MARKER = '-Wl,-Bdynamic' v.SONAME_ST = '-Wl,-h,%s' @conf def fc_add_flags(conf): """ Adds FCFLAGS / LDFLAGS / LINKFLAGS from os.environ to conf.env """ conf.add_os_flags('FCPPFLAGS', dup=False) conf.add_os_flags('FCFLAGS', dup=False) conf.add_os_flags('LINKFLAGS', dup=False) conf.add_os_flags('LDFLAGS', dup=False) @conf def check_fortran(self, *k, **kw): """ Compiles a Fortran program to ensure that the settings are correct """ self.check_cc( fragment = FC_FRAGMENT, compile_filename = 'test.f', features = 'fc fcprogram', msg = 'Compiling a simple fortran app') @conf def check_fc(self, *k, **kw): """ Same as :py:func:`waflib.Tools.c_config.check` but defaults to the *Fortran* programming language (this overrides the C defaults in :py:func:`waflib.Tools.c_config.validate_c`) """ kw['compiler'] = 'fc' if not 'compile_mode' in kw: kw['compile_mode'] = 'fc' if not 'type' in kw: kw['type'] = 'fcprogram' if not 'compile_filename' in kw: kw['compile_filename'] = 'test.f90' if not 'code' in kw: kw['code'] = FC_FRAGMENT return self.check(*k, **kw) # ------------------------------------------------------------------------ # --- These are the default platform modifiers, refactored here for # convenience. gfortran and g95 have much overlap. # ------------------------------------------------------------------------ @conf def fortran_modifier_darwin(conf): """ Defines Fortran flags and extensions for OSX systems """ v = conf.env v.FCFLAGS_fcshlib = ['-fPIC'] v.LINKFLAGS_fcshlib = ['-dynamiclib'] v.fcshlib_PATTERN = 'lib%s.dylib' v.FRAMEWORKPATH_ST = '-F%s' v.FRAMEWORK_ST = ['-framework'] v.LINKFLAGS_fcstlib = [] v.FCSHLIB_MARKER = '' v.FCSTLIB_MARKER = '' v.SONAME_ST = '' @conf def fortran_modifier_win32(conf): """ Defines Fortran flags for Windows platforms """ v = conf.env v.fcprogram_PATTERN = v.fcprogram_test_PATTERN = '%s.exe' v.fcshlib_PATTERN = '%s.dll' v.implib_PATTERN = '%s.dll.a' v.IMPLIB_ST = '-Wl,--out-implib,%s' v.FCFLAGS_fcshlib = [] # Auto-import is enabled by default even without this option, # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages # that the linker emits otherwise. v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) @conf def fortran_modifier_cygwin(conf): """ Defines Fortran flags for use on cygwin """ fortran_modifier_win32(conf) v = conf.env v.fcshlib_PATTERN = 'cyg%s.dll' v.append_value('LINKFLAGS_fcshlib', ['-Wl,--enable-auto-image-base']) v.FCFLAGS_fcshlib = [] # ------------------------------------------------------------------------ @conf def check_fortran_dummy_main(self, *k, **kw): """ Determines if a main function is needed by compiling a code snippet with the C compiler and linking it with the Fortran compiler (useful on unix-like systems) """ if not self.env.CC: self.fatal('A c compiler is required for check_fortran_dummy_main') lst = ['MAIN__', '__MAIN', '_MAIN', 'MAIN_', 'MAIN'] lst.extend([m.lower() for m in lst]) lst.append('') self.start_msg('Detecting whether we need a dummy main') for main in lst: kw['fortran_main'] = main try: self.check_cc( fragment = 'int %s() { return 0; }\n' % (main or 'test'), features = 'c fcprogram', mandatory = True ) if not main: self.env.FC_MAIN = -1 self.end_msg('no') else: self.env.FC_MAIN = main self.end_msg('yes %s' % main) break except self.errors.ConfigurationError: pass else: self.end_msg('not found') self.fatal('could not detect whether fortran requires a dummy main, see the config.log') # ------------------------------------------------------------------------ GCC_DRIVER_LINE = re.compile('^Driving:') POSIX_STATIC_EXT = re.compile(r'\S+\.a') POSIX_LIB_FLAGS = re.compile(r'-l\S+') @conf def is_link_verbose(self, txt): """Returns True if 'useful' link options can be found in txt""" assert isinstance(txt, str) for line in txt.splitlines(): if not GCC_DRIVER_LINE.search(line): if POSIX_STATIC_EXT.search(line) or POSIX_LIB_FLAGS.search(line): return True return False @conf def check_fortran_verbose_flag(self, *k, **kw): """ Checks what kind of verbose (-v) flag works, then sets it to env.FC_VERBOSE_FLAG """ self.start_msg('fortran link verbose flag') for x in ('-v', '--verbose', '-verbose', '-V'): try: self.check_cc( features = 'fc fcprogram_test', fragment = FC_FRAGMENT2, compile_filename = 'test.f', linkflags = [x], mandatory=True) except self.errors.ConfigurationError: pass else: # output is on stderr or stdout (for xlf) if self.is_link_verbose(self.test_bld.err) or self.is_link_verbose(self.test_bld.out): self.end_msg(x) break else: self.end_msg('failure') self.fatal('Could not obtain the fortran link verbose flag (see config.log)') self.env.FC_VERBOSE_FLAG = x return x # ------------------------------------------------------------------------ # linkflags which match those are ignored LINKFLAGS_IGNORED = [r'-lang*', r'-lcrt[a-zA-Z0-9\.]*\.o', r'-lc$', r'-lSystem', r'-libmil', r'-LIST:*', r'-LNO:*'] if os.name == 'nt': LINKFLAGS_IGNORED.extend([r'-lfrt*', r'-luser32', r'-lkernel32', r'-ladvapi32', r'-lmsvcrt', r'-lshell32', r'-lmingw', r'-lmoldname']) else: LINKFLAGS_IGNORED.append(r'-lgcc*') RLINKFLAGS_IGNORED = [re.compile(f) for f in LINKFLAGS_IGNORED] def _match_ignore(line): """Returns True if the line should be ignored (Fortran verbose flag test)""" for i in RLINKFLAGS_IGNORED: if i.match(line): return True return False def parse_fortran_link(lines): """Given the output of verbose link of Fortran compiler, this returns a list of flags necessary for linking using the standard linker.""" final_flags = [] for line in lines: if not GCC_DRIVER_LINE.match(line): _parse_flink_line(line, final_flags) return final_flags SPACE_OPTS = re.compile('^-[LRuYz]$') NOSPACE_OPTS = re.compile('^-[RL]') def _parse_flink_token(lexer, token, tmp_flags): # Here we go (convention for wildcard is shell, not regex !) # 1 TODO: we first get some root .a libraries # 2 TODO: take everything starting by -bI:* # 3 Ignore the following flags: -lang* | -lcrt*.o | -lc | # -lgcc* | -lSystem | -libmil | -LANG:=* | -LIST:* | -LNO:*) # 4 take into account -lkernel32 # 5 For options of the kind -[[LRuYz]], as they take one argument # after, the actual option is the next token # 6 For -YP,*: take and replace by -Larg where arg is the old # argument # 7 For -[lLR]*: take # step 3 if _match_ignore(token): pass # step 4 elif token.startswith('-lkernel32') and sys.platform == 'cygwin': tmp_flags.append(token) # step 5 elif SPACE_OPTS.match(token): t = lexer.get_token() if t.startswith('P,'): t = t[2:] for opt in t.split(os.pathsep): tmp_flags.append('-L%s' % opt) # step 6 elif NOSPACE_OPTS.match(token): tmp_flags.append(token) # step 7 elif POSIX_LIB_FLAGS.match(token): tmp_flags.append(token) else: # ignore anything not explicitly taken into account pass t = lexer.get_token() return t def _parse_flink_line(line, final_flags): """private""" lexer = shlex.shlex(line, posix = True) lexer.whitespace_split = True t = lexer.get_token() tmp_flags = [] while t: t = _parse_flink_token(lexer, t, tmp_flags) final_flags.extend(tmp_flags) return final_flags @conf def check_fortran_clib(self, autoadd=True, *k, **kw): """ Obtains the flags for linking with the C library if this check works, add uselib='CLIB' to your task generators """ if not self.env.FC_VERBOSE_FLAG: self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?') self.start_msg('Getting fortran runtime link flags') try: self.check_cc( fragment = FC_FRAGMENT2, compile_filename = 'test.f', features = 'fc fcprogram_test', linkflags = [self.env.FC_VERBOSE_FLAG] ) except Exception: self.end_msg(False) if kw.get('mandatory', True): conf.fatal('Could not find the c library flags') else: out = self.test_bld.err flags = parse_fortran_link(out.splitlines()) self.end_msg('ok (%s)' % ' '.join(flags)) self.env.LINKFLAGS_CLIB = flags return flags return [] def getoutput(conf, cmd, stdin=False): """ Obtains Fortran command outputs """ from waflib import Errors if conf.env.env: env = conf.env.env else: env = dict(os.environ) env['LANG'] = 'C' input = stdin and '\n'.encode() or None try: out, err = conf.cmd_and_log(cmd, env=env, output=0, input=input) except Errors.WafError as e: # An WafError might indicate an error code during the command # execution, in this case we still obtain the stderr and stdout, # which we can use to find the version string. if not (hasattr(e, 'stderr') and hasattr(e, 'stdout')): raise e else: # Ignore the return code and return the original # stdout and stderr. out = e.stdout err = e.stderr except Exception: conf.fatal('could not determine the compiler version %r' % cmd) return (out, err) # ------------------------------------------------------------------------ ROUTINES_CODE = """\ subroutine foobar() return end subroutine foo_bar() return end """ MAIN_CODE = """ void %(dummy_func_nounder)s(void); void %(dummy_func_under)s(void); int %(main_func_name)s() { %(dummy_func_nounder)s(); %(dummy_func_under)s(); return 0; } """ @feature('link_main_routines_func') @before_method('process_source') def link_main_routines_tg_method(self): """ The configuration test declares a unique task generator, so we create other task generators from there for fortran link tests """ def write_test_file(task): task.outputs[0].write(task.generator.code) bld = self.bld bld(rule=write_test_file, target='main.c', code=MAIN_CODE % self.__dict__) bld(rule=write_test_file, target='test.f', code=ROUTINES_CODE) bld(features='fc fcstlib', source='test.f', target='test') bld(features='c fcprogram', source='main.c', target='app', use='test') def mangling_schemes(): """ Generate triplets for use with mangle_name (used in check_fortran_mangling) the order is tuned for gfortan """ for u in ('_', ''): for du in ('', '_'): for c in ("lower", "upper"): yield (u, du, c) def mangle_name(u, du, c, name): """Mangle a name from a triplet (used in check_fortran_mangling)""" return getattr(name, c)() + u + (name.find('_') != -1 and du or '') @conf def check_fortran_mangling(self, *k, **kw): """ Detect the mangling scheme, sets FORTRAN_MANGLING to the triplet found This test will compile a fortran static library, then link a c app against it """ if not self.env.CC: self.fatal('A c compiler is required for link_main_routines') if not self.env.FC: self.fatal('A fortran compiler is required for link_main_routines') if not self.env.FC_MAIN: self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)') self.start_msg('Getting fortran mangling scheme') for (u, du, c) in mangling_schemes(): try: self.check_cc( compile_filename = [], features = 'link_main_routines_func', msg = 'nomsg', errmsg = 'nomsg', dummy_func_nounder = mangle_name(u, du, c, 'foobar'), dummy_func_under = mangle_name(u, du, c, 'foo_bar'), main_func_name = self.env.FC_MAIN ) except self.errors.ConfigurationError: pass else: self.end_msg("ok ('%s', '%s', '%s-case')" % (u, du, c)) self.env.FORTRAN_MANGLING = (u, du, c) break else: self.end_msg(False) self.fatal('mangler not found') return (u, du, c) @feature('pyext') @before_method('propagate_uselib_vars', 'apply_link') def set_lib_pat(self): """Sets the Fortran flags for linking with Python""" self.env.fcshlib_PATTERN = self.env.pyext_PATTERN @conf def detect_openmp(self): """ Detects openmp flags and sets the OPENMP ``FCFLAGS``/``LINKFLAGS`` """ for x in ('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'): try: self.check_fc( msg = 'Checking for OpenMP flag %s' % x, fragment = 'program main\n call omp_get_num_threads()\nend program main', fcflags = x, linkflags = x, uselib_store = 'OPENMP' ) except self.errors.ConfigurationError: pass else: break else: self.fatal('Could not find OpenMP') @conf def check_gfortran_o_space(self): if self.env.FC_NAME != 'GFORTRAN' or int(self.env.FC_VERSION[0]) > 4: # This is for old compilers and only for gfortran. # No idea how other implementations handle this. Be safe and bail out. return self.env.stash() self.env.FCLNK_TGT_F = ['-o', ''] try: self.check_fc(msg='Checking if the -o link must be split from arguments', fragment=FC_FRAGMENT, features='fc fcshlib') except self.errors.ConfigurationError: self.env.revert() else: self.env.commit() ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py0000660000000000000000000000602113573675414021654 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # DC 2008 # Thomas Nagy 2016-2018 (ita) import re INC_REGEX = r"""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])""" USE_REGEX = r"""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)""" MOD_REGEX = r"""(?:^|;)\s*MODULE(?!\s+(?:PROCEDURE|SUBROUTINE|FUNCTION))\s+(\w+)""" SMD_REGEX = r"""(?:^|;)\s*SUBMODULE\s*\(([\w:]+)\)\s*(\w+)""" re_inc = re.compile(INC_REGEX, re.I) re_use = re.compile(USE_REGEX, re.I) re_mod = re.compile(MOD_REGEX, re.I) re_smd = re.compile(SMD_REGEX, re.I) class fortran_parser(object): """ This parser returns: * the nodes corresponding to the module names to produce * the nodes corresponding to the include files used * the module names used by the fortran files """ def __init__(self, incpaths): self.seen = [] """Files already parsed""" self.nodes = [] """List of :py:class:`waflib.Node.Node` representing the dependencies to return""" self.names = [] """List of module names to return""" self.incpaths = incpaths """List of :py:class:`waflib.Node.Node` representing the include paths""" def find_deps(self, node): """ Parses a Fortran file to obtain the dependencies used/provided :param node: fortran file to read :type node: :py:class:`waflib.Node.Node` :return: lists representing the includes, the modules used, and the modules created by a fortran file :rtype: tuple of list of strings """ txt = node.read() incs = [] uses = [] mods = [] for line in txt.splitlines(): # line by line regexp search? optimize? m = re_inc.search(line) if m: incs.append(m.group(1)) m = re_use.search(line) if m: uses.append(m.group(1)) m = re_mod.search(line) if m: mods.append(m.group(1)) m = re_smd.search(line) if m: uses.append(m.group(1)) mods.append('{0}:{1}'.format(m.group(1),m.group(2))) return (incs, uses, mods) def start(self, node): """ Start parsing. Use the stack ``self.waiting`` to hold nodes to iterate on :param node: fortran file :type node: :py:class:`waflib.Node.Node` """ self.waiting = [node] while self.waiting: nd = self.waiting.pop(0) self.iter(nd) def iter(self, node): """ Processes a single file during dependency parsing. Extracts files used modules used and modules provided. """ incs, uses, mods = self.find_deps(node) for x in incs: if x in self.seen: continue self.seen.append(x) self.tryfind_header(x) for x in uses: name = "USE@%s" % x if not name in self.names: self.names.append(name) for x in mods: name = "MOD@%s" % x if not name in self.names: self.names.append(name) def tryfind_header(self, filename): """ Adds an include file to the list of nodes to process :param filename: file name :type filename: string """ found = None for n in self.incpaths: found = n.find_resource(filename) if found: self.nodes.append(found) self.waiting.append(found) break if not found: if not filename in self.names: self.names.append(filename) ldb-2.0.8/third_party/waf/waflib/Tools/flex.py0000660000000000000000000000302113573675414021213 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # John O'Meara, 2006 # Thomas Nagy, 2006-2018 (ita) """ The **flex** program is a code generator which creates C or C++ files. The generated files are compiled into object files. """ import os, re from waflib import Task, TaskGen from waflib.Tools import ccroot def decide_ext(self, node): if 'cxx' in self.features: return ['.lex.cc'] return ['.lex.c'] def flexfun(tsk): env = tsk.env bld = tsk.generator.bld wd = bld.variant_dir def to_list(xx): if isinstance(xx, str): return [xx] return xx tsk.last_cmd = lst = [] lst.extend(to_list(env.FLEX)) lst.extend(to_list(env.FLEXFLAGS)) inputs = [a.path_from(tsk.get_cwd()) for a in tsk.inputs] if env.FLEX_MSYS: inputs = [x.replace(os.sep, '/') for x in inputs] lst.extend(inputs) lst = [x for x in lst if x] txt = bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0) tsk.outputs[0].write(txt.replace('\r\n', '\n').replace('\r', '\n')) # issue #1207 TaskGen.declare_chain( name = 'flex', rule = flexfun, # issue #854 ext_in = '.l', decider = decide_ext, ) # To support the following: # bld(features='c', flexflags='-P/foo') Task.classes['flex'].vars = ['FLEXFLAGS', 'FLEX'] ccroot.USELIB_VARS['c'].add('FLEXFLAGS') ccroot.USELIB_VARS['cxx'].add('FLEXFLAGS') def configure(conf): """ Detect the *flex* program """ conf.find_program('flex', var='FLEX') conf.env.FLEXFLAGS = ['-t'] if re.search (r"\\msys\\[0-9.]+\\bin\\flex.exe$", conf.env.FLEX[0]): # this is the flex shipped with MSYS conf.env.FLEX_MSYS = True ldb-2.0.8/third_party/waf/waflib/Tools/g95.py0000660000000000000000000000276213573675414020674 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # KWS 2010 # Thomas Nagy 2016-2018 (ita) import re from waflib import Utils from waflib.Tools import fc, fc_config, fc_scan, ar from waflib.Configure import conf @conf def find_g95(conf): fc = conf.find_program('g95', var='FC') conf.get_g95_version(fc) conf.env.FC_NAME = 'G95' @conf def g95_flags(conf): v = conf.env v.FCFLAGS_fcshlib = ['-fPIC'] v.FORTRANMODFLAG = ['-fmod=', ''] # template for module path v.FCFLAGS_DEBUG = ['-Werror'] # why not @conf def g95_modifier_win32(conf): fc_config.fortran_modifier_win32(conf) @conf def g95_modifier_cygwin(conf): fc_config.fortran_modifier_cygwin(conf) @conf def g95_modifier_darwin(conf): fc_config.fortran_modifier_darwin(conf) @conf def g95_modifier_platform(conf): dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() g95_modifier_func = getattr(conf, 'g95_modifier_' + dest_os, None) if g95_modifier_func: g95_modifier_func() @conf def get_g95_version(conf, fc): """get the compiler version""" version_re = re.compile(r"g95\s*(?P\d*)\.(?P\d*)").search cmd = fc + ['--version'] out, err = fc_config.getoutput(conf, cmd, stdin=False) if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('cannot determine g95 version') k = match.groupdict() conf.env.FC_VERSION = (k['major'], k['minor']) def configure(conf): conf.find_g95() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.g95_flags() conf.g95_modifier_platform() ldb-2.0.8/third_party/waf/waflib/Tools/gas.py0000660000000000000000000000070013573675414021030 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2008-2018 (ita) "Detect as/gas/gcc for compiling assembly files" import waflib.Tools.asm # - leave this from waflib.Tools import ar def configure(conf): """ Find the programs gas/as/gcc and set the variable *AS* """ conf.find_program(['gas', 'gcc'], var='AS') conf.env.AS_TGT_F = ['-c', '-o'] conf.env.ASLNK_TGT_F = ['-o'] conf.find_ar() conf.load('asm') conf.env.ASM_NAME = 'gas' ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py0000660000000000000000000000770113573675414021022 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 """ gcc/llvm detection. """ from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_gcc(conf): """ Find the program gcc, and if present, try to detect its version number """ cc = conf.find_program(['gcc', 'cc'], var='CC') conf.get_cc_version(cc, gcc=True) conf.env.CC_NAME = 'gcc' @conf def gcc_common_flags(conf): """ Common flags for gcc on nearly all platforms """ v = conf.env v.CC_SRC_F = [] v.CC_TGT_F = ['-c', '-o'] if not v.LINK_CC: v.LINK_CC = v.CC v.CCLNK_SRC_F = [] v.CCLNK_TGT_F = ['-o'] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.RPATH_ST = '-Wl,-rpath,%s' v.SONAME_ST = '-Wl,-h,%s' v.SHLIB_MARKER = '-Wl,-Bdynamic' v.STLIB_MARKER = '-Wl,-Bstatic' v.cprogram_PATTERN = '%s' v.CFLAGS_cshlib = ['-fPIC'] v.LINKFLAGS_cshlib = ['-shared'] v.cshlib_PATTERN = 'lib%s.so' v.LINKFLAGS_cstlib = ['-Wl,-Bstatic'] v.cstlib_PATTERN = 'lib%s.a' v.LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] v.CFLAGS_MACBUNDLE = ['-fPIC'] v.macbundle_PATTERN = '%s.bundle' @conf def gcc_modifier_win32(conf): """Configuration flags for executing gcc on Windows""" v = conf.env v.cprogram_PATTERN = '%s.exe' v.cshlib_PATTERN = '%s.dll' v.implib_PATTERN = '%s.dll.a' v.IMPLIB_ST = '-Wl,--out-implib,%s' v.CFLAGS_cshlib = [] # Auto-import is enabled by default even without this option, # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages # that the linker emits otherwise. v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) @conf def gcc_modifier_cygwin(conf): """Configuration flags for executing gcc on Cygwin""" gcc_modifier_win32(conf) v = conf.env v.cshlib_PATTERN = 'cyg%s.dll' v.append_value('LINKFLAGS_cshlib', ['-Wl,--enable-auto-image-base']) v.CFLAGS_cshlib = [] @conf def gcc_modifier_darwin(conf): """Configuration flags for executing gcc on MacOS""" v = conf.env v.CFLAGS_cshlib = ['-fPIC'] v.LINKFLAGS_cshlib = ['-dynamiclib'] v.cshlib_PATTERN = 'lib%s.dylib' v.FRAMEWORKPATH_ST = '-F%s' v.FRAMEWORK_ST = ['-framework'] v.ARCH_ST = ['-arch'] v.LINKFLAGS_cstlib = [] v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.SONAME_ST = [] @conf def gcc_modifier_aix(conf): """Configuration flags for executing gcc on AIX""" v = conf.env v.LINKFLAGS_cprogram = ['-Wl,-brtl'] v.LINKFLAGS_cshlib = ['-shared','-Wl,-brtl,-bexpfull'] v.SHLIB_MARKER = [] @conf def gcc_modifier_hpux(conf): v = conf.env v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.CFLAGS_cshlib = ['-fPIC','-DPIC'] v.cshlib_PATTERN = 'lib%s.sl' @conf def gcc_modifier_openbsd(conf): conf.env.SONAME_ST = [] @conf def gcc_modifier_osf1V(conf): v = conf.env v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.SONAME_ST = [] @conf def gcc_modifier_platform(conf): """Execute platform-specific functions based on *gcc_modifier_+NAME*""" # * set configurations specific for a platform. # * the destination platform is detected automatically by looking at the macros the compiler predefines, # and if it's not recognised, it fallbacks to sys.platform. gcc_modifier_func = getattr(conf, 'gcc_modifier_' + conf.env.DEST_OS, None) if gcc_modifier_func: gcc_modifier_func() def configure(conf): """ Configuration for gcc """ conf.find_gcc() conf.find_ar() conf.gcc_common_flags() conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() conf.check_gcc_o_space() ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py0000660000000000000000000000212313573675414021014 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2007 (dv) from waflib.Tools import ar, d from waflib.Configure import conf @conf def find_gdc(conf): """ Finds the program gdc and set the variable *D* """ conf.find_program('gdc', var='D') out = conf.cmd_and_log(conf.env.D + ['--version']) if out.find("gdc") == -1: conf.fatal("detected compiler is not gdc") @conf def common_flags_gdc(conf): """ Sets the flags required by *gdc* """ v = conf.env v.DFLAGS = [] v.D_SRC_F = ['-c'] v.D_TGT_F = '-o%s' v.D_LINKER = v.D v.DLNK_SRC_F = '' v.DLNK_TGT_F = '-o%s' v.DINC_ST = '-I%s' v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' v.DSTLIB_ST = v.DSHLIB_ST = '-l%s' v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L%s' v.LINKFLAGS_dshlib = ['-shared'] v.DHEADER_ext = '.di' v.DFLAGS_d_with_header = '-fintfc' v.D_HDR_F = '-fintfc-file=%s' def configure(conf): """ Configuration for gdc """ conf.find_gdc() conf.load('ar') conf.load('d') conf.common_flags_gdc() conf.d_platform_flags() ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py0000660000000000000000000000442213573675414022105 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # DC 2008 # Thomas Nagy 2016-2018 (ita) import re from waflib import Utils from waflib.Tools import fc, fc_config, fc_scan, ar from waflib.Configure import conf @conf def find_gfortran(conf): """Find the gfortran program (will look in the environment variable 'FC')""" fc = conf.find_program(['gfortran','g77'], var='FC') # (fallback to g77 for systems, where no gfortran is available) conf.get_gfortran_version(fc) conf.env.FC_NAME = 'GFORTRAN' @conf def gfortran_flags(conf): v = conf.env v.FCFLAGS_fcshlib = ['-fPIC'] v.FORTRANMODFLAG = ['-J', ''] # template for module path v.FCFLAGS_DEBUG = ['-Werror'] # why not @conf def gfortran_modifier_win32(conf): fc_config.fortran_modifier_win32(conf) @conf def gfortran_modifier_cygwin(conf): fc_config.fortran_modifier_cygwin(conf) @conf def gfortran_modifier_darwin(conf): fc_config.fortran_modifier_darwin(conf) @conf def gfortran_modifier_platform(conf): dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() gfortran_modifier_func = getattr(conf, 'gfortran_modifier_' + dest_os, None) if gfortran_modifier_func: gfortran_modifier_func() @conf def get_gfortran_version(conf, fc): """Get the compiler version""" # ensure this is actually gfortran, not an imposter. version_re = re.compile(r"GNU\s*Fortran", re.I).search cmd = fc + ['--version'] out, err = fc_config.getoutput(conf, cmd, stdin=False) if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not determine the compiler type') # --- now get more detailed info -- see c_config.get_cc_version cmd = fc + ['-dM', '-E', '-'] out, err = fc_config.getoutput(conf, cmd, stdin=True) if out.find('__GNUC__') < 0: conf.fatal('Could not determine the compiler type') k = {} out = out.splitlines() import shlex for line in out: lst = shlex.split(line) if len(lst)>2: key = lst[1] val = lst[2] k[key] = val def isD(var): return var in k def isT(var): return var in k and k[var] != '0' conf.env.FC_VERSION = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__']) def configure(conf): conf.find_gfortran() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.gfortran_flags() conf.gfortran_modifier_platform() conf.check_gfortran_o_space() ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py0000660000000000000000000003663313573675414021273 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) """ Support for GLib2 tools: * marshal * enums * gsettings * gresource """ import os import functools from waflib import Context, Task, Utils, Options, Errors, Logs from waflib.TaskGen import taskgen_method, before_method, feature, extension from waflib.Configure import conf ################## marshal files @taskgen_method def add_marshal_file(self, filename, prefix): """ Adds a file to the list of marshal files to process. Store them in the attribute *marshal_list*. :param filename: xml file to compile :type filename: string :param prefix: marshal prefix (--prefix=prefix) :type prefix: string """ if not hasattr(self, 'marshal_list'): self.marshal_list = [] self.meths.append('process_marshal') self.marshal_list.append((filename, prefix)) @before_method('process_source') def process_marshal(self): """ Processes the marshal files stored in the attribute *marshal_list* to create :py:class:`waflib.Tools.glib2.glib_genmarshal` instances. Adds the c file created to the list of source to process. """ for f, prefix in getattr(self, 'marshal_list', []): node = self.path.find_resource(f) if not node: raise Errors.WafError('file not found %r' % f) h_node = node.change_ext('.h') c_node = node.change_ext('.c') task = self.create_task('glib_genmarshal', node, [h_node, c_node]) task.env.GLIB_GENMARSHAL_PREFIX = prefix self.source = self.to_nodes(getattr(self, 'source', [])) self.source.append(c_node) class glib_genmarshal(Task.Task): vars = ['GLIB_GENMARSHAL_PREFIX', 'GLIB_GENMARSHAL'] color = 'BLUE' ext_out = ['.h'] def run(self): bld = self.generator.bld get = self.env.get_flat cmd1 = "%s %s --prefix=%s --header > %s" % ( get('GLIB_GENMARSHAL'), self.inputs[0].srcpath(), get('GLIB_GENMARSHAL_PREFIX'), self.outputs[0].abspath() ) ret = bld.exec_command(cmd1) if ret: return ret #print self.outputs[1].abspath() c = '''#include "%s"\n''' % self.outputs[0].name self.outputs[1].write(c) cmd2 = "%s %s --prefix=%s --body >> %s" % ( get('GLIB_GENMARSHAL'), self.inputs[0].srcpath(), get('GLIB_GENMARSHAL_PREFIX'), self.outputs[1].abspath() ) return bld.exec_command(cmd2) ########################## glib-mkenums @taskgen_method def add_enums_from_template(self, source='', target='', template='', comments=''): """ Adds a file to the list of enum files to process. Stores them in the attribute *enums_list*. :param source: enum file to process :type source: string :param target: target file :type target: string :param template: template file :type template: string :param comments: comments :type comments: string """ if not hasattr(self, 'enums_list'): self.enums_list = [] self.meths.append('process_enums') self.enums_list.append({'source': source, 'target': target, 'template': template, 'file-head': '', 'file-prod': '', 'file-tail': '', 'enum-prod': '', 'value-head': '', 'value-prod': '', 'value-tail': '', 'comments': comments}) @taskgen_method def add_enums(self, source='', target='', file_head='', file_prod='', file_tail='', enum_prod='', value_head='', value_prod='', value_tail='', comments=''): """ Adds a file to the list of enum files to process. Stores them in the attribute *enums_list*. :param source: enum file to process :type source: string :param target: target file :type target: string :param file_head: unused :param file_prod: unused :param file_tail: unused :param enum_prod: unused :param value_head: unused :param value_prod: unused :param value_tail: unused :param comments: comments :type comments: string """ if not hasattr(self, 'enums_list'): self.enums_list = [] self.meths.append('process_enums') self.enums_list.append({'source': source, 'template': '', 'target': target, 'file-head': file_head, 'file-prod': file_prod, 'file-tail': file_tail, 'enum-prod': enum_prod, 'value-head': value_head, 'value-prod': value_prod, 'value-tail': value_tail, 'comments': comments}) @before_method('process_source') def process_enums(self): """ Processes the enum files stored in the attribute *enum_list* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances. """ for enum in getattr(self, 'enums_list', []): task = self.create_task('glib_mkenums') env = task.env inputs = [] # process the source source_list = self.to_list(enum['source']) if not source_list: raise Errors.WafError('missing source ' + str(enum)) source_list = [self.path.find_resource(k) for k in source_list] inputs += source_list env.GLIB_MKENUMS_SOURCE = [k.abspath() for k in source_list] # find the target if not enum['target']: raise Errors.WafError('missing target ' + str(enum)) tgt_node = self.path.find_or_declare(enum['target']) if tgt_node.name.endswith('.c'): self.source.append(tgt_node) env.GLIB_MKENUMS_TARGET = tgt_node.abspath() options = [] if enum['template']: # template, if provided template_node = self.path.find_resource(enum['template']) options.append('--template %s' % (template_node.abspath())) inputs.append(template_node) params = {'file-head' : '--fhead', 'file-prod' : '--fprod', 'file-tail' : '--ftail', 'enum-prod' : '--eprod', 'value-head' : '--vhead', 'value-prod' : '--vprod', 'value-tail' : '--vtail', 'comments': '--comments'} for param, option in params.items(): if enum[param]: options.append('%s %r' % (option, enum[param])) env.GLIB_MKENUMS_OPTIONS = ' '.join(options) # update the task instance task.set_inputs(inputs) task.set_outputs(tgt_node) class glib_mkenums(Task.Task): """ Processes enum files """ run_str = '${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}' color = 'PINK' ext_out = ['.h'] ######################################### gsettings @taskgen_method def add_settings_schemas(self, filename_list): """ Adds settings files to process to *settings_schema_files* :param filename_list: files :type filename_list: list of string """ if not hasattr(self, 'settings_schema_files'): self.settings_schema_files = [] if not isinstance(filename_list, list): filename_list = [filename_list] self.settings_schema_files.extend(filename_list) @taskgen_method def add_settings_enums(self, namespace, filename_list): """ Called only once by task generator to set the enums namespace. :param namespace: namespace :type namespace: string :param filename_list: enum files to process :type filename_list: file list """ if hasattr(self, 'settings_enum_namespace'): raise Errors.WafError("Tried to add gsettings enums to %r more than once" % self.name) self.settings_enum_namespace = namespace if not isinstance(filename_list, list): filename_list = [filename_list] self.settings_enum_files = filename_list @feature('glib2') def process_settings(self): """ Processes the schema files in *settings_schema_files* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances. The same files are validated through :py:class:`waflib.Tools.glib2.glib_validate_schema` tasks. """ enums_tgt_node = [] install_files = [] settings_schema_files = getattr(self, 'settings_schema_files', []) if settings_schema_files and not self.env.GLIB_COMPILE_SCHEMAS: raise Errors.WafError ("Unable to process GSettings schemas - glib-compile-schemas was not found during configure") # 1. process gsettings_enum_files (generate .enums.xml) # if hasattr(self, 'settings_enum_files'): enums_task = self.create_task('glib_mkenums') source_list = self.settings_enum_files source_list = [self.path.find_resource(k) for k in source_list] enums_task.set_inputs(source_list) enums_task.env.GLIB_MKENUMS_SOURCE = [k.abspath() for k in source_list] target = self.settings_enum_namespace + '.enums.xml' tgt_node = self.path.find_or_declare(target) enums_task.set_outputs(tgt_node) enums_task.env.GLIB_MKENUMS_TARGET = tgt_node.abspath() enums_tgt_node = [tgt_node] install_files.append(tgt_node) options = '--comments "" --fhead "" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " " --vtail " " --ftail "" ' % (self.settings_enum_namespace) enums_task.env.GLIB_MKENUMS_OPTIONS = options # 2. process gsettings_schema_files (validate .gschema.xml files) # for schema in settings_schema_files: schema_task = self.create_task ('glib_validate_schema') schema_node = self.path.find_resource(schema) if not schema_node: raise Errors.WafError("Cannot find the schema file %r" % schema) install_files.append(schema_node) source_list = enums_tgt_node + [schema_node] schema_task.set_inputs (source_list) schema_task.env.GLIB_COMPILE_SCHEMAS_OPTIONS = [("--schema-file=" + k.abspath()) for k in source_list] target_node = schema_node.change_ext('.xml.valid') schema_task.set_outputs (target_node) schema_task.env.GLIB_VALIDATE_SCHEMA_OUTPUT = target_node.abspath() # 3. schemas install task def compile_schemas_callback(bld): if not bld.is_install: return compile_schemas = Utils.to_list(bld.env.GLIB_COMPILE_SCHEMAS) destdir = Options.options.destdir paths = bld._compile_schemas_registered if destdir: paths = (os.path.join(destdir, path.lstrip(os.sep)) for path in paths) for path in paths: Logs.pprint('YELLOW', 'Updating GSettings schema cache %r' % path) if self.bld.exec_command(compile_schemas + [path]): Logs.warn('Could not update GSettings schema cache %r' % path) if self.bld.is_install: schemadir = self.env.GSETTINGSSCHEMADIR if not schemadir: raise Errors.WafError ('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)') if install_files: self.add_install_files(install_to=schemadir, install_from=install_files) registered_schemas = getattr(self.bld, '_compile_schemas_registered', None) if not registered_schemas: registered_schemas = self.bld._compile_schemas_registered = set() self.bld.add_post_fun(compile_schemas_callback) registered_schemas.add(schemadir) class glib_validate_schema(Task.Task): """ Validates schema files """ run_str = 'rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}' color = 'PINK' ################## gresource @extension('.gresource.xml') def process_gresource_source(self, node): """ Creates tasks that turn ``.gresource.xml`` files to C code """ if not self.env.GLIB_COMPILE_RESOURCES: raise Errors.WafError ("Unable to process GResource file - glib-compile-resources was not found during configure") if 'gresource' in self.features: return h_node = node.change_ext('_xml.h') c_node = node.change_ext('_xml.c') self.create_task('glib_gresource_source', node, [h_node, c_node]) self.source.append(c_node) @feature('gresource') def process_gresource_bundle(self): """ Creates tasks to turn ``.gresource`` files from ``.gresource.xml`` files:: def build(bld): bld( features='gresource', source=['resources1.gresource.xml', 'resources2.gresource.xml'], install_path='${LIBDIR}/${PACKAGE}' ) :param source: XML files to process :type source: list of string :param install_path: installation path :type install_path: string """ for i in self.to_list(self.source): node = self.path.find_resource(i) task = self.create_task('glib_gresource_bundle', node, node.change_ext('')) inst_to = getattr(self, 'install_path', None) if inst_to: self.add_install_files(install_to=inst_to, install_from=task.outputs) class glib_gresource_base(Task.Task): """ Base class for gresource based tasks """ color = 'BLUE' base_cmd = '${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}' def scan(self): """ Scans gresource dependencies through ``glib-compile-resources --generate-dependencies command`` """ bld = self.generator.bld kw = {} kw['cwd'] = self.get_cwd() kw['quiet'] = Context.BOTH cmd = Utils.subst_vars('${GLIB_COMPILE_RESOURCES} --sourcedir=%s --sourcedir=%s --generate-dependencies %s' % ( self.inputs[0].parent.srcpath(), self.inputs[0].bld_dir(), self.inputs[0].bldpath() ), self.env) output = bld.cmd_and_log(cmd, **kw) nodes = [] names = [] for dep in output.splitlines(): if dep: node = bld.bldnode.find_node(dep) if node: nodes.append(node) else: names.append(dep) return (nodes, names) class glib_gresource_source(glib_gresource_base): """ Task to generate C source code (.h and .c files) from a gresource.xml file """ vars = ['GLIB_COMPILE_RESOURCES'] fun_h = Task.compile_fun_shell(glib_gresource_base.base_cmd + ' --target=${TGT[0].abspath()} --generate-header ${SRC}') fun_c = Task.compile_fun_shell(glib_gresource_base.base_cmd + ' --target=${TGT[1].abspath()} --generate-source ${SRC}') ext_out = ['.h'] def run(self): return self.fun_h[0](self) or self.fun_c[0](self) class glib_gresource_bundle(glib_gresource_base): """ Task to generate a .gresource binary file from a gresource.xml file """ run_str = glib_gresource_base.base_cmd + ' --target=${TGT} ${SRC}' shell = True # temporary workaround for #795 @conf def find_glib_genmarshal(conf): conf.find_program('glib-genmarshal', var='GLIB_GENMARSHAL') @conf def find_glib_mkenums(conf): if not conf.env.PERL: conf.find_program('perl', var='PERL') conf.find_program('glib-mkenums', interpreter='PERL', var='GLIB_MKENUMS') @conf def find_glib_compile_schemas(conf): # when cross-compiling, gsettings.m4 locates the program with the following: # pkg-config --variable glib_compile_schemas gio-2.0 conf.find_program('glib-compile-schemas', var='GLIB_COMPILE_SCHEMAS') def getstr(varname): return getattr(Options.options, varname, getattr(conf.env,varname, '')) gsettingsschemadir = getstr('GSETTINGSSCHEMADIR') if not gsettingsschemadir: datadir = getstr('DATADIR') if not datadir: prefix = conf.env.PREFIX datadir = os.path.join(prefix, 'share') gsettingsschemadir = os.path.join(datadir, 'glib-2.0', 'schemas') conf.env.GSETTINGSSCHEMADIR = gsettingsschemadir @conf def find_glib_compile_resources(conf): conf.find_program('glib-compile-resources', var='GLIB_COMPILE_RESOURCES') def configure(conf): """ Finds the following programs: * *glib-genmarshal* and set *GLIB_GENMARSHAL* * *glib-mkenums* and set *GLIB_MKENUMS* * *glib-compile-schemas* and set *GLIB_COMPILE_SCHEMAS* (not mandatory) * *glib-compile-resources* and set *GLIB_COMPILE_RESOURCES* (not mandatory) """ conf.find_glib_genmarshal() conf.find_glib_mkenums() conf.find_glib_compile_schemas(mandatory=False) conf.find_glib_compile_resources(mandatory=False) def options(opt): """ Adds the ``--gsettingsschemadir`` command-line option """ gr = opt.add_option_group('Installation directories') gr.add_option('--gsettingsschemadir', help='GSettings schema location [DATADIR/glib-2.0/schemas]', default='', dest='GSETTINGSSCHEMADIR') ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py0000660000000000000000000001207613573675414022101 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Ali Sabil, 2007 """ Sets various standard variables such as INCLUDEDIR. SBINDIR and others. To use this module just call:: opt.load('gnu_dirs') and:: conf.load('gnu_dirs') Add options for the standard GNU directories, this tool will add the options found in autotools, and will update the environment with the following installation variables: ============== ========================================= ======================= Variable Description Default Value ============== ========================================= ======================= PREFIX installation prefix /usr/local EXEC_PREFIX installation prefix for binaries PREFIX BINDIR user commands EXEC_PREFIX/bin SBINDIR system binaries EXEC_PREFIX/sbin LIBEXECDIR program-specific binaries EXEC_PREFIX/libexec SYSCONFDIR host-specific configuration PREFIX/etc SHAREDSTATEDIR architecture-independent variable data PREFIX/com LOCALSTATEDIR variable data PREFIX/var LIBDIR object code libraries EXEC_PREFIX/lib INCLUDEDIR header files PREFIX/include OLDINCLUDEDIR header files for non-GCC compilers /usr/include DATAROOTDIR architecture-independent data root PREFIX/share DATADIR architecture-independent data DATAROOTDIR INFODIR GNU "info" documentation DATAROOTDIR/info LOCALEDIR locale-dependent data DATAROOTDIR/locale MANDIR manual pages DATAROOTDIR/man DOCDIR documentation root DATAROOTDIR/doc/APPNAME HTMLDIR HTML documentation DOCDIR DVIDIR DVI documentation DOCDIR PDFDIR PDF documentation DOCDIR PSDIR PostScript documentation DOCDIR ============== ========================================= ======================= """ import os, re from waflib import Utils, Options, Context gnuopts = ''' bindir, user commands, ${EXEC_PREFIX}/bin sbindir, system binaries, ${EXEC_PREFIX}/sbin libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec sysconfdir, host-specific configuration, ${PREFIX}/etc sharedstatedir, architecture-independent variable data, ${PREFIX}/com localstatedir, variable data, ${PREFIX}/var libdir, object code libraries, ${EXEC_PREFIX}/lib%s includedir, header files, ${PREFIX}/include oldincludedir, header files for non-GCC compilers, /usr/include datarootdir, architecture-independent data root, ${PREFIX}/share datadir, architecture-independent data, ${DATAROOTDIR} infodir, GNU "info" documentation, ${DATAROOTDIR}/info localedir, locale-dependent data, ${DATAROOTDIR}/locale mandir, manual pages, ${DATAROOTDIR}/man docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE} htmldir, HTML documentation, ${DOCDIR} dvidir, DVI documentation, ${DOCDIR} pdfdir, PDF documentation, ${DOCDIR} psdir, PostScript documentation, ${DOCDIR} ''' % Utils.lib64() _options = [x.split(', ') for x in gnuopts.splitlines() if x] def configure(conf): """ Reads the command-line options to set lots of variables in *conf.env*. The variables BINDIR and LIBDIR will be overwritten. """ def get_param(varname, default): return getattr(Options.options, varname, '') or default env = conf.env env.LIBDIR = env.BINDIR = [] env.EXEC_PREFIX = get_param('EXEC_PREFIX', env.PREFIX) env.PACKAGE = getattr(Context.g_module, 'APPNAME', None) or env.PACKAGE complete = False iter = 0 while not complete and iter < len(_options) + 1: iter += 1 complete = True for name, help, default in _options: name = name.upper() if not env[name]: try: env[name] = Utils.subst_vars(get_param(name, default).replace('/', os.sep), env) except TypeError: complete = False if not complete: lst = [x for x, _, _ in _options if not env[x.upper()]] raise conf.errors.WafError('Variable substitution failure %r' % lst) def options(opt): """ Adds lots of command-line options, for example:: --exec-prefix: EXEC_PREFIX """ inst_dir = opt.add_option_group('Installation prefix', 'By default, "waf install" will put the files in\ "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\ than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"') for k in ('--prefix', '--destdir'): option = opt.parser.get_option(k) if option: opt.parser.remove_option(k) inst_dir.add_option(option) inst_dir.add_option('--exec-prefix', help = 'installation prefix for binaries [PREFIX]', default = '', dest = 'EXEC_PREFIX') dirs_options = opt.add_option_group('Installation directories') for name, help, default in _options: option_name = '--' + name str_default = default str_help = '%s [%s]' % (help, re.sub(r'\$\{([^}]+)\}', r'\1', str_default)) dirs_options.add_option(option_name, help=str_help, default='', dest=name.upper()) ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py0000660000000000000000000000774013573675414021077 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 """ g++/llvm detection. """ from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_gxx(conf): """ Finds the program g++, and if present, try to detect its version number """ cxx = conf.find_program(['g++', 'c++'], var='CXX') conf.get_cc_version(cxx, gcc=True) conf.env.CXX_NAME = 'gcc' @conf def gxx_common_flags(conf): """ Common flags for g++ on nearly all platforms """ v = conf.env v.CXX_SRC_F = [] v.CXX_TGT_F = ['-c', '-o'] if not v.LINK_CXX: v.LINK_CXX = v.CXX v.CXXLNK_SRC_F = [] v.CXXLNK_TGT_F = ['-o'] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.RPATH_ST = '-Wl,-rpath,%s' v.SONAME_ST = '-Wl,-h,%s' v.SHLIB_MARKER = '-Wl,-Bdynamic' v.STLIB_MARKER = '-Wl,-Bstatic' v.cxxprogram_PATTERN = '%s' v.CXXFLAGS_cxxshlib = ['-fPIC'] v.LINKFLAGS_cxxshlib = ['-shared'] v.cxxshlib_PATTERN = 'lib%s.so' v.LINKFLAGS_cxxstlib = ['-Wl,-Bstatic'] v.cxxstlib_PATTERN = 'lib%s.a' v.LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] v.CXXFLAGS_MACBUNDLE = ['-fPIC'] v.macbundle_PATTERN = '%s.bundle' @conf def gxx_modifier_win32(conf): """Configuration flags for executing gcc on Windows""" v = conf.env v.cxxprogram_PATTERN = '%s.exe' v.cxxshlib_PATTERN = '%s.dll' v.implib_PATTERN = '%s.dll.a' v.IMPLIB_ST = '-Wl,--out-implib,%s' v.CXXFLAGS_cxxshlib = [] # Auto-import is enabled by default even without this option, # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages # that the linker emits otherwise. v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) @conf def gxx_modifier_cygwin(conf): """Configuration flags for executing g++ on Cygwin""" gxx_modifier_win32(conf) v = conf.env v.cxxshlib_PATTERN = 'cyg%s.dll' v.append_value('LINKFLAGS_cxxshlib', ['-Wl,--enable-auto-image-base']) v.CXXFLAGS_cxxshlib = [] @conf def gxx_modifier_darwin(conf): """Configuration flags for executing g++ on MacOS""" v = conf.env v.CXXFLAGS_cxxshlib = ['-fPIC'] v.LINKFLAGS_cxxshlib = ['-dynamiclib'] v.cxxshlib_PATTERN = 'lib%s.dylib' v.FRAMEWORKPATH_ST = '-F%s' v.FRAMEWORK_ST = ['-framework'] v.ARCH_ST = ['-arch'] v.LINKFLAGS_cxxstlib = [] v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.SONAME_ST = [] @conf def gxx_modifier_aix(conf): """Configuration flags for executing g++ on AIX""" v = conf.env v.LINKFLAGS_cxxprogram= ['-Wl,-brtl'] v.LINKFLAGS_cxxshlib = ['-shared', '-Wl,-brtl,-bexpfull'] v.SHLIB_MARKER = [] @conf def gxx_modifier_hpux(conf): v = conf.env v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.CFLAGS_cxxshlib = ['-fPIC','-DPIC'] v.cxxshlib_PATTERN = 'lib%s.sl' @conf def gxx_modifier_openbsd(conf): conf.env.SONAME_ST = [] @conf def gcc_modifier_osf1V(conf): v = conf.env v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.SONAME_ST = [] @conf def gxx_modifier_platform(conf): """Execute platform-specific functions based on *gxx_modifier_+NAME*""" # * set configurations specific for a platform. # * the destination platform is detected automatically by looking at the macros the compiler predefines, # and if it's not recognised, it fallbacks to sys.platform. gxx_modifier_func = getattr(conf, 'gxx_modifier_' + conf.env.DEST_OS, None) if gxx_modifier_func: gxx_modifier_func() def configure(conf): """ Configuration for g++ """ conf.find_gxx() conf.find_ar() conf.gxx_common_flags() conf.gxx_modifier_platform() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() conf.check_gcc_o_space('cxx') ldb-2.0.8/third_party/waf/waflib/Tools/icc.py0000660000000000000000000000113413573675414021016 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Stian Selnes 2008 # Thomas Nagy 2009-2018 (ita) """ Detects the Intel C compiler """ import sys from waflib.Tools import ccroot, ar, gcc from waflib.Configure import conf @conf def find_icc(conf): """ Finds the program icc and execute it to ensure it really is icc """ cc = conf.find_program(['icc', 'ICL'], var='CC') conf.get_cc_version(cc, icc=True) conf.env.CC_NAME = 'icc' def configure(conf): conf.find_icc() conf.find_ar() conf.gcc_common_flags() conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py0000660000000000000000000000111613573675414021176 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy 2009-2018 (ita) """ Detects the Intel C++ compiler """ import sys from waflib.Tools import ccroot, ar, gxx from waflib.Configure import conf @conf def find_icpc(conf): """ Finds the program icpc, and execute it to ensure it really is icpc """ cxx = conf.find_program('icpc', var='CXX') conf.get_cc_version(cxx, icc=True) conf.env.CXX_NAME = 'icc' def configure(conf): conf.find_icpc() conf.find_ar() conf.gxx_common_flags() conf.gxx_modifier_platform() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py0000660000000000000000000003027113573675414021407 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # DC 2008 # Thomas Nagy 2016-2018 (ita) import os, re, traceback from waflib import Utils, Logs, Errors from waflib.Tools import fc, fc_config, fc_scan, ar, ccroot from waflib.Configure import conf from waflib.TaskGen import after_method, feature @conf def find_ifort(conf): fc = conf.find_program('ifort', var='FC') conf.get_ifort_version(fc) conf.env.FC_NAME = 'IFORT' @conf def ifort_modifier_win32(self): v = self.env v.IFORT_WIN32 = True v.FCSTLIB_MARKER = '' v.FCSHLIB_MARKER = '' v.FCLIB_ST = v.FCSTLIB_ST = '%s.lib' v.FCLIBPATH_ST = v.STLIBPATH_ST = '/LIBPATH:%s' v.FCINCPATH_ST = '/I%s' v.FCDEFINES_ST = '/D%s' v.fcprogram_PATTERN = v.fcprogram_test_PATTERN = '%s.exe' v.fcshlib_PATTERN = '%s.dll' v.fcstlib_PATTERN = v.implib_PATTERN = '%s.lib' v.FCLNK_TGT_F = '/out:' v.FC_TGT_F = ['/c', '/o', ''] v.FCFLAGS_fcshlib = '' v.LINKFLAGS_fcshlib = '/DLL' v.AR_TGT_F = '/out:' v.IMPLIB_ST = '/IMPLIB:%s' v.append_value('LINKFLAGS', '/subsystem:console') if v.IFORT_MANIFEST: v.append_value('LINKFLAGS', ['/MANIFEST']) @conf def ifort_modifier_darwin(conf): fc_config.fortran_modifier_darwin(conf) @conf def ifort_modifier_platform(conf): dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() ifort_modifier_func = getattr(conf, 'ifort_modifier_' + dest_os, None) if ifort_modifier_func: ifort_modifier_func() @conf def get_ifort_version(conf, fc): """ Detects the compiler version and sets ``conf.env.FC_VERSION`` """ version_re = re.compile(r"\bIntel\b.*\bVersion\s*(?P\d*)\.(?P\d*)",re.I).search if Utils.is_win32: cmd = fc else: cmd = fc + ['-logo'] out, err = fc_config.getoutput(conf, cmd, stdin=False) match = version_re(out) or version_re(err) if not match: conf.fatal('cannot determine ifort version.') k = match.groupdict() conf.env.FC_VERSION = (k['major'], k['minor']) def configure(conf): """ Detects the Intel Fortran compilers """ if Utils.is_win32: compiler, version, path, includes, libdirs, arch = conf.detect_ifort() v = conf.env v.DEST_CPU = arch v.PATH = path v.INCLUDES = includes v.LIBPATH = libdirs v.MSVC_COMPILER = compiler try: v.MSVC_VERSION = float(version) except ValueError: v.MSVC_VERSION = float(version[:-3]) conf.find_ifort_win32() conf.ifort_modifier_win32() else: conf.find_ifort() conf.find_program('xiar', var='AR') conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.ifort_modifier_platform() all_ifort_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] """List of icl platforms""" @conf def gather_ifort_versions(conf, versions): """ List compiler versions by looking up registry keys """ version_pattern = re.compile(r'^...?.?\....?.?') try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran') except OSError: try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\Fortran') except OSError: return index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except OSError: break index += 1 if not version_pattern.match(version): continue targets = {} for target,arch in all_ifort_platforms: if target=='intel64': targetDir='EM64T_NATIVE' else: targetDir=target try: Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) icl_version=Utils.winreg.OpenKey(all_versions,version) path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') except OSError: pass else: batch_file=os.path.join(path,'bin','ifortvars.bat') if os.path.isfile(batch_file): targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) for target,arch in all_ifort_platforms: try: icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') except OSError: continue else: batch_file=os.path.join(path,'bin','ifortvars.bat') if os.path.isfile(batch_file): targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) major = version[0:2] versions['intel ' + major] = targets @conf def setup_ifort(conf, versiondict): """ Checks installed compilers and targets and returns the first combination from the user's options, env, or the global supported lists that checks. :param versiondict: dict(platform -> dict(architecture -> configuration)) :type versiondict: dict(string -> dict(string -> target_compiler) :return: the compiler, revision, path, include dirs, library paths and target architecture :rtype: tuple of strings """ platforms = Utils.to_list(conf.env.MSVC_TARGETS) or [i for i,j in all_ifort_platforms] desired_versions = conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys()))) for version in desired_versions: try: targets = versiondict[version] except KeyError: continue for arch in platforms: try: cfg = targets[arch] except KeyError: continue cfg.evaluate() if cfg.is_valid: compiler,revision = version.rsplit(' ', 1) return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r' % (desired_versions, list(versiondict.keys()))) @conf def get_ifort_version_win32(conf, compiler, version, target, vcvars): # FIXME hack try: conf.msvc_cnt += 1 except AttributeError: conf.msvc_cnt = 1 batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) batfile.write("""@echo off set INCLUDE= set LIB= call "%s" %s echo PATH=%%PATH%% echo INCLUDE=%%INCLUDE%% echo LIB=%%LIB%%;%%LIBPATH%% """ % (vcvars,target)) sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) batfile.delete() lines = sout.splitlines() if not lines[0]: lines.pop(0) MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None for line in lines: if line.startswith('PATH='): path = line[5:] MSVC_PATH = path.split(';') elif line.startswith('INCLUDE='): MSVC_INCDIR = [i for i in line[8:].split(';') if i] elif line.startswith('LIB='): MSVC_LIBDIR = [i for i in line[4:].split(';') if i] if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)') # Check if the compiler is usable at all. # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. env = dict(os.environ) env.update(PATH = path) compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) fc = conf.find_program(compiler_name, path_list=MSVC_PATH) # delete CL if exists. because it could contain parameters which can change cl's behaviour rather catastrophically. if 'CL' in env: del(env['CL']) try: conf.cmd_and_log(fc + ['/help'], env=env) except UnicodeError: st = traceback.format_exc() if conf.logger: conf.logger.error(st) conf.fatal('ifort: Unicode error - check the code page?') except Exception as e: Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s', compiler, version, target, str(e)) conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)') else: Logs.debug('ifort: get_ifort_version: %r %r %r -> OK', compiler, version, target) finally: conf.env[compiler_name] = '' return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) class target_compiler(object): """ Wraps a compiler configuration; call evaluate() to determine whether the configuration is usable. """ def __init__(self, ctx, compiler, cpu, version, bat_target, bat, callback=None): """ :param ctx: configuration context to use to eventually get the version environment :param compiler: compiler name :param cpu: target cpu :param version: compiler version number :param bat_target: ? :param bat: path to the batch file to run :param callback: optional function to take the realized environment variables tup and map it (e.g. to combine other constant paths) """ self.conf = ctx self.name = None self.is_valid = False self.is_done = False self.compiler = compiler self.cpu = cpu self.version = version self.bat_target = bat_target self.bat = bat self.callback = callback def evaluate(self): if self.is_done: return self.is_done = True try: vs = self.conf.get_ifort_version_win32(self.compiler, self.version, self.bat_target, self.bat) except Errors.ConfigurationError: self.is_valid = False return if self.callback: vs = self.callback(self, vs) self.is_valid = True (self.bindirs, self.incdirs, self.libdirs) = vs def __str__(self): return str((self.bindirs, self.incdirs, self.libdirs)) def __repr__(self): return repr((self.bindirs, self.incdirs, self.libdirs)) @conf def detect_ifort(self): return self.setup_ifort(self.get_ifort_versions(False)) @conf def get_ifort_versions(self, eval_and_save=True): """ :return: platforms to compiler configurations :rtype: dict """ dct = {} self.gather_ifort_versions(dct) return dct def _get_prog_names(self, compiler): if compiler=='intel': compiler_name = 'ifort' linker_name = 'XILINK' lib_name = 'XILIB' else: # assumes CL.exe compiler_name = 'CL' linker_name = 'LINK' lib_name = 'LIB' return compiler_name, linker_name, lib_name @conf def find_ifort_win32(conf): # the autodetection is supposed to be performed before entering in this method v = conf.env path = v.PATH compiler = v.MSVC_COMPILER version = v.MSVC_VERSION compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) v.IFORT_MANIFEST = (compiler == 'intel' and version >= 11) # compiler fc = conf.find_program(compiler_name, var='FC', path_list=path) # before setting anything, check if the compiler is really intel fortran env = dict(conf.environ) if path: env.update(PATH = ';'.join(path)) if not conf.cmd_and_log(fc + ['/nologo', '/help'], env=env): conf.fatal('not intel fortran compiler could not be identified') v.FC_NAME = 'IFORT' if not v.LINK_FC: conf.find_program(linker_name, var='LINK_FC', path_list=path, mandatory=True) if not v.AR: conf.find_program(lib_name, path_list=path, var='AR', mandatory=True) v.ARFLAGS = ['/nologo'] # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later if v.IFORT_MANIFEST: conf.find_program('MT', path_list=path, var='MT') v.MTFLAGS = ['/nologo'] try: conf.load('winres') except Errors.WafError: Logs.warn('Resource compiler not found. Compiling resource file is disabled') ####################################################################################################### ##### conf above, build below @after_method('apply_link') @feature('fc') def apply_flags_ifort(self): """ Adds additional flags implied by msvc, such as subsystems and pdb files:: def build(bld): bld.stlib(source='main.c', target='bar', subsystem='gruik') """ if not self.env.IFORT_WIN32 or not getattr(self, 'link_task', None): return is_static = isinstance(self.link_task, ccroot.stlink_task) subsystem = getattr(self, 'subsystem', '') if subsystem: subsystem = '/subsystem:%s' % subsystem flags = is_static and 'ARFLAGS' or 'LINKFLAGS' self.env.append_value(flags, subsystem) if not is_static: for f in self.env.LINKFLAGS: d = f.lower() if d[1:] == 'debug': pdbnode = self.link_task.outputs[0].change_ext('.pdb') self.link_task.outputs.append(pdbnode) if getattr(self, 'install_task', None): self.pdb_install_task = self.add_install_files(install_to=self.install_task.install_to, install_from=pdbnode) break @feature('fcprogram', 'fcshlib', 'fcprogram_test') @after_method('apply_link') def apply_manifest_ifort(self): """ Enables manifest embedding in Fortran DLLs when using ifort on Windows See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx """ if self.env.IFORT_WIN32 and getattr(self, 'link_task', None): # it seems ifort.exe cannot be called for linking self.link_task.env.FC = self.env.LINK_FC if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self, 'link_task', None): out_node = self.link_task.outputs[0] man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') self.link_task.outputs.append(man_node) self.env.DO_MANIFEST = True ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py0000660000000000000000000001520013573675414022123 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) """ Support for translation tools such as msgfmt and intltool Usage:: def configure(conf): conf.load('gnu_dirs intltool') def build(bld): # process the .po files into .gmo files, and install them in LOCALEDIR bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}") # process an input file, substituting the translations from the po dir bld( features = "intltool_in", podir = "../po", style = "desktop", flags = ["-u"], source = 'kupfer.desktop.in', install_path = "${DATADIR}/applications", ) Usage of the :py:mod:`waflib.Tools.gnu_dirs` is recommended, but not obligatory. """ from __future__ import with_statement import os, re from waflib import Context, Task, Utils, Logs import waflib.Tools.ccroot from waflib.TaskGen import feature, before_method, taskgen_method from waflib.Logs import error from waflib.Configure import conf _style_flags = { 'ba': '-b', 'desktop': '-d', 'keys': '-k', 'quoted': '--quoted-style', 'quotedxml': '--quotedxml-style', 'rfc822deb': '-r', 'schemas': '-s', 'xml': '-x', } @taskgen_method def ensure_localedir(self): """ Expands LOCALEDIR from DATAROOTDIR/locale if possible, or falls back to PREFIX/share/locale """ # use the tool gnu_dirs to provide options to define this if not self.env.LOCALEDIR: if self.env.DATAROOTDIR: self.env.LOCALEDIR = os.path.join(self.env.DATAROOTDIR, 'locale') else: self.env.LOCALEDIR = os.path.join(self.env.PREFIX, 'share', 'locale') @before_method('process_source') @feature('intltool_in') def apply_intltool_in_f(self): """ Creates tasks to translate files by intltool-merge:: def build(bld): bld( features = "intltool_in", podir = "../po", style = "desktop", flags = ["-u"], source = 'kupfer.desktop.in', install_path = "${DATADIR}/applications", ) :param podir: location of the .po files :type podir: string :param source: source files to process :type source: list of string :param style: the intltool-merge mode of operation, can be one of the following values: ``ba``, ``desktop``, ``keys``, ``quoted``, ``quotedxml``, ``rfc822deb``, ``schemas`` and ``xml``. See the ``intltool-merge`` man page for more information about supported modes of operation. :type style: string :param flags: compilation flags ("-quc" by default) :type flags: list of string :param install_path: installation path :type install_path: string """ try: self.meths.remove('process_source') except ValueError: pass self.ensure_localedir() podir = getattr(self, 'podir', '.') podirnode = self.path.find_dir(podir) if not podirnode: error("could not find the podir %r" % podir) return cache = getattr(self, 'intlcache', '.intlcache') self.env.INTLCACHE = [os.path.join(str(self.path.get_bld()), podir, cache)] self.env.INTLPODIR = podirnode.bldpath() self.env.append_value('INTLFLAGS', getattr(self, 'flags', self.env.INTLFLAGS_DEFAULT)) if '-c' in self.env.INTLFLAGS: self.bld.fatal('Redundant -c flag in intltool task %r' % self) style = getattr(self, 'style', None) if style: try: style_flag = _style_flags[style] except KeyError: self.bld.fatal('intltool_in style "%s" is not valid' % style) self.env.append_unique('INTLFLAGS', [style_flag]) for i in self.to_list(self.source): node = self.path.find_resource(i) task = self.create_task('intltool', node, node.change_ext('')) inst = getattr(self, 'install_path', None) if inst: self.add_install_files(install_to=inst, install_from=task.outputs) @feature('intltool_po') def apply_intltool_po(self): """ Creates tasks to process po files:: def build(bld): bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}") The relevant task generator arguments are: :param podir: directory of the .po files :type podir: string :param appname: name of the application :type appname: string :param install_path: installation directory :type install_path: string The file LINGUAS must be present in the directory pointed by *podir* and list the translation files to process. """ try: self.meths.remove('process_source') except ValueError: pass self.ensure_localedir() appname = getattr(self, 'appname', getattr(Context.g_module, Context.APPNAME, 'set_your_app_name')) podir = getattr(self, 'podir', '.') inst = getattr(self, 'install_path', '${LOCALEDIR}') linguas = self.path.find_node(os.path.join(podir, 'LINGUAS')) if linguas: # scan LINGUAS file for locales to process with open(linguas.abspath()) as f: langs = [] for line in f.readlines(): # ignore lines containing comments if not line.startswith('#'): langs += line.split() re_linguas = re.compile('[-a-zA-Z_@.]+') for lang in langs: # Make sure that we only process lines which contain locales if re_linguas.match(lang): node = self.path.find_resource(os.path.join(podir, re_linguas.match(lang).group() + '.po')) task = self.create_task('po', node, node.change_ext('.mo')) if inst: filename = task.outputs[0].name (langname, ext) = os.path.splitext(filename) inst_file = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + appname + '.mo' self.add_install_as(install_to=inst_file, install_from=task.outputs[0], chmod=getattr(self, 'chmod', Utils.O644)) else: Logs.pprint('RED', "Error no LINGUAS file found in po directory") class po(Task.Task): """ Compiles .po files into .gmo files """ run_str = '${MSGFMT} -o ${TGT} ${SRC}' color = 'BLUE' class intltool(Task.Task): """ Calls intltool-merge to update translation files """ run_str = '${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}' color = 'BLUE' @conf def find_msgfmt(conf): """ Detects msgfmt and sets the ``MSGFMT`` variable """ conf.find_program('msgfmt', var='MSGFMT') @conf def find_intltool_merge(conf): """ Detects intltool-merge """ if not conf.env.PERL: conf.find_program('perl', var='PERL') conf.env.INTLCACHE_ST = '--cache=%s' conf.env.INTLFLAGS_DEFAULT = ['-q', '-u'] conf.find_program('intltool-merge', interpreter='PERL', var='INTLTOOL') def configure(conf): """ Detects the program *msgfmt* and set *conf.env.MSGFMT*. Detects the program *intltool-merge* and set *conf.env.INTLTOOL*. It is possible to set INTLTOOL in the environment, but it must not have spaces in it:: $ INTLTOOL="/path/to/the program/intltool" waf configure If a C/C++ compiler is present, execute a compilation test to find the header *locale.h*. """ conf.find_msgfmt() conf.find_intltool_merge() if conf.env.CC or conf.env.CXX: conf.check(header_name='locale.h') ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py0000660000000000000000000000250613573675414021545 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # imported from samba """ Compiler definition for irix/MIPSpro cc compiler """ from waflib import Errors from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_irixcc(conf): v = conf.env cc = None if v.CC: cc = v.CC elif 'CC' in conf.environ: cc = conf.environ['CC'] if not cc: cc = conf.find_program('cc', var='CC') if not cc: conf.fatal('irixcc was not found') try: conf.cmd_and_log(cc + ['-version']) except Errors.WafError: conf.fatal('%r -version could not be executed' % cc) v.CC = cc v.CC_NAME = 'irix' @conf def irixcc_common_flags(conf): v = conf.env v.CC_SRC_F = '' v.CC_TGT_F = ['-c', '-o'] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' if not v.LINK_CC: v.LINK_CC = v.CC v.CCLNK_SRC_F = '' v.CCLNK_TGT_F = ['-o'] v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.cprogram_PATTERN = '%s' v.cshlib_PATTERN = 'lib%s.so' v.cstlib_PATTERN = 'lib%s.a' def configure(conf): conf.find_irixcc() conf.find_cpp() conf.find_ar() conf.irixcc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py0000660000000000000000000004076013573675414021400 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) """ Java support Javac is one of the few compilers that behaves very badly: #. it outputs files where it wants to (-d is only for the package root) #. it recompiles files silently behind your back #. it outputs an undefined amount of files (inner classes) Remember that the compilation can be performed using Jython[1] rather than regular Python. Instead of running one of the following commands:: ./waf configure python waf configure You would have to run:: java -jar /path/to/jython.jar waf configure [1] http://www.jython.org/ Usage ===== Load the "java" tool. def configure(conf): conf.load('java') Java tools will be autodetected and eventually, if present, the quite standard JAVA_HOME environment variable will be used. The also standard CLASSPATH variable is used for library searching. In configuration phase checks can be done on the system environment, for example to check if a class is known in the classpath:: conf.check_java_class('java.io.FileOutputStream') or if the system supports JNI applications building:: conf.check_jni_headers() The java tool supports compiling java code, creating jar files and creating javadoc documentation. This can be either done separately or together in a single definition. For example to manage them separately:: bld(features = 'javac', srcdir = 'src', compat = '1.7', use = 'animals', name = 'cats-src', ) bld(features = 'jar', basedir = '.', destfile = '../cats.jar', name = 'cats', use = 'cats-src' ) Or together by defining all the needed attributes:: bld(features = 'javac jar javadoc', srcdir = 'src/', # folder containing the sources to compile outdir = 'src', # folder where to output the classes (in the build directory) compat = '1.6', # java compatibility version number classpath = ['.', '..'], # jar basedir = 'src', # folder containing the classes and other files to package (must match outdir) destfile = 'foo.jar', # do not put the destfile in the folder of the java classes! use = 'NNN', jaropts = ['-C', 'default/src/', '.'], # can be used to give files manifest = 'src/Manifest.mf', # Manifest file to include # javadoc javadoc_package = ['com.meow' , 'com.meow.truc.bar', 'com.meow.truc.foo'], javadoc_output = 'javadoc', ) External jar dependencies can be mapped to a standard waf "use" dependency by setting an environment variable with a CLASSPATH prefix in the configuration, for example:: conf.env.CLASSPATH_NNN = ['aaaa.jar', 'bbbb.jar'] and then NNN can be freely used in rules as:: use = 'NNN', In the java tool the dependencies via use are not transitive by default, as this necessity depends on the code. To enable recursive dependency scanning use on a specific rule: recurse_use = True Or build-wise by setting RECURSE_JAVA: bld.env.RECURSE_JAVA = True Unit tests can be integrated in the waf unit test environment using the javatest extra. """ import os, shutil from waflib import Task, Utils, Errors, Node from waflib.Configure import conf from waflib.TaskGen import feature, before_method, after_method, taskgen_method from waflib.Tools import ccroot ccroot.USELIB_VARS['javac'] = set(['CLASSPATH', 'JAVACFLAGS']) SOURCE_RE = '**/*.java' JAR_RE = '**/*' class_check_source = ''' public class Test { public static void main(String[] argv) { Class lib; if (argv.length < 1) { System.err.println("Missing argument"); System.exit(77); } try { lib = Class.forName(argv[0]); } catch (ClassNotFoundException e) { System.err.println("ClassNotFoundException"); System.exit(1); } lib = null; System.exit(0); } } ''' @feature('javac') @before_method('process_source') def apply_java(self): """ Create a javac task for compiling *.java files*. There can be only one javac task by task generator. """ Utils.def_attrs(self, jarname='', classpath='', sourcepath='.', srcdir='.', jar_mf_attributes={}, jar_mf_classpath=[]) outdir = getattr(self, 'outdir', None) if outdir: if not isinstance(outdir, Node.Node): outdir = self.path.get_bld().make_node(self.outdir) else: outdir = self.path.get_bld() outdir.mkdir() self.outdir = outdir self.env.OUTDIR = outdir.abspath() self.javac_task = tsk = self.create_task('javac') tmp = [] srcdir = getattr(self, 'srcdir', '') if isinstance(srcdir, Node.Node): srcdir = [srcdir] for x in Utils.to_list(srcdir): if isinstance(x, Node.Node): y = x else: y = self.path.find_dir(x) if not y: self.bld.fatal('Could not find the folder %s from %s' % (x, self.path)) tmp.append(y) tsk.srcdir = tmp if getattr(self, 'compat', None): tsk.env.append_value('JAVACFLAGS', ['-source', str(self.compat)]) if hasattr(self, 'sourcepath'): fold = [isinstance(x, Node.Node) and x or self.path.find_dir(x) for x in self.to_list(self.sourcepath)] names = os.pathsep.join([x.srcpath() for x in fold]) else: names = [x.srcpath() for x in tsk.srcdir] if names: tsk.env.append_value('JAVACFLAGS', ['-sourcepath', names]) @taskgen_method def java_use_rec(self, name, **kw): """ Processes recursively the *use* attribute for each referred java compilation """ if name in self.tmp_use_seen: return self.tmp_use_seen.append(name) try: y = self.bld.get_tgen_by_name(name) except Errors.WafError: self.uselib.append(name) return else: y.post() # Add generated JAR name for CLASSPATH. Task ordering (set_run_after) # is already guaranteed by ordering done between the single tasks if hasattr(y, 'jar_task'): self.use_lst.append(y.jar_task.outputs[0].abspath()) else: if hasattr(y,'outdir'): self.use_lst.append(y.outdir.abspath()) else: self.use_lst.append(y.path.get_bld().abspath()) for x in self.to_list(getattr(y, 'use', [])): self.java_use_rec(x) @feature('javac') @before_method('propagate_uselib_vars') @after_method('apply_java') def use_javac_files(self): """ Processes the *use* attribute referring to other java compilations """ self.use_lst = [] self.tmp_use_seen = [] self.uselib = self.to_list(getattr(self, 'uselib', [])) names = self.to_list(getattr(self, 'use', [])) get = self.bld.get_tgen_by_name for x in names: try: tg = get(x) except Errors.WafError: self.uselib.append(x) else: tg.post() if hasattr(tg, 'jar_task'): self.use_lst.append(tg.jar_task.outputs[0].abspath()) self.javac_task.set_run_after(tg.jar_task) self.javac_task.dep_nodes.extend(tg.jar_task.outputs) else: if hasattr(tg, 'outdir'): base_node = tg.outdir else: base_node = tg.path.get_bld() self.use_lst.append(base_node.abspath()) self.javac_task.dep_nodes.extend([x for x in base_node.ant_glob(JAR_RE, remove=False, quiet=True)]) for tsk in tg.tasks: self.javac_task.set_run_after(tsk) # If recurse use scan is enabled recursively add use attribute for each used one if getattr(self, 'recurse_use', False) or self.bld.env.RECURSE_JAVA: self.java_use_rec(x) self.env.append_value('CLASSPATH', self.use_lst) @feature('javac') @after_method('apply_java', 'propagate_uselib_vars', 'use_javac_files') def set_classpath(self): """ Sets the CLASSPATH value on the *javac* task previously created. """ if getattr(self, 'classpath', None): self.env.append_unique('CLASSPATH', getattr(self, 'classpath', [])) for x in self.tasks: x.env.CLASSPATH = os.pathsep.join(self.env.CLASSPATH) + os.pathsep @feature('jar') @after_method('apply_java', 'use_javac_files') @before_method('process_source') def jar_files(self): """ Creates a jar task (one maximum per task generator) """ destfile = getattr(self, 'destfile', 'test.jar') jaropts = getattr(self, 'jaropts', []) manifest = getattr(self, 'manifest', None) basedir = getattr(self, 'basedir', None) if basedir: if not isinstance(self.basedir, Node.Node): basedir = self.path.get_bld().make_node(basedir) else: basedir = self.path.get_bld() if not basedir: self.bld.fatal('Could not find the basedir %r for %r' % (self.basedir, self)) self.jar_task = tsk = self.create_task('jar_create') if manifest: jarcreate = getattr(self, 'jarcreate', 'cfm') if not isinstance(manifest,Node.Node): node = self.path.find_resource(manifest) else: node = manifest if not node: self.bld.fatal('invalid manifest file %r for %r' % (manifest, self)) tsk.dep_nodes.append(node) jaropts.insert(0, node.abspath()) else: jarcreate = getattr(self, 'jarcreate', 'cf') if not isinstance(destfile, Node.Node): destfile = self.path.find_or_declare(destfile) if not destfile: self.bld.fatal('invalid destfile %r for %r' % (destfile, self)) tsk.set_outputs(destfile) tsk.basedir = basedir jaropts.append('-C') jaropts.append(basedir.bldpath()) jaropts.append('.') tsk.env.JAROPTS = jaropts tsk.env.JARCREATE = jarcreate if getattr(self, 'javac_task', None): tsk.set_run_after(self.javac_task) @feature('jar') @after_method('jar_files') def use_jar_files(self): """ Processes the *use* attribute to set the build order on the tasks created by another task generator. """ self.uselib = self.to_list(getattr(self, 'uselib', [])) names = self.to_list(getattr(self, 'use', [])) get = self.bld.get_tgen_by_name for x in names: try: y = get(x) except Errors.WafError: self.uselib.append(x) else: y.post() self.jar_task.run_after.update(y.tasks) class JTask(Task.Task): """ Base class for java and jar tasks; provides functionality to run long commands """ def split_argfile(self, cmd): inline = [cmd[0]] infile = [] for x in cmd[1:]: # jar and javac do not want -J flags in @file if x.startswith('-J'): inline.append(x) else: infile.append(self.quote_flag(x)) return (inline, infile) class jar_create(JTask): """ Creates a jar file """ color = 'GREEN' run_str = '${JAR} ${JARCREATE} ${TGT} ${JAROPTS}' def runnable_status(self): """ Wait for dependent tasks to be executed, then read the files to update the list of inputs. """ for t in self.run_after: if not t.hasrun: return Task.ASK_LATER if not self.inputs: try: self.inputs = [x for x in self.basedir.ant_glob(JAR_RE, remove=False, quiet=True) if id(x) != id(self.outputs[0])] except Exception: raise Errors.WafError('Could not find the basedir %r for %r' % (self.basedir, self)) return super(jar_create, self).runnable_status() class javac(JTask): """ Compiles java files """ color = 'BLUE' run_str = '${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}' vars = ['CLASSPATH', 'JAVACFLAGS', 'JAVAC', 'OUTDIR'] """ The javac task will be executed again if the variables CLASSPATH, JAVACFLAGS, JAVAC or OUTDIR change. """ def uid(self): """Identify java tasks by input&output folder""" lst = [self.__class__.__name__, self.generator.outdir.abspath()] for x in self.srcdir: lst.append(x.abspath()) return Utils.h_list(lst) def runnable_status(self): """ Waits for dependent tasks to be complete, then read the file system to find the input nodes. """ for t in self.run_after: if not t.hasrun: return Task.ASK_LATER if not self.inputs: self.inputs = [] for x in self.srcdir: if x.exists(): self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False, quiet=True)) return super(javac, self).runnable_status() def post_run(self): """ List class files created """ for node in self.generator.outdir.ant_glob('**/*.class', quiet=True): self.generator.bld.node_sigs[node] = self.uid() self.generator.bld.task_sigs[self.uid()] = self.cache_sig @feature('javadoc') @after_method('process_rule') def create_javadoc(self): """ Creates a javadoc task (feature 'javadoc') """ tsk = self.create_task('javadoc') tsk.classpath = getattr(self, 'classpath', []) self.javadoc_package = Utils.to_list(self.javadoc_package) if not isinstance(self.javadoc_output, Node.Node): self.javadoc_output = self.bld.path.find_or_declare(self.javadoc_output) class javadoc(Task.Task): """ Builds java documentation """ color = 'BLUE' def __str__(self): return '%s: %s -> %s\n' % (self.__class__.__name__, self.generator.srcdir, self.generator.javadoc_output) def run(self): env = self.env bld = self.generator.bld wd = bld.bldnode #add src node + bld node (for generated java code) srcpath = self.generator.path.abspath() + os.sep + self.generator.srcdir srcpath += os.pathsep srcpath += self.generator.path.get_bld().abspath() + os.sep + self.generator.srcdir classpath = env.CLASSPATH classpath += os.pathsep classpath += os.pathsep.join(self.classpath) classpath = "".join(classpath) self.last_cmd = lst = [] lst.extend(Utils.to_list(env.JAVADOC)) lst.extend(['-d', self.generator.javadoc_output.abspath()]) lst.extend(['-sourcepath', srcpath]) lst.extend(['-classpath', classpath]) lst.extend(['-subpackages']) lst.extend(self.generator.javadoc_package) lst = [x for x in lst if x] self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0) def post_run(self): nodes = self.generator.javadoc_output.ant_glob('**', quiet=True) for node in nodes: self.generator.bld.node_sigs[node] = self.uid() self.generator.bld.task_sigs[self.uid()] = self.cache_sig def configure(self): """ Detects the javac, java and jar programs """ # If JAVA_PATH is set, we prepend it to the path list java_path = self.environ['PATH'].split(os.pathsep) v = self.env if 'JAVA_HOME' in self.environ: java_path = [os.path.join(self.environ['JAVA_HOME'], 'bin')] + java_path self.env.JAVA_HOME = [self.environ['JAVA_HOME']] for x in 'javac java jar javadoc'.split(): self.find_program(x, var=x.upper(), path_list=java_path, mandatory=(x not in ('javadoc'))) if 'CLASSPATH' in self.environ: v.CLASSPATH = self.environ['CLASSPATH'] if not v.JAR: self.fatal('jar is required for making java packages') if not v.JAVAC: self.fatal('javac is required for compiling java classes') v.JARCREATE = 'cf' # can use cvf v.JAVACFLAGS = [] @conf def check_java_class(self, classname, with_classpath=None): """ Checks if the specified java class exists :param classname: class to check, like java.util.HashMap :type classname: string :param with_classpath: additional classpath to give :type with_classpath: string """ javatestdir = '.waf-javatest' classpath = javatestdir if self.env.CLASSPATH: classpath += os.pathsep + self.env.CLASSPATH if isinstance(with_classpath, str): classpath += os.pathsep + with_classpath shutil.rmtree(javatestdir, True) os.mkdir(javatestdir) Utils.writef(os.path.join(javatestdir, 'Test.java'), class_check_source) # Compile the source self.exec_command(self.env.JAVAC + [os.path.join(javatestdir, 'Test.java')], shell=False) # Try to run the app cmd = self.env.JAVA + ['-cp', classpath, 'Test', classname] self.to_log("%s\n" % str(cmd)) found = self.exec_command(cmd, shell=False) self.msg('Checking for java class %s' % classname, not found) shutil.rmtree(javatestdir, True) return found @conf def check_jni_headers(conf): """ Checks for jni headers and libraries. On success the conf.env variables xxx_JAVA are added for use in C/C++ targets:: def options(opt): opt.load('compiler_c') def configure(conf): conf.load('compiler_c java') conf.check_jni_headers() def build(bld): bld.shlib(source='a.c', target='app', use='JAVA') """ if not conf.env.CC_NAME and not conf.env.CXX_NAME: conf.fatal('load a compiler first (gcc, g++, ..)') if not conf.env.JAVA_HOME: conf.fatal('set JAVA_HOME in the system environment') # jni requires the jvm javaHome = conf.env.JAVA_HOME[0] dir = conf.root.find_dir(conf.env.JAVA_HOME[0] + '/include') if dir is None: dir = conf.root.find_dir(conf.env.JAVA_HOME[0] + '/../Headers') # think different?! if dir is None: conf.fatal('JAVA_HOME does not seem to be set properly') f = dir.ant_glob('**/(jni|jni_md).h') incDirs = [x.parent.abspath() for x in f] dir = conf.root.find_dir(conf.env.JAVA_HOME[0]) f = dir.ant_glob('**/*jvm.(so|dll|dylib)') libDirs = [x.parent.abspath() for x in f] or [javaHome] # On windows, we need both the .dll and .lib to link. On my JDK, they are # in different directories... f = dir.ant_glob('**/*jvm.(lib)') if f: libDirs = [[x, y.parent.abspath()] for x in libDirs for y in f] if conf.env.DEST_OS == 'freebsd': conf.env.append_unique('LINKFLAGS_JAVA', '-pthread') for d in libDirs: try: conf.check(header_name='jni.h', define_name='HAVE_JNI_H', lib='jvm', libpath=d, includes=incDirs, uselib_store='JAVA', uselib='JAVA') except Exception: pass else: break else: conf.fatal('could not find lib jvm in %r (see config.log)' % libDirs) ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py0000660000000000000000000000224113573675414021104 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Alex Rønne Petersen, 2012 (alexrp/Zor) from waflib.Tools import ar, d from waflib.Configure import conf @conf def find_ldc2(conf): """ Finds the program *ldc2* and set the variable *D* """ conf.find_program(['ldc2'], var='D') out = conf.cmd_and_log(conf.env.D + ['-version']) if out.find("based on DMD v2.") == -1: conf.fatal("detected compiler is not ldc2") @conf def common_flags_ldc2(conf): """ Sets the D flags required by *ldc2* """ v = conf.env v.D_SRC_F = ['-c'] v.D_TGT_F = '-of%s' v.D_LINKER = v.D v.DLNK_SRC_F = '' v.DLNK_TGT_F = '-of%s' v.DINC_ST = '-I%s' v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' v.DSTLIB_ST = v.DSHLIB_ST = '-L-l%s' v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L-L%s' v.LINKFLAGS_dshlib = ['-L-shared'] v.DHEADER_ext = '.di' v.DFLAGS_d_with_header = ['-H', '-Hf'] v.D_HDR_F = '%s' v.LINKFLAGS = [] v.DFLAGS_dshlib = ['-relocation-model=pic'] def configure(conf): """ Configuration for *ldc2* """ conf.find_ldc2() conf.load('ar') conf.load('d') conf.common_flags_ldc2() conf.d_platform_flags() ldb-2.0.8/third_party/waf/waflib/Tools/lua.py0000660000000000000000000000152313573675414021043 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Sebastian Schlingmann, 2008 # Thomas Nagy, 2008-2018 (ita) """ Lua support. Compile *.lua* files into *.luac*:: def configure(conf): conf.load('lua') conf.env.LUADIR = '/usr/local/share/myapp/scripts/' def build(bld): bld(source='foo.lua') """ from waflib.TaskGen import extension from waflib import Task @extension('.lua') def add_lua(self, node): tsk = self.create_task('luac', node, node.change_ext('.luac')) inst_to = getattr(self, 'install_path', self.env.LUADIR and '${LUADIR}' or None) if inst_to: self.add_install_files(install_to=inst_to, install_from=tsk.outputs) return tsk class luac(Task.Task): run_str = '${LUAC} -s -o ${TGT} ${SRC}' color = 'PINK' def configure(conf): """ Detect the luac compiler and set *conf.env.LUAC* """ conf.find_program('luac', var='LUAC') ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py0000660000000000000000000000170313573675414022337 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 """ Re-calculate md5 hashes of files only when the file time have changed:: def options(opt): opt.load('md5_tstamp') The hashes can also reflect either the file contents (STRONGEST=True) or the file time and file size. The performance benefits of this module are usually insignificant. """ import os, stat from waflib import Utils, Build, Node STRONGEST = True Build.SAVED_ATTRS.append('hashes_md5_tstamp') def h_file(self): filename = self.abspath() st = os.stat(filename) cache = self.ctx.hashes_md5_tstamp if filename in cache and cache[filename][0] == st.st_mtime: return cache[filename][1] if STRONGEST: ret = Utils.h_file(filename) else: if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('Not a file') ret = Utils.md5(str((st.st_mtime, st.st_size)).encode()).digest() cache[filename] = (st.st_mtime, ret) return ret h_file.__doc__ = Node.Node.h_file.__doc__ Node.Node.h_file = h_file ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py0000660000000000000000000010420213573675414021230 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2006 (dv) # Tamas Pal, 2007 (folti) # Nicolas Mercier, 2009 # Matt Clarkson, 2012 """ Microsoft Visual C++/Intel C++ compiler support If you get detection problems, first try any of the following:: chcp 65001 set PYTHONIOENCODING=... set PYTHONLEGACYWINDOWSSTDIO=1 Usage:: $ waf configure --msvc_version="msvc 10.0,msvc 9.0" --msvc_target="x64" or:: def configure(conf): conf.env.MSVC_VERSIONS = ['msvc 10.0', 'msvc 9.0', 'msvc 8.0', 'msvc 7.1', 'msvc 7.0', 'msvc 6.0', 'wsdk 7.0', 'intel 11', 'PocketPC 9.0', 'Smartphone 8.0'] conf.env.MSVC_TARGETS = ['x64'] conf.load('msvc') or:: def configure(conf): conf.load('msvc', funs='no_autodetect') conf.check_lib_msvc('gdi32') conf.check_libs_msvc('kernel32 user32') def build(bld): tg = bld.program(source='main.c', target='app', use='KERNEL32 USER32 GDI32') Platforms and targets will be tested in the order they appear; the first good configuration will be used. To force testing all the configurations that are not used, use the ``--no-msvc-lazy`` option or set ``conf.env.MSVC_LAZY_AUTODETECT=False``. Supported platforms: ia64, x64, x86, x86_amd64, x86_ia64, x86_arm, amd64_x86, amd64_arm Compilers supported: * msvc => Visual Studio, versions 6.0 (VC 98, VC .NET 2002) to 15 (Visual Studio 2017) * wsdk => Windows SDK, versions 6.0, 6.1, 7.0, 7.1, 8.0 * icl => Intel compiler, versions 9, 10, 11, 13 * winphone => Visual Studio to target Windows Phone 8 native (version 8.0 for now) * Smartphone => Compiler/SDK for Smartphone devices (armv4/v4i) * PocketPC => Compiler/SDK for PocketPC devices (armv4/v4i) To use WAF in a VS2008 Make file project (see http://code.google.com/p/waf/issues/detail?id=894) You may consider to set the environment variable "VS_UNICODE_OUTPUT" to nothing before calling waf. So in your project settings use something like 'cmd.exe /C "set VS_UNICODE_OUTPUT=& set PYTHONUNBUFFERED=true & waf build"'. cmd.exe /C "chcp 1252 & set PYTHONUNBUFFERED=true && set && waf configure" Setting PYTHONUNBUFFERED gives the unbuffered output. """ import os, sys, re, traceback from waflib import Utils, Logs, Options, Errors from waflib.TaskGen import after_method, feature from waflib.Configure import conf from waflib.Tools import ccroot, c, cxx, ar g_msvc_systemlibs = ''' aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32 osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32 shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32 traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp '''.split() """importlibs provided by MSVC/Platform SDK. Do NOT search them""" all_msvc_platforms = [ ('x64', 'amd64'), ('x86', 'x86'), ('ia64', 'ia64'), ('x86_amd64', 'amd64'), ('x86_ia64', 'ia64'), ('x86_arm', 'arm'), ('x86_arm64', 'arm64'), ('amd64_x86', 'x86'), ('amd64_arm', 'arm'), ('amd64_arm64', 'arm64') ] """List of msvc platforms""" all_wince_platforms = [ ('armv4', 'arm'), ('armv4i', 'arm'), ('mipsii', 'mips'), ('mipsii_fp', 'mips'), ('mipsiv', 'mips'), ('mipsiv_fp', 'mips'), ('sh4', 'sh'), ('x86', 'cex86') ] """List of wince platforms""" all_icl_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] """List of icl platforms""" def options(opt): opt.add_option('--msvc_version', type='string', help = 'msvc version, eg: "msvc 10.0,msvc 9.0"', default='') opt.add_option('--msvc_targets', type='string', help = 'msvc targets, eg: "x64,arm"', default='') opt.add_option('--no-msvc-lazy', action='store_false', help = 'lazily check msvc target environments', default=True, dest='msvc_lazy') @conf def setup_msvc(conf, versiondict): """ Checks installed compilers and targets and returns the first combination from the user's options, env, or the global supported lists that checks. :param versiondict: dict(platform -> dict(architecture -> configuration)) :type versiondict: dict(string -> dict(string -> target_compiler) :return: the compiler, revision, path, include dirs, library paths and target architecture :rtype: tuple of strings """ platforms = getattr(Options.options, 'msvc_targets', '').split(',') if platforms == ['']: platforms=Utils.to_list(conf.env.MSVC_TARGETS) or [i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms] desired_versions = getattr(Options.options, 'msvc_version', '').split(',') if desired_versions == ['']: desired_versions = conf.env.MSVC_VERSIONS or list(reversed(sorted(versiondict.keys()))) # Override lazy detection by evaluating after the fact. lazy_detect = getattr(Options.options, 'msvc_lazy', True) if conf.env.MSVC_LAZY_AUTODETECT is False: lazy_detect = False if not lazy_detect: for val in versiondict.values(): for arch in list(val.keys()): cfg = val[arch] cfg.evaluate() if not cfg.is_valid: del val[arch] conf.env.MSVC_INSTALLED_VERSIONS = versiondict for version in desired_versions: Logs.debug('msvc: detecting %r - %r', version, desired_versions) try: targets = versiondict[version] except KeyError: continue seen = set() for arch in platforms: if arch in seen: continue else: seen.add(arch) try: cfg = targets[arch] except KeyError: continue cfg.evaluate() if cfg.is_valid: compiler,revision = version.rsplit(' ', 1) return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu conf.fatal('msvc: Impossible to find a valid architecture for building %r - %r' % (desired_versions, list(versiondict.keys()))) @conf def get_msvc_version(conf, compiler, version, target, vcvars): """ Checks that an installed compiler actually runs and uses vcvars to obtain the environment needed by the compiler. :param compiler: compiler type, for looking up the executable name :param version: compiler version, for debugging only :param target: target architecture :param vcvars: batch file to run to check the environment :return: the location of the compiler executable, the location of include dirs, and the library paths :rtype: tuple of strings """ Logs.debug('msvc: get_msvc_version: %r %r %r', compiler, version, target) try: conf.msvc_cnt += 1 except AttributeError: conf.msvc_cnt = 1 batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) batfile.write("""@echo off set INCLUDE= set LIB= call "%s" %s echo PATH=%%PATH%% echo INCLUDE=%%INCLUDE%% echo LIB=%%LIB%%;%%LIBPATH%% """ % (vcvars,target)) sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) lines = sout.splitlines() if not lines[0]: lines.pop(0) MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None for line in lines: if line.startswith('PATH='): path = line[5:] MSVC_PATH = path.split(';') elif line.startswith('INCLUDE='): MSVC_INCDIR = [i for i in line[8:].split(';') if i] elif line.startswith('LIB='): MSVC_LIBDIR = [i for i in line[4:].split(';') if i] if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)') # Check if the compiler is usable at all. # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. env = dict(os.environ) env.update(PATH = path) compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) cxx = conf.find_program(compiler_name, path_list=MSVC_PATH) # delete CL if exists. because it could contain parameters which can change cl's behaviour rather catastrophically. if 'CL' in env: del(env['CL']) try: conf.cmd_and_log(cxx + ['/help'], env=env) except UnicodeError: st = traceback.format_exc() if conf.logger: conf.logger.error(st) conf.fatal('msvc: Unicode error - check the code page?') except Exception as e: Logs.debug('msvc: get_msvc_version: %r %r %r -> failure %s', compiler, version, target, str(e)) conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)') else: Logs.debug('msvc: get_msvc_version: %r %r %r -> OK', compiler, version, target) finally: conf.env[compiler_name] = '' return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) def gather_wince_supported_platforms(): """ Checks SmartPhones SDKs :param versions: list to modify :type versions: list """ supported_wince_platforms = [] try: ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs') except OSError: try: ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs') except OSError: ce_sdk = '' if not ce_sdk: return supported_wince_platforms index = 0 while 1: try: sdk_device = Utils.winreg.EnumKey(ce_sdk, index) sdk = Utils.winreg.OpenKey(ce_sdk, sdk_device) except OSError: break index += 1 try: path,type = Utils.winreg.QueryValueEx(sdk, 'SDKRootDir') except OSError: try: path,type = Utils.winreg.QueryValueEx(sdk,'SDKInformation') except OSError: continue path,xml = os.path.split(path) path = str(path) path,device = os.path.split(path) if not device: path,device = os.path.split(path) platforms = [] for arch,compiler in all_wince_platforms: if os.path.isdir(os.path.join(path, device, 'Lib', arch)): platforms.append((arch, compiler, os.path.join(path, device, 'Include', arch), os.path.join(path, device, 'Lib', arch))) if platforms: supported_wince_platforms.append((device, platforms)) return supported_wince_platforms def gather_msvc_detected_versions(): #Detected MSVC versions! version_pattern = re.compile(r'^(\d\d?\.\d\d?)(Exp)?$') detected_versions = [] for vcver,vcvar in (('VCExpress','Exp'), ('VisualStudio','')): prefix = 'SOFTWARE\\Wow6432node\\Microsoft\\' + vcver try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) except OSError: prefix = 'SOFTWARE\\Microsoft\\' + vcver try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) except OSError: continue index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except OSError: break index += 1 match = version_pattern.match(version) if match: versionnumber = float(match.group(1)) else: continue detected_versions.append((versionnumber, version+vcvar, prefix+'\\'+version)) def fun(tup): return tup[0] detected_versions.sort(key = fun) return detected_versions class target_compiler(object): """ Wrap a compiler configuration; call evaluate() to determine whether the configuration is usable. """ def __init__(self, ctx, compiler, cpu, version, bat_target, bat, callback=None): """ :param ctx: configuration context to use to eventually get the version environment :param compiler: compiler name :param cpu: target cpu :param version: compiler version number :param bat_target: ? :param bat: path to the batch file to run """ self.conf = ctx self.name = None self.is_valid = False self.is_done = False self.compiler = compiler self.cpu = cpu self.version = version self.bat_target = bat_target self.bat = bat self.callback = callback def evaluate(self): if self.is_done: return self.is_done = True try: vs = self.conf.get_msvc_version(self.compiler, self.version, self.bat_target, self.bat) except Errors.ConfigurationError: self.is_valid = False return if self.callback: vs = self.callback(self, vs) self.is_valid = True (self.bindirs, self.incdirs, self.libdirs) = vs def __str__(self): return str((self.compiler, self.cpu, self.version, self.bat_target, self.bat)) def __repr__(self): return repr((self.compiler, self.cpu, self.version, self.bat_target, self.bat)) @conf def gather_wsdk_versions(conf, versions): """ Use winreg to add the msvc versions to the input list :param versions: list to modify :type versions: list """ version_pattern = re.compile(r'^v..?.?\...?.?') try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows') except OSError: try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows') except OSError: return index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except OSError: break index += 1 if not version_pattern.match(version): continue try: msvc_version = Utils.winreg.OpenKey(all_versions, version) path,type = Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder') except OSError: continue if path and os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')): targets = {} for target,arch in all_msvc_platforms: targets[target] = target_compiler(conf, 'wsdk', arch, version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd')) versions['wsdk ' + version[1:]] = targets @conf def gather_msvc_targets(conf, versions, version, vc_path): #Looking for normal MSVC compilers! targets = {} if os.path.isfile(os.path.join(vc_path, 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat')): for target,realtarget in all_msvc_platforms[::-1]: targets[target] = target_compiler(conf, 'msvc', realtarget, version, target, os.path.join(vc_path, 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat')) elif os.path.isfile(os.path.join(vc_path, 'vcvarsall.bat')): for target,realtarget in all_msvc_platforms[::-1]: targets[target] = target_compiler(conf, 'msvc', realtarget, version, target, os.path.join(vc_path, 'vcvarsall.bat')) elif os.path.isfile(os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')): targets['x86'] = target_compiler(conf, 'msvc', 'x86', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')) elif os.path.isfile(os.path.join(vc_path, 'Bin', 'vcvars32.bat')): targets['x86'] = target_compiler(conf, 'msvc', 'x86', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat')) if targets: versions['msvc %s' % version] = targets @conf def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms): #Looking for Win CE compilers! for device,platforms in supported_platforms: targets = {} for platform,compiler,include,lib in platforms: winCEpath = os.path.join(vc_path, 'ce') if not os.path.isdir(winCEpath): continue if os.path.isdir(os.path.join(winCEpath, 'lib', platform)): bindirs = [os.path.join(winCEpath, 'bin', compiler), os.path.join(winCEpath, 'bin', 'x86_'+compiler)] incdirs = [os.path.join(winCEpath, 'include'), os.path.join(winCEpath, 'atlmfc', 'include'), include] libdirs = [os.path.join(winCEpath, 'lib', platform), os.path.join(winCEpath, 'atlmfc', 'lib', platform), lib] def combine_common(obj, compiler_env): # TODO this is likely broken, remove in waf 2.1 (common_bindirs,_1,_2) = compiler_env return (bindirs + common_bindirs, incdirs, libdirs) targets[platform] = target_compiler(conf, 'msvc', platform, version, 'x86', vsvars, combine_common) if targets: versions[device + ' ' + version] = targets @conf def gather_winphone_targets(conf, versions, version, vc_path, vsvars): #Looking for WinPhone compilers targets = {} for target,realtarget in all_msvc_platforms[::-1]: targets[target] = target_compiler(conf, 'winphone', realtarget, version, target, vsvars) if targets: versions['winphone ' + version] = targets @conf def gather_vswhere_versions(conf, versions): try: import json except ImportError: Logs.error('Visual Studio 2017 detection requires Python 2.6') return prg_path = os.environ.get('ProgramFiles(x86)', os.environ.get('ProgramFiles', 'C:\\Program Files (x86)')) vswhere = os.path.join(prg_path, 'Microsoft Visual Studio', 'Installer', 'vswhere.exe') args = [vswhere, '-products', '*', '-legacy', '-format', 'json'] try: txt = conf.cmd_and_log(args) except Errors.WafError as e: Logs.debug('msvc: vswhere.exe failed %s', e) return if sys.version_info[0] < 3: txt = txt.decode(Utils.console_encoding()) arr = json.loads(txt) arr.sort(key=lambda x: x['installationVersion']) for entry in arr: ver = entry['installationVersion'] ver = str('.'.join(ver.split('.')[:2])) path = str(os.path.abspath(entry['installationPath'])) if os.path.exists(path) and ('msvc %s' % ver) not in versions: conf.gather_msvc_targets(versions, ver, path) @conf def gather_msvc_versions(conf, versions): vc_paths = [] for (v,version,reg) in gather_msvc_detected_versions(): try: try: msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\VC") except OSError: msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\Microsoft Visual C++") path,type = Utils.winreg.QueryValueEx(msvc_version, 'ProductDir') except OSError: try: msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432node\\Microsoft\\VisualStudio\\SxS\\VS7") path,type = Utils.winreg.QueryValueEx(msvc_version, version) except OSError: continue else: vc_paths.append((version, os.path.abspath(str(path)))) continue else: vc_paths.append((version, os.path.abspath(str(path)))) wince_supported_platforms = gather_wince_supported_platforms() for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) vsvars = os.path.join(vs_path, 'Common7', 'Tools', 'vsvars32.bat') if wince_supported_platforms and os.path.isfile(vsvars): conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms) # WP80 works with 11.0Exp and 11.0, both of which resolve to the same vc_path. # Stop after one is found. for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) vsvars = os.path.join(vs_path, 'VC', 'WPSDK', 'WP80', 'vcvarsphoneall.bat') if os.path.isfile(vsvars): conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars) break for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) conf.gather_msvc_targets(versions, version, vc_path) @conf def gather_icl_versions(conf, versions): """ Checks ICL compilers :param versions: list to modify :type versions: list """ version_pattern = re.compile(r'^...?.?\....?.?') try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++') except OSError: try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\C++') except OSError: return index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except OSError: break index += 1 if not version_pattern.match(version): continue targets = {} for target,arch in all_icl_platforms: if target=='intel64': targetDir='EM64T_NATIVE' else: targetDir=target try: Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) icl_version=Utils.winreg.OpenKey(all_versions,version) path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') except OSError: pass else: batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) for target,arch in all_icl_platforms: try: icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') except OSError: continue else: batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) major = version[0:2] versions['intel ' + major] = targets @conf def gather_intel_composer_versions(conf, versions): """ Checks ICL compilers that are part of Intel Composer Suites :param versions: list to modify :type versions: list """ version_pattern = re.compile(r'^...?.?\...?.?.?') try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Suites') except OSError: try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Suites') except OSError: return index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except OSError: break index += 1 if not version_pattern.match(version): continue targets = {} for target,arch in all_icl_platforms: if target=='intel64': targetDir='EM64T_NATIVE' else: targetDir=target try: try: defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir) except OSError: if targetDir == 'EM64T_NATIVE': defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T') else: raise uid,type = Utils.winreg.QueryValueEx(defaults, 'SubKey') Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir) icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++') path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') except OSError: pass else: batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) # The intel compilervar_arch.bat is broken when used with Visual Studio Express 2012 # http://software.intel.com/en-us/forums/topic/328487 compilervars_warning_attr = '_compilervars_warning_key' if version[0:2] == '13' and getattr(conf, compilervars_warning_attr, True): setattr(conf, compilervars_warning_attr, False) patch_url = 'http://software.intel.com/en-us/forums/topic/328487' compilervars_arch = os.path.join(path, 'bin', 'compilervars_arch.bat') for vscomntool in ('VS110COMNTOOLS', 'VS100COMNTOOLS'): if vscomntool in os.environ: vs_express_path = os.environ[vscomntool] + r'..\IDE\VSWinExpress.exe' dev_env_path = os.environ[vscomntool] + r'..\IDE\devenv.exe' if (r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"' in Utils.readf(compilervars_arch) and not os.path.exists(vs_express_path) and not os.path.exists(dev_env_path)): Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ' '(VSWinExpress.exe) but it does not seem to be installed at %r. ' 'The intel command line set up will fail to configure unless the file %r' 'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url)) major = version[0:2] versions['intel ' + major] = targets @conf def detect_msvc(self): return self.setup_msvc(self.get_msvc_versions()) @conf def get_msvc_versions(self): """ :return: platform to compiler configurations :rtype: dict """ dct = Utils.ordered_iter_dict() self.gather_icl_versions(dct) self.gather_intel_composer_versions(dct) self.gather_wsdk_versions(dct) self.gather_msvc_versions(dct) self.gather_vswhere_versions(dct) Logs.debug('msvc: detected versions %r', list(dct.keys())) return dct @conf def find_lt_names_msvc(self, libname, is_static=False): """ Win32/MSVC specific code to glean out information from libtool la files. this function is not attached to the task_gen class. Returns a triplet: (library absolute path, library name without extension, whether the library is static) """ lt_names=[ 'lib%s.la' % libname, '%s.la' % libname, ] for path in self.env.LIBPATH: for la in lt_names: laf=os.path.join(path,la) dll=None if os.path.exists(laf): ltdict = Utils.read_la_file(laf) lt_libdir=None if ltdict.get('libdir', ''): lt_libdir = ltdict['libdir'] if not is_static and ltdict.get('library_names', ''): dllnames=ltdict['library_names'].split() dll=dllnames[0].lower() dll=re.sub(r'\.dll$', '', dll) return (lt_libdir, dll, False) elif ltdict.get('old_library', ''): olib=ltdict['old_library'] if os.path.exists(os.path.join(path,olib)): return (path, olib, True) elif lt_libdir != '' and os.path.exists(os.path.join(lt_libdir,olib)): return (lt_libdir, olib, True) else: return (None, olib, True) else: raise self.errors.WafError('invalid libtool object file: %s' % laf) return (None, None, None) @conf def libname_msvc(self, libname, is_static=False): lib = libname.lower() lib = re.sub(r'\.lib$','',lib) if lib in g_msvc_systemlibs: return lib lib=re.sub('^lib','',lib) if lib == 'm': return None (lt_path, lt_libname, lt_static) = self.find_lt_names_msvc(lib, is_static) if lt_path != None and lt_libname != None: if lt_static: # file existence check has been made by find_lt_names return os.path.join(lt_path,lt_libname) if lt_path != None: _libpaths = [lt_path] + self.env.LIBPATH else: _libpaths = self.env.LIBPATH static_libs=[ 'lib%ss.lib' % lib, 'lib%s.lib' % lib, '%ss.lib' % lib, '%s.lib' %lib, ] dynamic_libs=[ 'lib%s.dll.lib' % lib, 'lib%s.dll.a' % lib, '%s.dll.lib' % lib, '%s.dll.a' % lib, 'lib%s_d.lib' % lib, '%s_d.lib' % lib, '%s.lib' %lib, ] libnames=static_libs if not is_static: libnames=dynamic_libs + static_libs for path in _libpaths: for libn in libnames: if os.path.exists(os.path.join(path, libn)): Logs.debug('msvc: lib found: %s', os.path.join(path,libn)) return re.sub(r'\.lib$', '',libn) #if no lib can be found, just return the libname as msvc expects it self.fatal('The library %r could not be found' % libname) return re.sub(r'\.lib$', '', libname) @conf def check_lib_msvc(self, libname, is_static=False, uselib_store=None): """ Ideally we should be able to place the lib in the right env var, either STLIB or LIB, but we don't distinguish static libs from shared libs. This is ok since msvc doesn't have any special linker flag to select static libs (no env.STLIB_MARKER) """ libn = self.libname_msvc(libname, is_static) if not uselib_store: uselib_store = libname.upper() if False and is_static: # disabled self.env['STLIB_' + uselib_store] = [libn] else: self.env['LIB_' + uselib_store] = [libn] @conf def check_libs_msvc(self, libnames, is_static=False): for libname in Utils.to_list(libnames): self.check_lib_msvc(libname, is_static) def configure(conf): """ Configuration methods to call for detecting msvc """ conf.autodetect(True) conf.find_msvc() conf.msvc_common_flags() conf.cc_load_tools() conf.cxx_load_tools() conf.cc_add_flags() conf.cxx_add_flags() conf.link_add_flags() conf.visual_studio_add_flags() @conf def no_autodetect(conf): conf.env.NO_MSVC_DETECT = 1 configure(conf) @conf def autodetect(conf, arch=False): v = conf.env if v.NO_MSVC_DETECT: return compiler, version, path, includes, libdirs, cpu = conf.detect_msvc() if arch: v.DEST_CPU = cpu v.PATH = path v.INCLUDES = includes v.LIBPATH = libdirs v.MSVC_COMPILER = compiler try: v.MSVC_VERSION = float(version) except ValueError: v.MSVC_VERSION = float(version[:-3]) def _get_prog_names(conf, compiler): if compiler == 'intel': compiler_name = 'ICL' linker_name = 'XILINK' lib_name = 'XILIB' else: # assumes CL.exe compiler_name = 'CL' linker_name = 'LINK' lib_name = 'LIB' return compiler_name, linker_name, lib_name @conf def find_msvc(conf): """Due to path format limitations, limit operation only to native Win32. Yeah it sucks.""" if sys.platform == 'cygwin': conf.fatal('MSVC module does not work under cygwin Python!') # the autodetection is supposed to be performed before entering in this method v = conf.env path = v.PATH compiler = v.MSVC_COMPILER version = v.MSVC_VERSION compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) v.MSVC_MANIFEST = (compiler == 'msvc' and version >= 8) or (compiler == 'wsdk' and version >= 6) or (compiler == 'intel' and version >= 11) # compiler cxx = conf.find_program(compiler_name, var='CXX', path_list=path) # before setting anything, check if the compiler is really msvc env = dict(conf.environ) if path: env.update(PATH = ';'.join(path)) if not conf.cmd_and_log(cxx + ['/nologo', '/help'], env=env): conf.fatal('the msvc compiler could not be identified') # c/c++ compiler v.CC = v.CXX = cxx v.CC_NAME = v.CXX_NAME = 'msvc' # linker if not v.LINK_CXX: conf.find_program(linker_name, path_list=path, errmsg='%s was not found (linker)' % linker_name, var='LINK_CXX') if not v.LINK_CC: v.LINK_CC = v.LINK_CXX # staticlib linker if not v.AR: stliblink = conf.find_program(lib_name, path_list=path, var='AR') if not stliblink: return v.ARFLAGS = ['/nologo'] # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later if v.MSVC_MANIFEST: conf.find_program('MT', path_list=path, var='MT') v.MTFLAGS = ['/nologo'] try: conf.load('winres') except Errors.ConfigurationError: Logs.warn('Resource compiler not found. Compiling resource file is disabled') @conf def visual_studio_add_flags(self): """visual studio flags found in the system environment""" v = self.env if self.environ.get('INCLUDE'): v.prepend_value('INCLUDES', [x for x in self.environ['INCLUDE'].split(';') if x]) # notice the 'S' if self.environ.get('LIB'): v.prepend_value('LIBPATH', [x for x in self.environ['LIB'].split(';') if x]) @conf def msvc_common_flags(conf): """ Setup the flags required for executing the msvc compiler """ v = conf.env v.DEST_BINFMT = 'pe' v.append_value('CFLAGS', ['/nologo']) v.append_value('CXXFLAGS', ['/nologo']) v.append_value('LINKFLAGS', ['/nologo']) v.DEFINES_ST = '/D%s' v.CC_SRC_F = '' v.CC_TGT_F = ['/c', '/Fo'] v.CXX_SRC_F = '' v.CXX_TGT_F = ['/c', '/Fo'] if (v.MSVC_COMPILER == 'msvc' and v.MSVC_VERSION >= 8) or (v.MSVC_COMPILER == 'wsdk' and v.MSVC_VERSION >= 6): v.CC_TGT_F = ['/FC'] + v.CC_TGT_F v.CXX_TGT_F = ['/FC'] + v.CXX_TGT_F v.CPPPATH_ST = '/I%s' # template for adding include paths v.AR_TGT_F = v.CCLNK_TGT_F = v.CXXLNK_TGT_F = '/OUT:' # CRT specific flags v.CFLAGS_CRT_MULTITHREADED = v.CXXFLAGS_CRT_MULTITHREADED = ['/MT'] v.CFLAGS_CRT_MULTITHREADED_DLL = v.CXXFLAGS_CRT_MULTITHREADED_DLL = ['/MD'] v.CFLAGS_CRT_MULTITHREADED_DBG = v.CXXFLAGS_CRT_MULTITHREADED_DBG = ['/MTd'] v.CFLAGS_CRT_MULTITHREADED_DLL_DBG = v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG = ['/MDd'] v.LIB_ST = '%s.lib' v.LIBPATH_ST = '/LIBPATH:%s' v.STLIB_ST = '%s.lib' v.STLIBPATH_ST = '/LIBPATH:%s' if v.MSVC_MANIFEST: v.append_value('LINKFLAGS', ['/MANIFEST']) v.CFLAGS_cshlib = [] v.CXXFLAGS_cxxshlib = [] v.LINKFLAGS_cshlib = v.LINKFLAGS_cxxshlib = ['/DLL'] v.cshlib_PATTERN = v.cxxshlib_PATTERN = '%s.dll' v.implib_PATTERN = '%s.lib' v.IMPLIB_ST = '/IMPLIB:%s' v.LINKFLAGS_cstlib = [] v.cstlib_PATTERN = v.cxxstlib_PATTERN = '%s.lib' v.cprogram_PATTERN = v.cxxprogram_PATTERN = '%s.exe' v.def_PATTERN = '/def:%s' ####################################################################################################### ##### conf above, build below @after_method('apply_link') @feature('c', 'cxx') def apply_flags_msvc(self): """ Add additional flags implied by msvc, such as subsystems and pdb files:: def build(bld): bld.stlib(source='main.c', target='bar', subsystem='gruik') """ if self.env.CC_NAME != 'msvc' or not getattr(self, 'link_task', None): return is_static = isinstance(self.link_task, ccroot.stlink_task) subsystem = getattr(self, 'subsystem', '') if subsystem: subsystem = '/subsystem:%s' % subsystem flags = is_static and 'ARFLAGS' or 'LINKFLAGS' self.env.append_value(flags, subsystem) if not is_static: for f in self.env.LINKFLAGS: d = f.lower() if d[1:] in ('debug', 'debug:full', 'debug:fastlink'): pdbnode = self.link_task.outputs[0].change_ext('.pdb') self.link_task.outputs.append(pdbnode) if getattr(self, 'install_task', None): self.pdb_install_task = self.add_install_files( install_to=self.install_task.install_to, install_from=pdbnode) break @feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib') @after_method('apply_link') def apply_manifest(self): """ Special linker for MSVC with support for embedding manifests into DLL's and executables compiled by Visual Studio 2005 or probably later. Without the manifest file, the binaries are unusable. See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx """ if self.env.CC_NAME == 'msvc' and self.env.MSVC_MANIFEST and getattr(self, 'link_task', None): out_node = self.link_task.outputs[0] man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') self.link_task.outputs.append(man_node) self.env.DO_MANIFEST = True def make_winapp(self, family): append = self.env.append_unique append('DEFINES', 'WINAPI_FAMILY=%s' % family) append('CXXFLAGS', ['/ZW', '/TP']) for lib_path in self.env.LIBPATH: append('CXXFLAGS','/AI%s'%lib_path) @feature('winphoneapp') @after_method('process_use') @after_method('propagate_uselib_vars') def make_winphone_app(self): """ Insert configuration flags for windows phone applications (adds /ZW, /TP...) """ make_winapp(self, 'WINAPI_FAMILY_PHONE_APP') self.env.append_unique('LINKFLAGS', ['/NODEFAULTLIB:ole32.lib', 'PhoneAppModelHost.lib']) @feature('winapp') @after_method('process_use') @after_method('propagate_uselib_vars') def make_windows_app(self): """ Insert configuration flags for windows applications (adds /ZW, /TP...) """ make_winapp(self, 'WINAPI_FAMILY_DESKTOP_APP') ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py0000660000000000000000000000133513573675414021221 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2008-2018 (ita) """ Nasm tool (asm processing) """ import os import waflib.Tools.asm # leave this from waflib.TaskGen import feature @feature('asm') def apply_nasm_vars(self): """provided for compatibility""" self.env.append_value('ASFLAGS', self.to_list(getattr(self, 'nasm_flags', []))) def configure(conf): """ Detect nasm/yasm and set the variable *AS* """ conf.find_program(['nasm', 'yasm'], var='AS') conf.env.AS_TGT_F = ['-o'] conf.env.ASLNK_TGT_F = ['-o'] conf.load('asm') conf.env.ASMPATH_ST = '-I%s' + os.sep txt = conf.cmd_and_log(conf.env.AS + ['--version']) if 'yasm' in txt.lower(): conf.env.ASM_NAME = 'yasm' else: conf.env.ASM_NAME = 'nasm' ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py0000660000000000000000000000064313573675414021720 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2015 (ita) """ Override the build commands to write empty files. This is useful for profiling and evaluating the Python overhead. To use:: def build(bld): ... bld.load('nobuild') """ from waflib import Task def build(bld): def run(self): for x in self.outputs: x.write('') for (name, cls) in Task.classes.items(): cls.run = run ldb-2.0.8/third_party/waf/waflib/Tools/perl.py0000660000000000000000000001064513573675414021231 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # andersg at 0x63.nu 2007 # Thomas Nagy 2016-2018 (ita) """ Support for Perl extensions. A C/C++ compiler is required:: def options(opt): opt.load('compiler_c perl') def configure(conf): conf.load('compiler_c perl') conf.check_perl_version((5,6,0)) conf.check_perl_ext_devel() conf.check_perl_module('Cairo') conf.check_perl_module('Devel::PPPort 4.89') def build(bld): bld( features = 'c cshlib perlext', source = 'Mytest.xs', target = 'Mytest', install_path = '${ARCHDIR_PERL}/auto') bld.install_files('${ARCHDIR_PERL}', 'Mytest.pm') """ import os from waflib import Task, Options, Utils, Errors from waflib.Configure import conf from waflib.TaskGen import extension, feature, before_method @before_method('apply_incpaths', 'apply_link', 'propagate_uselib_vars') @feature('perlext') def init_perlext(self): """ Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the *lib* prefix from library names. """ self.uselib = self.to_list(getattr(self, 'uselib', [])) if not 'PERLEXT' in self.uselib: self.uselib.append('PERLEXT') self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.perlext_PATTERN @extension('.xs') def xsubpp_file(self, node): """ Create :py:class:`waflib.Tools.perl.xsubpp` tasks to process *.xs* files """ outnode = node.change_ext('.c') self.create_task('xsubpp', node, outnode) self.source.append(outnode) class xsubpp(Task.Task): """ Process *.xs* files """ run_str = '${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}' color = 'BLUE' ext_out = ['.h'] @conf def check_perl_version(self, minver=None): """ Check if Perl is installed, and set the variable PERL. minver is supposed to be a tuple """ res = True if minver: cver = '.'.join(map(str,minver)) else: cver = '' self.start_msg('Checking for minimum perl version %s' % cver) perl = self.find_program('perl', var='PERL', value=getattr(Options.options, 'perlbinary', None)) version = self.cmd_and_log(perl + ["-e", 'printf \"%vd\", $^V']) if not version: res = False version = "Unknown" elif not minver is None: ver = tuple(map(int, version.split("."))) if ver < minver: res = False self.end_msg(version, color=res and 'GREEN' or 'YELLOW') return res @conf def check_perl_module(self, module): """ Check if specified perlmodule is installed. The minimum version can be specified by specifying it after modulename like this:: def configure(conf): conf.check_perl_module("Some::Module 2.92") """ cmd = self.env.PERL + ['-e', 'use %s' % module] self.start_msg('perl module %s' % module) try: r = self.cmd_and_log(cmd) except Errors.WafError: self.end_msg(False) return None self.end_msg(r or True) return r @conf def check_perl_ext_devel(self): """ Check for configuration needed to build perl extensions. Sets different xxx_PERLEXT variables in the environment. Also sets the ARCHDIR_PERL variable useful as installation path, which can be overridden by ``--with-perl-archdir`` option. """ env = self.env perl = env.PERL if not perl: self.fatal('find perl first') def cmd_perl_config(s): return perl + ['-MConfig', '-e', 'print \"%s\"' % s] def cfg_str(cfg): return self.cmd_and_log(cmd_perl_config(cfg)) def cfg_lst(cfg): return Utils.to_list(cfg_str(cfg)) def find_xsubpp(): for var in ('privlib', 'vendorlib'): xsubpp = cfg_lst('$Config{%s}/ExtUtils/xsubpp$Config{exe_ext}' % var) if xsubpp and os.path.isfile(xsubpp[0]): return xsubpp return self.find_program('xsubpp') env.LINKFLAGS_PERLEXT = cfg_lst('$Config{lddlflags}') env.INCLUDES_PERLEXT = cfg_lst('$Config{archlib}/CORE') env.CFLAGS_PERLEXT = cfg_lst('$Config{ccflags} $Config{cccdlflags}') env.EXTUTILS_TYPEMAP = cfg_lst('$Config{privlib}/ExtUtils/typemap') env.XSUBPP = find_xsubpp() if not getattr(Options.options, 'perlarchdir', None): env.ARCHDIR_PERL = cfg_str('$Config{sitearch}') else: env.ARCHDIR_PERL = getattr(Options.options, 'perlarchdir') env.perlext_PATTERN = '%s.' + cfg_str('$Config{dlext}') def options(opt): """ Add the ``--with-perl-archdir`` and ``--with-perl-binary`` command-line options. """ opt.add_option('--with-perl-binary', type='string', dest='perlbinary', help = 'Specify alternate perl binary', default=None) opt.add_option('--with-perl-archdir', type='string', dest='perlarchdir', help = 'Specify directory where to install arch specific files', default=None) ldb-2.0.8/third_party/waf/waflib/Tools/python.py0000660000000000000000000005365313573675414021616 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2007-2015 (ita) # Gustavo Carneiro (gjc), 2007 """ Support for Python, detect the headers and libraries and provide *use* variables to link C/C++ programs against them:: def options(opt): opt.load('compiler_c python') def configure(conf): conf.load('compiler_c python') conf.check_python_version((2,4,2)) conf.check_python_headers() def build(bld): bld.program(features='pyembed', source='a.c', target='myprog') bld.shlib(features='pyext', source='b.c', target='mylib') """ import os, sys from waflib import Errors, Logs, Node, Options, Task, Utils from waflib.TaskGen import extension, before_method, after_method, feature from waflib.Configure import conf FRAG = ''' #include #ifdef __cplusplus extern "C" { #endif void Py_Initialize(void); void Py_Finalize(void); #ifdef __cplusplus } #endif int main(int argc, char **argv) { (void)argc; (void)argv; Py_Initialize(); Py_Finalize(); return 0; } ''' """ Piece of C/C++ code used in :py:func:`waflib.Tools.python.check_python_headers` """ INST = ''' import sys, py_compile py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True) ''' """ Piece of Python code used in :py:class:`waflib.Tools.python.pyo` and :py:class:`waflib.Tools.python.pyc` for byte-compiling python files """ DISTUTILS_IMP = ['from distutils.sysconfig import get_config_var, get_python_lib'] @before_method('process_source') @feature('py') def feature_py(self): """ Create tasks to byte-compile .py files and install them, if requested """ self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') install_from = getattr(self, 'install_from', None) if install_from and not isinstance(install_from, Node.Node): install_from = self.path.find_dir(install_from) self.install_from = install_from ver = self.env.PYTHON_VERSION if not ver: self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version') if int(ver.replace('.', '')) > 31: self.install_32 = True @extension('.py') def process_py(self, node): """ Add signature of .py file, so it will be byte-compiled when necessary """ assert(hasattr(self, 'install_path')), 'add features="py" for target "%s" in "%s/wscript".' % (self.target, self.path.nice_path()) self.install_from = getattr(self, 'install_from', None) relative_trick = getattr(self, 'relative_trick', True) if self.install_from: assert isinstance(self.install_from, Node.Node), \ 'add features="py" for target "%s" in "%s/wscript" (%s).' % (self.target, self.path.nice_path(), type(self.install_from)) # where to install the python file if self.install_path: if self.install_from: self.add_install_files(install_to=self.install_path, install_from=node, cwd=self.install_from, relative_trick=relative_trick) else: self.add_install_files(install_to=self.install_path, install_from=node, relative_trick=relative_trick) lst = [] if self.env.PYC: lst.append('pyc') if self.env.PYO: lst.append('pyo') if self.install_path: if self.install_from: target_dir = node.path_from(self.install_from) if relative_trick else node.name pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env) else: target_dir = node.path_from(self.path) if relative_trick else node.name pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env) else: pyd = node.abspath() for ext in lst: if self.env.PYTAG and not self.env.NOPYCACHE: # __pycache__ installation for python 3.2 - PEP 3147 name = node.name[:-3] pyobj = node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s" % (name, self.env.PYTAG, ext)) pyobj.parent.mkdir() else: pyobj = node.change_ext(".%s" % ext) tsk = self.create_task(ext, node, pyobj) tsk.pyd = pyd if self.install_path: self.add_install_files(install_to=os.path.dirname(pyd), install_from=pyobj, cwd=node.parent.get_bld(), relative_trick=relative_trick) class pyc(Task.Task): """ Byte-compiling python files """ color = 'PINK' def __str__(self): node = self.outputs[0] return node.path_from(node.ctx.launch_node()) def run(self): cmd = [Utils.subst_vars('${PYTHON}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd] ret = self.generator.bld.exec_command(cmd) return ret class pyo(Task.Task): """ Byte-compiling python files """ color = 'PINK' def __str__(self): node = self.outputs[0] return node.path_from(node.ctx.launch_node()) def run(self): cmd = [Utils.subst_vars('${PYTHON}', self.env), Utils.subst_vars('${PYFLAGS_OPT}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd] ret = self.generator.bld.exec_command(cmd) return ret @feature('pyext') @before_method('propagate_uselib_vars', 'apply_link') @after_method('apply_bundle') def init_pyext(self): """ Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the *lib* prefix from library names. """ self.uselib = self.to_list(getattr(self, 'uselib', [])) if not 'PYEXT' in self.uselib: self.uselib.append('PYEXT') # override shlib_PATTERN set by the osx module self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN = self.env.pyext_PATTERN self.env.fcshlib_PATTERN = self.env.dshlib_PATTERN = self.env.pyext_PATTERN try: if not self.install_path: return except AttributeError: self.install_path = '${PYTHONARCHDIR}' @feature('pyext') @before_method('apply_link', 'apply_bundle') def set_bundle(self): """Mac-specific pyext extension that enables bundles from c_osx.py""" if Utils.unversioned_sys_platform() == 'darwin': self.mac_bundle = True @before_method('propagate_uselib_vars') @feature('pyembed') def init_pyembed(self): """ Add the PYEMBED variable. """ self.uselib = self.to_list(getattr(self, 'uselib', [])) if not 'PYEMBED' in self.uselib: self.uselib.append('PYEMBED') @conf def get_python_variables(self, variables, imports=None): """ Spawn a new python process to dump configuration variables :param variables: variables to print :type variables: list of string :param imports: one import by element :type imports: list of string :return: the variable values :rtype: list of string """ if not imports: try: imports = self.python_imports except AttributeError: imports = DISTUTILS_IMP program = list(imports) # copy program.append('') for v in variables: program.append("print(repr(%s))" % v) os_env = dict(os.environ) try: del os_env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool except KeyError: pass try: out = self.cmd_and_log(self.env.PYTHON + ['-c', '\n'.join(program)], env=os_env) except Errors.WafError: self.fatal('The distutils module is unusable: install "python-devel"?') self.to_log(out) return_values = [] for s in out.splitlines(): s = s.strip() if not s: continue if s == 'None': return_values.append(None) elif (s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"'): return_values.append(eval(s)) elif s[0].isdigit(): return_values.append(int(s)) else: break return return_values @conf def test_pyembed(self, mode, msg='Testing pyembed configuration'): self.check(header_name='Python.h', define_name='HAVE_PYEMBED', msg=msg, fragment=FRAG, errmsg='Could not build a python embedded interpreter', features='%s %sprogram pyembed' % (mode, mode)) @conf def test_pyext(self, mode, msg='Testing pyext configuration'): self.check(header_name='Python.h', define_name='HAVE_PYEXT', msg=msg, fragment=FRAG, errmsg='Could not build python extensions', features='%s %sshlib pyext' % (mode, mode)) @conf def python_cross_compile(self, features='pyembed pyext'): """ For cross-compilation purposes, it is possible to bypass the normal detection and set the flags that you want: PYTHON_VERSION='3.4' PYTAG='cpython34' pyext_PATTERN="%s.so" PYTHON_LDFLAGS='-lpthread -ldl' waf configure The following variables are used: PYTHON_VERSION required PYTAG required PYTHON_LDFLAGS required pyext_PATTERN required PYTHON_PYEXT_LDFLAGS PYTHON_PYEMBED_LDFLAGS """ features = Utils.to_list(features) if not ('PYTHON_LDFLAGS' in self.environ or 'PYTHON_PYEXT_LDFLAGS' in self.environ or 'PYTHON_PYEMBED_LDFLAGS' in self.environ): return False for x in 'PYTHON_VERSION PYTAG pyext_PATTERN'.split(): if not x in self.environ: self.fatal('Please set %s in the os environment' % x) else: self.env[x] = self.environ[x] xx = self.env.CXX_NAME and 'cxx' or 'c' if 'pyext' in features: flags = self.environ.get('PYTHON_PYEXT_LDFLAGS', self.environ.get('PYTHON_LDFLAGS')) if flags is None: self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required') else: self.parse_flags(flags, 'PYEXT') self.test_pyext(xx) if 'pyembed' in features: flags = self.environ.get('PYTHON_PYEMBED_LDFLAGS', self.environ.get('PYTHON_LDFLAGS')) if flags is None: self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required') else: self.parse_flags(flags, 'PYEMBED') self.test_pyembed(xx) return True @conf def check_python_headers(conf, features='pyembed pyext'): """ Check for headers and libraries necessary to extend or embed python by using the module *distutils*. On success the environment variables xxx_PYEXT and xxx_PYEMBED are added: * PYEXT: for compiling python extensions * PYEMBED: for embedding a python interpreter """ features = Utils.to_list(features) assert ('pyembed' in features) or ('pyext' in features), "check_python_headers features must include 'pyembed' and/or 'pyext'" env = conf.env if not env.CC_NAME and not env.CXX_NAME: conf.fatal('load a compiler first (gcc, g++, ..)') # bypass all the code below for cross-compilation if conf.python_cross_compile(features): return if not env.PYTHON_VERSION: conf.check_python_version() pybin = env.PYTHON if not pybin: conf.fatal('Could not find the python executable') # so we actually do all this for compatibility reasons and for obtaining pyext_PATTERN below v = 'prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split() try: lst = conf.get_python_variables(["get_config_var('%s') or ''" % x for x in v]) except RuntimeError: conf.fatal("Python development headers not found (-v for details).") vals = ['%s = %r' % (x, y) for (x, y) in zip(v, lst)] conf.to_log("Configuration returned from %r:\n%s\n" % (pybin, '\n'.join(vals))) dct = dict(zip(v, lst)) x = 'MACOSX_DEPLOYMENT_TARGET' if dct[x]: env[x] = conf.environ[x] = dct[x] env.pyext_PATTERN = '%s' + dct['SO'] # not a mistake # Try to get pythonX.Y-config num = '.'.join(env.PYTHON_VERSION.split('.')[:2]) conf.find_program([''.join(pybin) + '-config', 'python%s-config' % num, 'python-config-%s' % num, 'python%sm-config' % num], var='PYTHON_CONFIG', msg="python-config", mandatory=False) if env.PYTHON_CONFIG: # check python-config output only once if conf.env.HAVE_PYTHON_H: return # python2.6-config requires 3 runs all_flags = [['--cflags', '--libs', '--ldflags']] if sys.hexversion < 0x2070000: all_flags = [[k] for k in all_flags[0]] xx = env.CXX_NAME and 'cxx' or 'c' if 'pyembed' in features: for flags in all_flags: # Python 3.8 has different flags for pyembed, needs --embed embedflags = flags + ['--embed'] try: conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(embedflags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=embedflags) except conf.errors.ConfigurationError: # However Python < 3.8 doesn't accept --embed, so we need a fallback conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=flags) try: conf.test_pyembed(xx) except conf.errors.ConfigurationError: # python bug 7352 if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']: env.append_unique('LIBPATH_PYEMBED', [dct['LIBDIR']]) conf.test_pyembed(xx) else: raise if 'pyext' in features: for flags in all_flags: conf.check_cfg(msg='Asking python-config for pyext %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEXT', args=flags) try: conf.test_pyext(xx) except conf.errors.ConfigurationError: # python bug 7352 if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']: env.append_unique('LIBPATH_PYEXT', [dct['LIBDIR']]) conf.test_pyext(xx) else: raise conf.define('HAVE_PYTHON_H', 1) return # No python-config, do something else on windows systems all_flags = dct['LDFLAGS'] + ' ' + dct['CFLAGS'] conf.parse_flags(all_flags, 'PYEMBED') all_flags = dct['LDFLAGS'] + ' ' + dct['LDSHARED'] + ' ' + dct['CFLAGS'] conf.parse_flags(all_flags, 'PYEXT') result = None if not dct["LDVERSION"]: dct["LDVERSION"] = env.PYTHON_VERSION # further simplification will be complicated for name in ('python' + dct['LDVERSION'], 'python' + env.PYTHON_VERSION + 'm', 'python' + env.PYTHON_VERSION.replace('.', '')): # LIBPATH_PYEMBED is already set; see if it works. if not result and env.LIBPATH_PYEMBED: path = env.LIBPATH_PYEMBED conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n" % path) result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBPATH_PYEMBED' % name) if not result and dct['LIBDIR']: path = [dct['LIBDIR']] conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n" % path) result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBDIR' % name) if not result and dct['LIBPL']: path = [dct['LIBPL']] conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n") result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in python_LIBPL' % name) if not result: path = [os.path.join(dct['prefix'], "libs")] conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n") result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $prefix/libs' % name) if result: break # do not forget to set LIBPATH_PYEMBED if result: env.LIBPATH_PYEMBED = path env.append_value('LIB_PYEMBED', [name]) else: conf.to_log("\n\n### LIB NOT FOUND\n") # under certain conditions, python extensions must link to # python libraries, not just python embedding programs. if Utils.is_win32 or dct['Py_ENABLE_SHARED']: env.LIBPATH_PYEXT = env.LIBPATH_PYEMBED env.LIB_PYEXT = env.LIB_PYEMBED conf.to_log("Include path for Python extensions (found via distutils module): %r\n" % (dct['INCLUDEPY'],)) env.INCLUDES_PYEXT = [dct['INCLUDEPY']] env.INCLUDES_PYEMBED = [dct['INCLUDEPY']] # Code using the Python API needs to be compiled with -fno-strict-aliasing if env.CC_NAME == 'gcc': env.append_unique('CFLAGS_PYEMBED', ['-fno-strict-aliasing']) env.append_unique('CFLAGS_PYEXT', ['-fno-strict-aliasing']) if env.CXX_NAME == 'gcc': env.append_unique('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing']) env.append_unique('CXXFLAGS_PYEXT', ['-fno-strict-aliasing']) if env.CC_NAME == "msvc": from distutils.msvccompiler import MSVCCompiler dist_compiler = MSVCCompiler() dist_compiler.initialize() env.append_value('CFLAGS_PYEXT', dist_compiler.compile_options) env.append_value('CXXFLAGS_PYEXT', dist_compiler.compile_options) env.append_value('LINKFLAGS_PYEXT', dist_compiler.ldflags_shared) # See if it compiles conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H', uselib='PYEMBED', fragment=FRAG, errmsg='Distutils not installed? Broken python installation? Get python-config now!') @conf def check_python_version(conf, minver=None): """ Check if the python interpreter is found matching a given minimum version. minver should be a tuple, eg. to check for python >= 2.4.2 pass (2,4,2) as minver. If successful, PYTHON_VERSION is defined as 'MAJOR.MINOR' (eg. '2.4') of the actual python version found, and PYTHONDIR and PYTHONARCHDIR are defined, pointing to the site-packages directories appropriate for this python version, where modules/packages/extensions should be installed. :param minver: minimum version :type minver: tuple of int """ assert minver is None or isinstance(minver, tuple) pybin = conf.env.PYTHON if not pybin: conf.fatal('could not find the python executable') # Get python version string cmd = pybin + ['-c', 'import sys\nfor x in sys.version_info: print(str(x))'] Logs.debug('python: Running python command %r', cmd) lines = conf.cmd_and_log(cmd).split() assert len(lines) == 5, "found %r lines, expected 5: %r" % (len(lines), lines) pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4])) # Compare python version with the minimum required result = (minver is None) or (pyver_tuple >= minver) if result: # define useful environment variables pyver = '.'.join([str(x) for x in pyver_tuple[:2]]) conf.env.PYTHON_VERSION = pyver if 'PYTHONDIR' in conf.env: # Check if --pythondir was specified pydir = conf.env.PYTHONDIR elif 'PYTHONDIR' in conf.environ: # Check environment for PYTHONDIR pydir = conf.environ['PYTHONDIR'] else: # Finally, try to guess if Utils.is_win32: (python_LIBDEST, pydir) = conf.get_python_variables( ["get_config_var('LIBDEST') or ''", "get_python_lib(standard_lib=0) or ''"]) else: python_LIBDEST = None (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) if python_LIBDEST is None: if conf.env.LIBDIR: python_LIBDEST = os.path.join(conf.env.LIBDIR, 'python' + pyver) else: python_LIBDEST = os.path.join(conf.env.PREFIX, 'lib', 'python' + pyver) if 'PYTHONARCHDIR' in conf.env: # Check if --pythonarchdir was specified pyarchdir = conf.env.PYTHONARCHDIR elif 'PYTHONARCHDIR' in conf.environ: # Check environment for PYTHONDIR pyarchdir = conf.environ['PYTHONARCHDIR'] else: # Finally, try to guess (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) if not pyarchdir: pyarchdir = pydir if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist conf.define('PYTHONDIR', pydir) conf.define('PYTHONARCHDIR', pyarchdir) conf.env.PYTHONDIR = pydir conf.env.PYTHONARCHDIR = pyarchdir # Feedback pyver_full = '.'.join(map(str, pyver_tuple[:3])) if minver is None: conf.msg('Checking for python version', pyver_full) else: minver_str = '.'.join(map(str, minver)) conf.msg('Checking for python version >= %s' % (minver_str,), pyver_full, color=result and 'GREEN' or 'YELLOW') if not result: conf.fatal('The python version is too old, expecting %r' % (minver,)) PYTHON_MODULE_TEMPLATE = ''' import %s as current_module version = getattr(current_module, '__version__', None) if version is not None: print(str(version)) else: print('unknown version') ''' @conf def check_python_module(conf, module_name, condition=''): """ Check if the selected python interpreter can import the given python module:: def configure(conf): conf.check_python_module('pygccxml') conf.check_python_module('re', condition="ver > num(2, 0, 4) and ver <= num(3, 0, 0)") :param module_name: module :type module_name: string """ msg = "Checking for python module %r" % module_name if condition: msg = '%s (%s)' % (msg, condition) conf.start_msg(msg) try: ret = conf.cmd_and_log(conf.env.PYTHON + ['-c', PYTHON_MODULE_TEMPLATE % module_name]) except Errors.WafError: conf.end_msg(False) conf.fatal('Could not find the python module %r' % module_name) ret = ret.strip() if condition: conf.end_msg(ret) if ret == 'unknown version': conf.fatal('Could not check the %s version' % module_name) from distutils.version import LooseVersion def num(*k): if isinstance(k[0], int): return LooseVersion('.'.join([str(x) for x in k])) else: return LooseVersion(k[0]) d = {'num': num, 'ver': LooseVersion(ret)} ev = eval(condition, {}, d) if not ev: conf.fatal('The %s version does not satisfy the requirements' % module_name) else: if ret == 'unknown version': conf.end_msg(True) else: conf.end_msg(ret) def configure(conf): """ Detect the python interpreter """ v = conf.env if getattr(Options.options, 'pythondir', None): v.PYTHONDIR = Options.options.pythondir if getattr(Options.options, 'pythonarchdir', None): v.PYTHONARCHDIR = Options.options.pythonarchdir if getattr(Options.options, 'nopycache', None): v.NOPYCACHE=Options.options.nopycache if not v.PYTHON: v.PYTHON = [getattr(Options.options, 'python', None) or sys.executable] v.PYTHON = Utils.to_list(v.PYTHON) conf.find_program('python', var='PYTHON') v.PYFLAGS = '' v.PYFLAGS_OPT = '-O' v.PYC = getattr(Options.options, 'pyc', 1) v.PYO = getattr(Options.options, 'pyo', 1) try: v.PYTAG = conf.cmd_and_log(conf.env.PYTHON + ['-c', "import imp;print(imp.get_tag())"]).strip() except Errors.WafError: pass def options(opt): """ Add python-specific options """ pyopt=opt.add_option_group("Python Options") pyopt.add_option('--nopyc', dest = 'pyc', action='store_false', default=1, help = 'Do not install bytecode compiled .pyc files (configuration) [Default:install]') pyopt.add_option('--nopyo', dest='pyo', action='store_false', default=1, help='Do not install optimised compiled .pyo files (configuration) [Default:install]') pyopt.add_option('--nopycache',dest='nopycache', action='store_true', help='Do not use __pycache__ directory to install objects [Default:auto]') pyopt.add_option('--python', dest="python", help='python binary to be used [Default: %s]' % sys.executable) pyopt.add_option('--pythondir', dest='pythondir', help='Installation path for python modules (py, platform-independent .py and .pyc files)') pyopt.add_option('--pythonarchdir', dest='pythonarchdir', help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)') ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py0000660000000000000000000005642113573675414021002 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) """ This tool helps with finding Qt5 tools and libraries, and also provides syntactic sugar for using Qt5 tools. The following snippet illustrates the tool usage:: def options(opt): opt.load('compiler_cxx qt5') def configure(conf): conf.load('compiler_cxx qt5') def build(bld): bld( features = 'qt5 cxx cxxprogram', uselib = 'QT5CORE QT5GUI QT5OPENGL QT5SVG', source = 'main.cpp textures.qrc aboutDialog.ui', target = 'window', ) Here, the UI description and resource files will be processed to generate code. Usage ===== Load the "qt5" tool. You also need to edit your sources accordingly: - the normal way of doing things is to have your C++ files include the .moc file. This is regarded as the best practice (and provides much faster compilations). It also implies that the include paths have beenset properly. - to have the include paths added automatically, use the following:: from waflib.TaskGen import feature, before_method, after_method @feature('cxx') @after_method('process_source') @before_method('apply_incpaths') def add_includes_paths(self): incs = set(self.to_list(getattr(self, 'includes', ''))) for x in self.compiled_tasks: incs.add(x.inputs[0].parent.path_from(self.path)) self.includes = sorted(incs) Note: another tool provides Qt processing that does not require .moc includes, see 'playground/slow_qt/'. A few options (--qt{dir,bin,...}) and environment variables (QT5_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool, tool path selection, etc; please read the source for more info. The detection uses pkg-config on Linux by default. To force static library detection use: QT5_XCOMPILE=1 QT5_FORCE_STATIC=1 waf configure """ from __future__ import with_statement try: from xml.sax import make_parser from xml.sax.handler import ContentHandler except ImportError: has_xml = False ContentHandler = object else: has_xml = True import os, sys, re from waflib.Tools import cxx from waflib import Build, Task, Utils, Options, Errors, Context from waflib.TaskGen import feature, after_method, extension, before_method from waflib.Configure import conf from waflib import Logs MOC_H = ['.h', '.hpp', '.hxx', '.hh'] """ File extensions associated to .moc files """ EXT_RCC = ['.qrc'] """ File extension for the resource (.qrc) files """ EXT_UI = ['.ui'] """ File extension for the user interface (.ui) files """ EXT_QT5 = ['.cpp', '.cc', '.cxx', '.C'] """ File extensions of C++ files that may require a .moc processing """ class qxx(Task.classes['cxx']): """ Each C++ file can have zero or several .moc files to create. They are known only when the files are scanned (preprocessor) To avoid scanning the c++ files each time (parsing C/C++), the results are retrieved from the task cache (bld.node_deps/bld.raw_deps). The moc tasks are also created *dynamically* during the build. """ def __init__(self, *k, **kw): Task.Task.__init__(self, *k, **kw) self.moc_done = 0 def runnable_status(self): """ Compute the task signature to make sure the scanner was executed. Create the moc tasks by using :py:meth:`waflib.Tools.qt5.qxx.add_moc_tasks` (if necessary), then postpone the task execution (there is no need to recompute the task signature). """ if self.moc_done: return Task.Task.runnable_status(self) else: for t in self.run_after: if not t.hasrun: return Task.ASK_LATER self.add_moc_tasks() return Task.Task.runnable_status(self) def create_moc_task(self, h_node, m_node): """ If several libraries use the same classes, it is possible that moc will run several times (Issue 1318) It is not possible to change the file names, but we can assume that the moc transformation will be identical, and the moc tasks can be shared in a global cache. """ try: moc_cache = self.generator.bld.moc_cache except AttributeError: moc_cache = self.generator.bld.moc_cache = {} try: return moc_cache[h_node] except KeyError: tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator) tsk.set_inputs(h_node) tsk.set_outputs(m_node) tsk.env.append_unique('MOC_FLAGS', '-i') if self.generator: self.generator.tasks.append(tsk) # direct injection in the build phase (safe because called from the main thread) gen = self.generator.bld.producer gen.outstanding.append(tsk) gen.total += 1 return tsk else: # remove the signature, it must be recomputed with the moc task delattr(self, 'cache_sig') def add_moc_tasks(self): """ Creates moc tasks by looking in the list of file dependencies ``bld.raw_deps[self.uid()]`` """ node = self.inputs[0] bld = self.generator.bld # skip on uninstall due to generated files if bld.is_install == Build.UNINSTALL: return try: # compute the signature once to know if there is a moc file to create self.signature() except KeyError: # the moc file may be referenced somewhere else pass else: # remove the signature, it must be recomputed with the moc task delattr(self, 'cache_sig') include_nodes = [node.parent] + self.generator.includes_nodes moctasks = [] mocfiles = set() for d in bld.raw_deps.get(self.uid(), []): if not d.endswith('.moc'): continue # process that base.moc only once if d in mocfiles: continue mocfiles.add(d) # find the source associated with the moc file h_node = None base2 = d[:-4] # foo.moc from foo.cpp prefix = node.name[:node.name.rfind('.')] if base2 == prefix: h_node = node else: # this deviates from the standard # if bar.cpp includes foo.moc, then assume it is from foo.h for x in include_nodes: for e in MOC_H: h_node = x.find_node(base2 + e) if h_node: break else: continue break if h_node: m_node = h_node.change_ext('.moc') else: raise Errors.WafError('No source found for %r which is a moc file' % d) # create the moc task task = self.create_moc_task(h_node, m_node) moctasks.append(task) # simple scheduler dependency: run the moc task before others self.run_after.update(set(moctasks)) self.moc_done = 1 class trans_update(Task.Task): """Updates a .ts files from a list of C++ files""" run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}' color = 'BLUE' class XMLHandler(ContentHandler): """ Parses ``.qrc`` files """ def __init__(self): ContentHandler.__init__(self) self.buf = [] self.files = [] def startElement(self, name, attrs): if name == 'file': self.buf = [] def endElement(self, name): if name == 'file': self.files.append(str(''.join(self.buf))) def characters(self, cars): self.buf.append(cars) @extension(*EXT_RCC) def create_rcc_task(self, node): "Creates rcc and cxx tasks for ``.qrc`` files" rcnode = node.change_ext('_rc.%d.cpp' % self.idx) self.create_task('rcc', node, rcnode) cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o')) try: self.compiled_tasks.append(cpptask) except AttributeError: self.compiled_tasks = [cpptask] return cpptask @extension(*EXT_UI) def create_uic_task(self, node): "Create uic tasks for user interface ``.ui`` definition files" """ If UIC file is used in more than one bld, we would have a conflict in parallel execution It is not possible to change the file names (like .self.idx. as for objects) as they have to be referenced by the source file, but we can assume that the transformation will be identical and the tasks can be shared in a global cache. """ try: uic_cache = self.bld.uic_cache except AttributeError: uic_cache = self.bld.uic_cache = {} if node not in uic_cache: uictask = uic_cache[node] = self.create_task('ui5', node) uictask.outputs = [node.parent.find_or_declare(self.env.ui_PATTERN % node.name[:-3])] @extension('.ts') def add_lang(self, node): """Adds all the .ts file into ``self.lang``""" self.lang = self.to_list(getattr(self, 'lang', [])) + [node] @feature('qt5') @before_method('process_source') def process_mocs(self): """ Processes MOC files included in headers:: def build(bld): bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE', moc='foo.h') The build will run moc on foo.h to create moc_foo.n.cpp. The number in the file name is provided to avoid name clashes when the same headers are used by several targets. """ lst = self.to_nodes(getattr(self, 'moc', [])) self.source = self.to_list(getattr(self, 'source', [])) for x in lst: prefix = x.name[:x.name.rfind('.')] # foo.h -> foo moc_target = 'moc_%s.%d.cpp' % (prefix, self.idx) moc_node = x.parent.find_or_declare(moc_target) self.source.append(moc_node) self.create_task('moc', x, moc_node) @feature('qt5') @after_method('apply_link') def apply_qt5(self): """ Adds MOC_FLAGS which may be necessary for moc:: def build(bld): bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE') The additional parameters are: :param lang: list of translation files (\\*.ts) to process :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension :param update: whether to process the C++ files to update the \\*.ts files (use **waf --translate**) :type update: bool :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension """ if getattr(self, 'lang', None): qmtasks = [] for x in self.to_list(self.lang): if isinstance(x, str): x = self.path.find_resource(x + '.ts') qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.%d.qm' % self.idx))) if getattr(self, 'update', None) and Options.options.trans_qt5: cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [ a.inputs[0] for a in self.tasks if a.inputs and a.inputs[0].name.endswith('.ui')] for x in qmtasks: self.create_task('trans_update', cxxnodes, x.inputs) if getattr(self, 'langname', None): qmnodes = [x.outputs[0] for x in qmtasks] rcnode = self.langname if isinstance(rcnode, str): rcnode = self.path.find_or_declare(rcnode + ('.%d.qrc' % self.idx)) t = self.create_task('qm2rcc', qmnodes, rcnode) k = create_rcc_task(self, t.outputs[0]) self.link_task.inputs.append(k.outputs[0]) lst = [] for flag in self.to_list(self.env.CXXFLAGS): if len(flag) < 2: continue f = flag[0:2] if f in ('-D', '-I', '/D', '/I'): if (f[0] == '/'): lst.append('-' + flag[1:]) else: lst.append(flag) self.env.append_value('MOC_FLAGS', lst) @extension(*EXT_QT5) def cxx_hook(self, node): """ Re-maps C++ file extensions to the :py:class:`waflib.Tools.qt5.qxx` task. """ return self.create_compiled_task('qxx', node) class rcc(Task.Task): """ Processes ``.qrc`` files """ color = 'BLUE' run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' ext_out = ['.h'] def rcname(self): return os.path.splitext(self.inputs[0].name)[0] def scan(self): """Parse the *.qrc* files""" if not has_xml: Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') return ([], []) parser = make_parser() curHandler = XMLHandler() parser.setContentHandler(curHandler) with open(self.inputs[0].abspath(), 'r') as f: parser.parse(f) nodes = [] names = [] root = self.inputs[0].parent for x in curHandler.files: nd = root.find_resource(x) if nd: nodes.append(nd) else: names.append(x) return (nodes, names) def quote_flag(self, x): """ Override Task.quote_flag. QT parses the argument files differently than cl.exe and link.exe :param x: flag :type x: string :return: quoted flag :rtype: string """ return x class moc(Task.Task): """ Creates ``.moc`` files """ color = 'BLUE' run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' def quote_flag(self, x): """ Override Task.quote_flag. QT parses the argument files differently than cl.exe and link.exe :param x: flag :type x: string :return: quoted flag :rtype: string """ return x class ui5(Task.Task): """ Processes ``.ui`` files """ color = 'BLUE' run_str = '${QT_UIC} ${SRC} -o ${TGT}' ext_out = ['.h'] class ts2qm(Task.Task): """ Generates ``.qm`` files from ``.ts`` files """ color = 'BLUE' run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' class qm2rcc(Task.Task): """ Generates ``.qrc`` files from ``.qm`` files """ color = 'BLUE' after = 'ts2qm' def run(self): """Create a qrc file including the inputs""" txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) code = '\n\n%s\n\n' % txt self.outputs[0].write(code) def configure(self): """ Besides the configuration options, the environment variable QT5_ROOT may be used to give the location of the qt5 libraries (absolute path). The detection uses the program ``pkg-config`` through :py:func:`waflib.Tools.config_c.check_cfg` """ self.find_qt5_binaries() self.set_qt5_libs_dir() self.set_qt5_libs_to_check() self.set_qt5_defines() self.find_qt5_libraries() self.add_qt5_rpath() self.simplify_qt5_libs() # warn about this during the configuration too if not has_xml: Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') if 'COMPILER_CXX' not in self.env: self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?') # Qt5 may be compiled with '-reduce-relocations' which requires dependent programs to have -fPIE or -fPIC? frag = '#include \nint main(int argc, char **argv) {return 0;}\n' uses = 'QT5CORE QT5WIDGETS QT5GUI' for flag in [[], '-fPIE', '-fPIC', '-std=c++11' , ['-std=c++11', '-fPIE'], ['-std=c++11', '-fPIC']]: msg = 'See if Qt files compile ' if flag: msg += 'with %s' % flag try: self.check(features='qt5 cxx', use=uses, uselib_store='qt5', cxxflags=flag, fragment=frag, msg=msg) except self.errors.ConfigurationError: pass else: break else: self.fatal('Could not build a simple Qt application') # FreeBSD does not add /usr/local/lib and the pkg-config files do not provide it either :-/ if Utils.unversioned_sys_platform() == 'freebsd': frag = '#include \nint main(int argc, char **argv) { QApplication app(argc, argv); return NULL != (void*) (&app);}\n' try: self.check(features='qt5 cxx cxxprogram', use=uses, fragment=frag, msg='Can we link Qt programs on FreeBSD directly?') except self.errors.ConfigurationError: self.check(features='qt5 cxx cxxprogram', use=uses, uselib_store='qt5', libpath='/usr/local/lib', fragment=frag, msg='Is /usr/local/lib required?') @conf def find_qt5_binaries(self): """ Detects Qt programs such as qmake, moc, uic, lrelease """ env = self.env opt = Options.options qtdir = getattr(opt, 'qtdir', '') qtbin = getattr(opt, 'qtbin', '') paths = [] if qtdir: qtbin = os.path.join(qtdir, 'bin') # the qt directory has been given from QT5_ROOT - deduce the qt binary path if not qtdir: qtdir = self.environ.get('QT5_ROOT', '') qtbin = self.environ.get('QT5_BIN') or os.path.join(qtdir, 'bin') if qtbin: paths = [qtbin] # no qtdir, look in the path and in /usr/local/Trolltech if not qtdir: paths = self.environ.get('PATH', '').split(os.pathsep) paths.extend(['/usr/share/qt5/bin', '/usr/local/lib/qt5/bin']) try: lst = Utils.listdir('/usr/local/Trolltech/') except OSError: pass else: if lst: lst.sort() lst.reverse() # keep the highest version qtdir = '/usr/local/Trolltech/%s/' % lst[0] qtbin = os.path.join(qtdir, 'bin') paths.append(qtbin) # at the end, try to find qmake in the paths given # keep the one with the highest version cand = None prev_ver = ['5', '0', '0'] for qmk in ('qmake-qt5', 'qmake5', 'qmake'): try: qmake = self.find_program(qmk, path_list=paths) except self.errors.ConfigurationError: pass else: try: version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip() except self.errors.WafError: pass else: if version: new_ver = version.split('.') if new_ver > prev_ver: cand = qmake prev_ver = new_ver # qmake could not be found easily, rely on qtchooser if not cand: try: self.find_program('qtchooser') except self.errors.ConfigurationError: pass else: cmd = self.env.QTCHOOSER + ['-qt=5', '-run-tool=qmake'] try: version = self.cmd_and_log(cmd + ['-query', 'QT_VERSION']) except self.errors.WafError: pass else: cand = cmd if cand: self.env.QMAKE = cand else: self.fatal('Could not find qmake for qt5') self.env.QT_HOST_BINS = qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_HOST_BINS']).strip() paths.insert(0, qtbin) def find_bin(lst, var): if var in env: return for f in lst: try: ret = self.find_program(f, path_list=paths) except self.errors.ConfigurationError: pass else: env[var]=ret break find_bin(['uic-qt5', 'uic'], 'QT_UIC') if not env.QT_UIC: self.fatal('cannot find the uic compiler for qt5') self.start_msg('Checking for uic version') uicver = self.cmd_and_log(env.QT_UIC + ['-version'], output=Context.BOTH) uicver = ''.join(uicver).strip() uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '') self.end_msg(uicver) if uicver.find(' 3.') != -1 or uicver.find(' 4.') != -1: self.fatal('this uic compiler is for qt3 or qt4, add uic for qt5 to your path') find_bin(['moc-qt5', 'moc'], 'QT_MOC') find_bin(['rcc-qt5', 'rcc'], 'QT_RCC') find_bin(['lrelease-qt5', 'lrelease'], 'QT_LRELEASE') find_bin(['lupdate-qt5', 'lupdate'], 'QT_LUPDATE') env.UIC_ST = '%s -o %s' env.MOC_ST = '-o' env.ui_PATTERN = 'ui_%s.h' env.QT_LRELEASE_FLAGS = ['-silent'] env.MOCCPPPATH_ST = '-I%s' env.MOCDEFINES_ST = '-D%s' @conf def set_qt5_libs_dir(self): env = self.env qtlibs = getattr(Options.options, 'qtlibs', None) or self.environ.get('QT5_LIBDIR') if not qtlibs: try: qtlibs = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip() except Errors.WafError: qtdir = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() qtlibs = os.path.join(qtdir, 'lib') self.msg('Found the Qt5 libraries in', qtlibs) env.QTLIBS = qtlibs @conf def find_single_qt5_lib(self, name, uselib, qtlibs, qtincludes, force_static): env = self.env if force_static: exts = ('.a', '.lib') prefix = 'STLIB' else: exts = ('.so', '.lib') prefix = 'LIB' def lib_names(): for x in exts: for k in ('', '5') if Utils.is_win32 else ['']: for p in ('lib', ''): yield (p, name, k, x) for tup in lib_names(): k = ''.join(tup) path = os.path.join(qtlibs, k) if os.path.exists(path): if env.DEST_OS == 'win32': libval = ''.join(tup[:-1]) else: libval = name env.append_unique(prefix + '_' + uselib, libval) env.append_unique('%sPATH_%s' % (prefix, uselib), qtlibs) env.append_unique('INCLUDES_' + uselib, qtincludes) env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, name.replace('Qt5', 'Qt'))) return k return False @conf def find_qt5_libraries(self): env = self.env qtincludes = self.environ.get('QT5_INCLUDES') or self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip() force_static = self.environ.get('QT5_FORCE_STATIC') try: if self.environ.get('QT5_XCOMPILE'): self.fatal('QT5_XCOMPILE Disables pkg-config detection') self.check_cfg(atleast_pkgconfig_version='0.1') except self.errors.ConfigurationError: for i in self.qt5_vars: uselib = i.upper() if Utils.unversioned_sys_platform() == 'darwin': # Since at least qt 4.7.3 each library locates in separate directory fwk = i.replace('Qt5', 'Qt') frameworkName = fwk + '.framework' qtDynamicLib = os.path.join(env.QTLIBS, frameworkName, fwk) if os.path.exists(qtDynamicLib): env.append_unique('FRAMEWORK_' + uselib, fwk) env.append_unique('FRAMEWORKPATH_' + uselib, env.QTLIBS) self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') else: self.msg('Checking for %s' % i, False, 'YELLOW') env.append_unique('INCLUDES_' + uselib, os.path.join(env.QTLIBS, frameworkName, 'Headers')) else: ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, force_static) if not force_static and not ret: ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, True) self.msg('Checking for %s' % i, ret, 'GREEN' if ret else 'YELLOW') else: path = '%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib' % ( self.environ.get('PKG_CONFIG_PATH', ''), env.QTLIBS, env.QTLIBS) for i in self.qt5_vars: self.check_cfg(package=i, args='--cflags --libs', mandatory=False, force_static=force_static, pkg_config_path=path) @conf def simplify_qt5_libs(self): """ Since library paths make really long command-lines, and since everything depends on qtcore, remove the qtcore ones from qtgui, etc """ env = self.env def process_lib(vars_, coreval): for d in vars_: var = d.upper() if var == 'QTCORE': continue value = env['LIBPATH_'+var] if value: core = env[coreval] accu = [] for lib in value: if lib in core: continue accu.append(lib) env['LIBPATH_'+var] = accu process_lib(self.qt5_vars, 'LIBPATH_QTCORE') @conf def add_qt5_rpath(self): """ Defines rpath entries for Qt libraries """ env = self.env if getattr(Options.options, 'want_rpath', False): def process_rpath(vars_, coreval): for d in vars_: var = d.upper() value = env['LIBPATH_' + var] if value: core = env[coreval] accu = [] for lib in value: if var != 'QTCORE': if lib in core: continue accu.append('-Wl,--rpath='+lib) env['RPATH_' + var] = accu process_rpath(self.qt5_vars, 'LIBPATH_QTCORE') @conf def set_qt5_libs_to_check(self): self.qt5_vars = Utils.to_list(getattr(self, 'qt5_vars', [])) if not self.qt5_vars: dirlst = Utils.listdir(self.env.QTLIBS) pat = self.env.cxxshlib_PATTERN if Utils.is_win32: pat = pat.replace('.dll', '.lib') if self.environ.get('QT5_FORCE_STATIC'): pat = self.env.cxxstlib_PATTERN if Utils.unversioned_sys_platform() == 'darwin': pat = r"%s\.framework" re_qt = re.compile(pat%'Qt5?(?P.*)'+'$') for x in dirlst: m = re_qt.match(x) if m: self.qt5_vars.append("Qt5%s" % m.group('name')) if not self.qt5_vars: self.fatal('cannot find any Qt5 library (%r)' % self.env.QTLIBS) qtextralibs = getattr(Options.options, 'qtextralibs', None) if qtextralibs: self.qt5_vars.extend(qtextralibs.split(',')) @conf def set_qt5_defines(self): if sys.platform != 'win32': return for x in self.qt5_vars: y=x.replace('Qt5', 'Qt')[2:].upper() self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y) def options(opt): """ Command-line options """ opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries') for i in 'qtdir qtbin qtlibs'.split(): opt.add_option('--'+i, type='string', default='', dest=i) opt.add_option('--translate', action='store_true', help='collect translation strings', dest='trans_qt5', default=False) opt.add_option('--qtextralibs', type='string', default='', dest='qtextralibs', help='additional qt libraries on the system to add to default ones, comma separated') ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py0000660000000000000000000001271313573675414021246 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # daniel.svensson at purplescout.se 2008 # Thomas Nagy 2016-2018 (ita) """ Support for Ruby extensions. A C/C++ compiler is required:: def options(opt): opt.load('compiler_c ruby') def configure(conf): conf.load('compiler_c ruby') conf.check_ruby_version((1,8,0)) conf.check_ruby_ext_devel() conf.check_ruby_module('libxml') def build(bld): bld( features = 'c cshlib rubyext', source = 'rb_mytest.c', target = 'mytest_ext', install_path = '${ARCHDIR_RUBY}') bld.install_files('${LIBDIR_RUBY}', 'Mytest.rb') """ import os from waflib import Errors, Options, Task, Utils from waflib.TaskGen import before_method, feature, extension from waflib.Configure import conf @feature('rubyext') @before_method('apply_incpaths', 'process_source', 'apply_bundle', 'apply_link') def init_rubyext(self): """ Add required variables for ruby extensions """ self.install_path = '${ARCHDIR_RUBY}' self.uselib = self.to_list(getattr(self, 'uselib', '')) if not 'RUBY' in self.uselib: self.uselib.append('RUBY') if not 'RUBYEXT' in self.uselib: self.uselib.append('RUBYEXT') @feature('rubyext') @before_method('apply_link', 'propagate_uselib_vars') def apply_ruby_so_name(self): """ Strip the *lib* prefix from ruby extensions """ self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.rubyext_PATTERN @conf def check_ruby_version(self, minver=()): """ Checks if ruby is installed. If installed the variable RUBY will be set in environment. The ruby binary can be overridden by ``--with-ruby-binary`` command-line option. """ ruby = self.find_program('ruby', var='RUBY', value=Options.options.rubybinary) try: version = self.cmd_and_log(ruby + ['-e', 'puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip() except Errors.WafError: self.fatal('could not determine ruby version') self.env.RUBY_VERSION = version try: ver = tuple(map(int, version.split('.'))) except Errors.WafError: self.fatal('unsupported ruby version %r' % version) cver = '' if minver: cver = '> ' + '.'.join(str(x) for x in minver) if ver < minver: self.fatal('ruby is too old %r' % ver) self.msg('Checking for ruby version %s' % cver, version) @conf def check_ruby_ext_devel(self): """ Check if a ruby extension can be created """ if not self.env.RUBY: self.fatal('ruby detection is required first') if not self.env.CC_NAME and not self.env.CXX_NAME: self.fatal('load a c/c++ compiler first') version = tuple(map(int, self.env.RUBY_VERSION.split("."))) def read_out(cmd): return Utils.to_list(self.cmd_and_log(self.env.RUBY + ['-rrbconfig', '-e', cmd])) def read_config(key): return read_out('puts RbConfig::CONFIG[%r]' % key) cpppath = archdir = read_config('archdir') if version >= (1, 9, 0): ruby_hdrdir = read_config('rubyhdrdir') cpppath += ruby_hdrdir if version >= (2, 0, 0): cpppath += read_config('rubyarchhdrdir') cpppath += [os.path.join(ruby_hdrdir[0], read_config('arch')[0])] self.check(header_name='ruby.h', includes=cpppath, errmsg='could not find ruby header file', link_header_test=False) self.env.LIBPATH_RUBYEXT = read_config('libdir') self.env.LIBPATH_RUBYEXT += archdir self.env.INCLUDES_RUBYEXT = cpppath self.env.CFLAGS_RUBYEXT = read_config('CCDLFLAGS') self.env.rubyext_PATTERN = '%s.' + read_config('DLEXT')[0] # ok this is really stupid, but the command and flags are combined. # so we try to find the first argument... flags = read_config('LDSHARED') while flags and flags[0][0] != '-': flags = flags[1:] # we also want to strip out the deprecated ppc flags if len(flags) > 1 and flags[1] == "ppc": flags = flags[2:] self.env.LINKFLAGS_RUBYEXT = flags self.env.LINKFLAGS_RUBYEXT += read_config('LIBS') self.env.LINKFLAGS_RUBYEXT += read_config('LIBRUBYARG_SHARED') if Options.options.rubyarchdir: self.env.ARCHDIR_RUBY = Options.options.rubyarchdir else: self.env.ARCHDIR_RUBY = read_config('sitearchdir')[0] if Options.options.rubylibdir: self.env.LIBDIR_RUBY = Options.options.rubylibdir else: self.env.LIBDIR_RUBY = read_config('sitelibdir')[0] @conf def check_ruby_module(self, module_name): """ Check if the selected ruby interpreter can require the given ruby module:: def configure(conf): conf.check_ruby_module('libxml') :param module_name: module :type module_name: string """ self.start_msg('Ruby module %s' % module_name) try: self.cmd_and_log(self.env.RUBY + ['-e', 'require \'%s\';puts 1' % module_name]) except Errors.WafError: self.end_msg(False) self.fatal('Could not find the ruby module %r' % module_name) self.end_msg(True) @extension('.rb') def process(self, node): return self.create_task('run_ruby', node) class run_ruby(Task.Task): """ Task to run ruby files detected by file extension .rb:: def options(opt): opt.load('ruby') def configure(ctx): ctx.check_ruby_version() def build(bld): bld.env.RBFLAGS = '-e puts "hello world"' bld(source='a_ruby_file.rb') """ run_str = '${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}' def options(opt): """ Add the ``--with-ruby-archdir``, ``--with-ruby-libdir`` and ``--with-ruby-binary`` options """ opt.add_option('--with-ruby-archdir', type='string', dest='rubyarchdir', help='Specify directory where to install arch specific files') opt.add_option('--with-ruby-libdir', type='string', dest='rubylibdir', help='Specify alternate ruby library path') opt.add_option('--with-ruby-binary', type='string', dest='rubybinary', help='Specify alternate ruby binary') ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py0000660000000000000000000000272313573675414021400 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) # Ralf Habacker, 2006 (rh) from waflib import Errors from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_scc(conf): """ Detects the Sun C compiler """ v = conf.env cc = conf.find_program('cc', var='CC') try: conf.cmd_and_log(cc + ['-flags']) except Errors.WafError: conf.fatal('%r is not a Sun compiler' % cc) v.CC_NAME = 'sun' conf.get_suncc_version(cc) @conf def scc_common_flags(conf): """ Flags required for executing the sun C compiler """ v = conf.env v.CC_SRC_F = [] v.CC_TGT_F = ['-c', '-o', ''] if not v.LINK_CC: v.LINK_CC = v.CC v.CCLNK_SRC_F = '' v.CCLNK_TGT_F = ['-o', ''] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.SONAME_ST = '-Wl,-h,%s' v.SHLIB_MARKER = '-Bdynamic' v.STLIB_MARKER = '-Bstatic' v.cprogram_PATTERN = '%s' v.CFLAGS_cshlib = ['-xcode=pic32', '-DPIC'] v.LINKFLAGS_cshlib = ['-G'] v.cshlib_PATTERN = 'lib%s.so' v.LINKFLAGS_cstlib = ['-Bstatic'] v.cstlib_PATTERN = 'lib%s.a' def configure(conf): conf.find_scc() conf.find_ar() conf.scc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py0000660000000000000000000000274713573675414021623 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) # Ralf Habacker, 2006 (rh) from waflib import Errors from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_sxx(conf): """ Detects the sun C++ compiler """ v = conf.env cc = conf.find_program(['CC', 'c++'], var='CXX') try: conf.cmd_and_log(cc + ['-flags']) except Errors.WafError: conf.fatal('%r is not a Sun compiler' % cc) v.CXX_NAME = 'sun' conf.get_suncc_version(cc) @conf def sxx_common_flags(conf): """ Flags required for executing the sun C++ compiler """ v = conf.env v.CXX_SRC_F = [] v.CXX_TGT_F = ['-c', '-o', ''] if not v.LINK_CXX: v.LINK_CXX = v.CXX v.CXXLNK_SRC_F = [] v.CXXLNK_TGT_F = ['-o', ''] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.SONAME_ST = '-Wl,-h,%s' v.SHLIB_MARKER = '-Bdynamic' v.STLIB_MARKER = '-Bstatic' v.cxxprogram_PATTERN = '%s' v.CXXFLAGS_cxxshlib = ['-xcode=pic32', '-DPIC'] v.LINKFLAGS_cxxshlib = ['-G'] v.cxxshlib_PATTERN = 'lib%s.so' v.LINKFLAGS_cxxstlib = ['-Bstatic'] v.cxxstlib_PATTERN = 'lib%s.a' def configure(conf): conf.find_sxx() conf.find_ar() conf.sxx_common_flags() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/tex.py0000660000000000000000000003573113573675414021072 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) """ TeX/LaTeX/PDFLaTeX/XeLaTeX support Example:: def configure(conf): conf.load('tex') if not conf.env.LATEX: conf.fatal('The program LaTex is required') def build(bld): bld( features = 'tex', type = 'latex', # pdflatex or xelatex source = 'document.ltx', # mandatory, the source outs = 'ps', # 'pdf' or 'ps pdf' deps = 'crossreferencing.lst', # to give dependencies directly prompt = 1, # 0 for the batch mode ) Notes: - To configure with a special program, use:: $ PDFLATEX=luatex waf configure - This tool does not use the target attribute of the task generator (``bld(target=...)``); the target file name is built from the source base name and the output type(s) """ import os, re from waflib import Utils, Task, Errors, Logs, Node from waflib.TaskGen import feature, before_method re_bibunit = re.compile(r'\\(?Pputbib)\[(?P[^\[\]]*)\]',re.M) def bibunitscan(self): """ Parses TeX inputs and try to find the *bibunit* file dependencies :return: list of bibunit files :rtype: list of :py:class:`waflib.Node.Node` """ node = self.inputs[0] nodes = [] if not node: return nodes code = node.read() for match in re_bibunit.finditer(code): path = match.group('file') if path: found = None for k in ('', '.bib'): # add another loop for the tex include paths? Logs.debug('tex: trying %s%s', path, k) fi = node.parent.find_resource(path + k) if fi: found = True nodes.append(fi) # no break if not found: Logs.debug('tex: could not find %s', path) Logs.debug('tex: found the following bibunit files: %s', nodes) return nodes exts_deps_tex = ['', '.ltx', '.tex', '.bib', '.pdf', '.png', '.eps', '.ps', '.sty'] """List of typical file extensions included in latex files""" exts_tex = ['.ltx', '.tex'] """List of typical file extensions that contain latex""" re_tex = re.compile(r'\\(?Pusepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P[^{}]*)}',re.M) """Regexp for expressions that may include latex files""" g_bibtex_re = re.compile('bibdata', re.M) """Regexp for bibtex files""" g_glossaries_re = re.compile('\\@newglossary', re.M) """Regexp for expressions that create glossaries""" class tex(Task.Task): """ Compiles a tex/latex file. .. inheritance-diagram:: waflib.Tools.tex.latex waflib.Tools.tex.xelatex waflib.Tools.tex.pdflatex """ bibtex_fun, _ = Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}', shell=False) bibtex_fun.__doc__ = """ Execute the program **bibtex** """ makeindex_fun, _ = Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}', shell=False) makeindex_fun.__doc__ = """ Execute the program **makeindex** """ makeglossaries_fun, _ = Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}', shell=False) makeglossaries_fun.__doc__ = """ Execute the program **makeglossaries** """ def exec_command(self, cmd, **kw): """ Executes TeX commands without buffering (latex may prompt for inputs) :return: the return code :rtype: int """ if self.env.PROMPT_LATEX: # capture the outputs in configuration tests kw['stdout'] = kw['stderr'] = None return super(tex, self).exec_command(cmd, **kw) def scan_aux(self, node): """ Recursive regex-based scanner that finds included auxiliary files. """ nodes = [node] re_aux = re.compile(r'\\@input{(?P[^{}]*)}', re.M) def parse_node(node): code = node.read() for match in re_aux.finditer(code): path = match.group('file') found = node.parent.find_or_declare(path) if found and found not in nodes: Logs.debug('tex: found aux node %r', found) nodes.append(found) parse_node(found) parse_node(node) return nodes def scan(self): """ Recursive regex-based scanner that finds latex dependencies. It uses :py:attr:`waflib.Tools.tex.re_tex` Depending on your needs you might want: * to change re_tex:: from waflib.Tools import tex tex.re_tex = myregex * or to change the method scan from the latex tasks:: from waflib.Task import classes classes['latex'].scan = myscanfunction """ node = self.inputs[0] nodes = [] names = [] seen = [] if not node: return (nodes, names) def parse_node(node): if node in seen: return seen.append(node) code = node.read() for match in re_tex.finditer(code): multibib = match.group('type') if multibib and multibib.startswith('bibliography'): multibib = multibib[len('bibliography'):] if multibib.startswith('style'): continue else: multibib = None for path in match.group('file').split(','): if path: add_name = True found = None for k in exts_deps_tex: # issue 1067, scan in all texinputs folders for up in self.texinputs_nodes: Logs.debug('tex: trying %s%s', path, k) found = up.find_resource(path + k) if found: break for tsk in self.generator.tasks: if not found or found in tsk.outputs: break else: nodes.append(found) add_name = False for ext in exts_tex: if found.name.endswith(ext): parse_node(found) break # multibib stuff if found and multibib and found.name.endswith('.bib'): try: self.multibibs.append(found) except AttributeError: self.multibibs = [found] # no break, people are crazy if add_name: names.append(path) parse_node(node) for x in nodes: x.parent.get_bld().mkdir() Logs.debug("tex: found the following : %s and names %s", nodes, names) return (nodes, names) def check_status(self, msg, retcode): """ Checks an exit status and raise an error with a particular message :param msg: message to display if the code is non-zero :type msg: string :param retcode: condition :type retcode: boolean """ if retcode != 0: raise Errors.WafError('%r command exit status %r' % (msg, retcode)) def info(self, *k, **kw): try: info = self.generator.bld.conf.logger.info except AttributeError: info = Logs.info info(*k, **kw) def bibfile(self): """ Parses *.aux* files to find bibfiles to process. If present, execute :py:meth:`waflib.Tools.tex.tex.bibtex_fun` """ for aux_node in self.aux_nodes: try: ct = aux_node.read() except EnvironmentError: Logs.error('Error reading %s: %r', aux_node.abspath()) continue if g_bibtex_re.findall(ct): self.info('calling bibtex') self.env.env = {} self.env.env.update(os.environ) self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) self.env.SRCFILE = aux_node.name[:-4] self.check_status('error when calling bibtex', self.bibtex_fun()) for node in getattr(self, 'multibibs', []): self.env.env = {} self.env.env.update(os.environ) self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) self.env.SRCFILE = node.name[:-4] self.check_status('error when calling bibtex', self.bibtex_fun()) def bibunits(self): """ Parses *.aux* file to find bibunit files. If there are bibunit files, runs :py:meth:`waflib.Tools.tex.tex.bibtex_fun`. """ try: bibunits = bibunitscan(self) except OSError: Logs.error('error bibunitscan') else: if bibunits: fn = ['bu' + str(i) for i in range(1, len(bibunits) + 1)] if fn: self.info('calling bibtex on bibunits') for f in fn: self.env.env = {'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()} self.env.SRCFILE = f self.check_status('error when calling bibtex', self.bibtex_fun()) def makeindex(self): """ Searches the filesystem for *.idx* files to process. If present, runs :py:meth:`waflib.Tools.tex.tex.makeindex_fun` """ self.idx_node = self.inputs[0].change_ext('.idx') try: idx_path = self.idx_node.abspath() os.stat(idx_path) except OSError: self.info('index file %s absent, not calling makeindex', idx_path) else: self.info('calling makeindex') self.env.SRCFILE = self.idx_node.name self.env.env = {} self.check_status('error when calling makeindex %s' % idx_path, self.makeindex_fun()) def bibtopic(self): """ Lists additional .aux files from the bibtopic package """ p = self.inputs[0].parent.get_bld() if os.path.exists(os.path.join(p.abspath(), 'btaux.aux')): self.aux_nodes += p.ant_glob('*[0-9].aux') def makeglossaries(self): """ Lists additional glossaries from .aux files. If present, runs the makeglossaries program. """ src_file = self.inputs[0].abspath() base_file = os.path.basename(src_file) base, _ = os.path.splitext(base_file) for aux_node in self.aux_nodes: try: ct = aux_node.read() except EnvironmentError: Logs.error('Error reading %s: %r', aux_node.abspath()) continue if g_glossaries_re.findall(ct): if not self.env.MAKEGLOSSARIES: raise Errors.WafError("The program 'makeglossaries' is missing!") Logs.warn('calling makeglossaries') self.env.SRCFILE = base self.check_status('error when calling makeglossaries %s' % base, self.makeglossaries_fun()) return def texinputs(self): """ Returns the list of texinput nodes as a string suitable for the TEXINPUTS environment variables :rtype: string """ return os.pathsep.join([k.abspath() for k in self.texinputs_nodes]) + os.pathsep def run(self): """ Runs the whole TeX build process Multiple passes are required depending on the usage of cross-references, bibliographies, glossaries, indexes and additional contents The appropriate TeX compiler is called until the *.aux* files stop changing. """ env = self.env if not env.PROMPT_LATEX: env.append_value('LATEXFLAGS', '-interaction=batchmode') env.append_value('PDFLATEXFLAGS', '-interaction=batchmode') env.append_value('XELATEXFLAGS', '-interaction=batchmode') # important, set the cwd for everybody self.cwd = self.inputs[0].parent.get_bld() self.info('first pass on %s', self.__class__.__name__) # Hash .aux files before even calling the LaTeX compiler cur_hash = self.hash_aux_nodes() self.call_latex() # Find the .aux files again since bibtex processing can require it self.hash_aux_nodes() self.bibtopic() self.bibfile() self.bibunits() self.makeindex() self.makeglossaries() for i in range(10): # There is no need to call latex again if the .aux hash value has not changed prev_hash = cur_hash cur_hash = self.hash_aux_nodes() if not cur_hash: Logs.error('No aux.h to process') if cur_hash and cur_hash == prev_hash: break # run the command self.info('calling %s', self.__class__.__name__) self.call_latex() def hash_aux_nodes(self): """ Returns a hash of the .aux file contents :rtype: string or bytes """ try: self.aux_nodes except AttributeError: try: self.aux_nodes = self.scan_aux(self.inputs[0].change_ext('.aux')) except IOError: return None return Utils.h_list([Utils.h_file(x.abspath()) for x in self.aux_nodes]) def call_latex(self): """ Runs the TeX compiler once """ self.env.env = {} self.env.env.update(os.environ) self.env.env.update({'TEXINPUTS': self.texinputs()}) self.env.SRCFILE = self.inputs[0].abspath() self.check_status('error when calling latex', self.texfun()) class latex(tex): "Compiles LaTeX files" texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False) class pdflatex(tex): "Compiles PdfLaTeX files" texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False) class xelatex(tex): "XeLaTeX files" texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False) class dvips(Task.Task): "Converts dvi files to postscript" run_str = '${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}' color = 'BLUE' after = ['latex', 'pdflatex', 'xelatex'] class dvipdf(Task.Task): "Converts dvi files to pdf" run_str = '${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}' color = 'BLUE' after = ['latex', 'pdflatex', 'xelatex'] class pdf2ps(Task.Task): "Converts pdf files to postscript" run_str = '${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}' color = 'BLUE' after = ['latex', 'pdflatex', 'xelatex'] @feature('tex') @before_method('process_source') def apply_tex(self): """ Creates :py:class:`waflib.Tools.tex.tex` objects, and dvips/dvipdf/pdf2ps tasks if necessary (outs='ps', etc). """ if not getattr(self, 'type', None) in ('latex', 'pdflatex', 'xelatex'): self.type = 'pdflatex' outs = Utils.to_list(getattr(self, 'outs', [])) # prompt for incomplete files (else the batchmode is used) try: self.generator.bld.conf except AttributeError: default_prompt = False else: default_prompt = True self.env.PROMPT_LATEX = getattr(self, 'prompt', default_prompt) deps_lst = [] if getattr(self, 'deps', None): deps = self.to_list(self.deps) for dep in deps: if isinstance(dep, str): n = self.path.find_resource(dep) if not n: self.bld.fatal('Could not find %r for %r' % (dep, self)) if not n in deps_lst: deps_lst.append(n) elif isinstance(dep, Node.Node): deps_lst.append(dep) for node in self.to_nodes(self.source): if self.type == 'latex': task = self.create_task('latex', node, node.change_ext('.dvi')) elif self.type == 'pdflatex': task = self.create_task('pdflatex', node, node.change_ext('.pdf')) elif self.type == 'xelatex': task = self.create_task('xelatex', node, node.change_ext('.pdf')) task.env = self.env # add the manual dependencies if deps_lst: for n in deps_lst: if not n in task.dep_nodes: task.dep_nodes.append(n) # texinputs is a nasty beast if hasattr(self, 'texinputs_nodes'): task.texinputs_nodes = self.texinputs_nodes else: task.texinputs_nodes = [node.parent, node.parent.get_bld(), self.path, self.path.get_bld()] lst = os.environ.get('TEXINPUTS', '') if self.env.TEXINPUTS: lst += os.pathsep + self.env.TEXINPUTS if lst: lst = lst.split(os.pathsep) for x in lst: if x: if os.path.isabs(x): p = self.bld.root.find_node(x) if p: task.texinputs_nodes.append(p) else: Logs.error('Invalid TEXINPUTS folder %s', x) else: Logs.error('Cannot resolve relative paths in TEXINPUTS %s', x) if self.type == 'latex': if 'ps' in outs: tsk = self.create_task('dvips', task.outputs, node.change_ext('.ps')) tsk.env.env = dict(os.environ) if 'pdf' in outs: tsk = self.create_task('dvipdf', task.outputs, node.change_ext('.pdf')) tsk.env.env = dict(os.environ) elif self.type == 'pdflatex': if 'ps' in outs: self.create_task('pdf2ps', task.outputs, node.change_ext('.ps')) self.source = [] def configure(self): """ Find the programs tex, latex and others without raising errors. """ v = self.env for p in 'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split(): try: self.find_program(p, var=p.upper()) except self.errors.ConfigurationError: pass v.DVIPSFLAGS = '-Ppdf' ldb-2.0.8/third_party/waf/waflib/Tools/vala.py0000660000000000000000000002615513573675414021215 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Ali Sabil, 2007 # Radosław Szkodziński, 2010 """ At this point, vala is still unstable, so do not expect this tool to be too stable either (apis, etc) """ import re from waflib import Build, Context, Errors, Logs, Node, Options, Task, Utils from waflib.TaskGen import extension, taskgen_method from waflib.Configure import conf class valac(Task.Task): """ Compiles vala files """ #run_str = "${VALAC} ${VALAFLAGS}" # ideally #vars = ['VALAC_VERSION'] vars = ["VALAC", "VALAC_VERSION", "VALAFLAGS"] ext_out = ['.h'] def run(self): cmd = self.env.VALAC + self.env.VALAFLAGS resources = getattr(self, 'vala_exclude', []) cmd.extend([a.abspath() for a in self.inputs if a not in resources]) ret = self.exec_command(cmd, cwd=self.vala_dir_node.abspath()) if ret: return ret if self.generator.dump_deps_node: self.generator.dump_deps_node.write('\n'.join(self.generator.packages)) return ret @taskgen_method def init_vala_task(self): """ Initializes the vala task with the relevant data (acts as a constructor) """ self.profile = getattr(self, 'profile', 'gobject') self.packages = packages = Utils.to_list(getattr(self, 'packages', [])) self.use = Utils.to_list(getattr(self, 'use', [])) if packages and not self.use: self.use = packages[:] # copy if self.profile == 'gobject': if not 'GOBJECT' in self.use: self.use.append('GOBJECT') def addflags(flags): self.env.append_value('VALAFLAGS', flags) if self.profile: addflags('--profile=%s' % self.profile) valatask = self.valatask # output directory if hasattr(self, 'vala_dir'): if isinstance(self.vala_dir, str): valatask.vala_dir_node = self.path.get_bld().make_node(self.vala_dir) try: valatask.vala_dir_node.mkdir() except OSError: raise self.bld.fatal('Cannot create the vala dir %r' % valatask.vala_dir_node) else: valatask.vala_dir_node = self.vala_dir else: valatask.vala_dir_node = self.path.get_bld() addflags('--directory=%s' % valatask.vala_dir_node.abspath()) if hasattr(self, 'thread'): if self.profile == 'gobject': if not 'GTHREAD' in self.use: self.use.append('GTHREAD') else: #Vala doesn't have threading support for dova nor posix Logs.warn('Profile %s means no threading support', self.profile) self.thread = False if self.thread: addflags('--thread') self.is_lib = 'cprogram' not in self.features if self.is_lib: addflags('--library=%s' % self.target) h_node = valatask.vala_dir_node.find_or_declare('%s.h' % self.target) valatask.outputs.append(h_node) addflags('--header=%s' % h_node.name) valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi' % self.target)) if getattr(self, 'gir', None): gir_node = valatask.vala_dir_node.find_or_declare('%s.gir' % self.gir) addflags('--gir=%s' % gir_node.name) valatask.outputs.append(gir_node) self.vala_target_glib = getattr(self, 'vala_target_glib', getattr(Options.options, 'vala_target_glib', None)) if self.vala_target_glib: addflags('--target-glib=%s' % self.vala_target_glib) addflags(['--define=%s' % x for x in Utils.to_list(getattr(self, 'vala_defines', []))]) packages_private = Utils.to_list(getattr(self, 'packages_private', [])) addflags(['--pkg=%s' % x for x in packages_private]) def _get_api_version(): api_version = '1.0' if hasattr(Context.g_module, 'API_VERSION'): version = Context.g_module.API_VERSION.split(".") if version[0] == "0": api_version = "0." + version[1] else: api_version = version[0] + ".0" return api_version self.includes = Utils.to_list(getattr(self, 'includes', [])) valatask.install_path = getattr(self, 'install_path', '') valatask.vapi_path = getattr(self, 'vapi_path', '${DATAROOTDIR}/vala/vapi') valatask.pkg_name = getattr(self, 'pkg_name', self.env.PACKAGE) valatask.header_path = getattr(self, 'header_path', '${INCLUDEDIR}/%s-%s' % (valatask.pkg_name, _get_api_version())) valatask.install_binding = getattr(self, 'install_binding', True) self.vapi_dirs = vapi_dirs = Utils.to_list(getattr(self, 'vapi_dirs', [])) #includes = [] if hasattr(self, 'use'): local_packages = Utils.to_list(self.use)[:] # make sure to have a copy seen = [] while len(local_packages) > 0: package = local_packages.pop() if package in seen: continue seen.append(package) # check if the package exists try: package_obj = self.bld.get_tgen_by_name(package) except Errors.WafError: continue # in practice the other task is already processed # but this makes it explicit package_obj.post() package_name = package_obj.target task = getattr(package_obj, 'valatask', None) if task: for output in task.outputs: if output.name == package_name + ".vapi": valatask.set_run_after(task) if package_name not in packages: packages.append(package_name) if output.parent not in vapi_dirs: vapi_dirs.append(output.parent) if output.parent not in self.includes: self.includes.append(output.parent) if hasattr(package_obj, 'use'): lst = self.to_list(package_obj.use) lst.reverse() local_packages = [pkg for pkg in lst if pkg not in seen] + local_packages addflags(['--pkg=%s' % p for p in packages]) for vapi_dir in vapi_dirs: if isinstance(vapi_dir, Node.Node): v_node = vapi_dir else: v_node = self.path.find_dir(vapi_dir) if not v_node: Logs.warn('Unable to locate Vala API directory: %r', vapi_dir) else: addflags('--vapidir=%s' % v_node.abspath()) self.dump_deps_node = None if self.is_lib and self.packages: self.dump_deps_node = valatask.vala_dir_node.find_or_declare('%s.deps' % self.target) valatask.outputs.append(self.dump_deps_node) if self.is_lib and valatask.install_binding: headers_list = [o for o in valatask.outputs if o.suffix() == ".h"] if headers_list: self.install_vheader = self.add_install_files(install_to=valatask.header_path, install_from=headers_list) vapi_list = [o for o in valatask.outputs if (o.suffix() in (".vapi", ".deps"))] if vapi_list: self.install_vapi = self.add_install_files(install_to=valatask.vapi_path, install_from=vapi_list) gir_list = [o for o in valatask.outputs if o.suffix() == '.gir'] if gir_list: self.install_gir = self.add_install_files( install_to=getattr(self, 'gir_path', '${DATAROOTDIR}/gir-1.0'), install_from=gir_list) if hasattr(self, 'vala_resources'): nodes = self.to_nodes(self.vala_resources) valatask.vala_exclude = getattr(valatask, 'vala_exclude', []) + nodes valatask.inputs.extend(nodes) for x in nodes: addflags(['--gresources', x.abspath()]) @extension('.vala', '.gs') def vala_file(self, node): """ Compile a vala file and bind the task to *self.valatask*. If an existing vala task is already set, add the node to its inputs. The typical example is:: def build(bld): bld.program( packages = 'gtk+-2.0', target = 'vala-gtk-example', use = 'GTK GLIB', source = 'vala-gtk-example.vala foo.vala', vala_defines = ['DEBUG'] # adds --define= values to the command-line # the following arguments are for libraries #gir = 'hello-1.0', #gir_path = '/tmp', #vapi_path = '/tmp', #pkg_name = 'hello' # disable installing of gir, vapi and header #install_binding = False # profile = 'xyz' # adds --profile= to enable profiling # thread = True, # adds --thread, except if profile is on or not on 'gobject' # vala_target_glib = 'xyz' # adds --target-glib=, can be given through the command-line option --vala-target-glib= ) :param node: vala file :type node: :py:class:`waflib.Node.Node` """ try: valatask = self.valatask except AttributeError: valatask = self.valatask = self.create_task('valac') self.init_vala_task() valatask.inputs.append(node) name = node.name[:node.name.rfind('.')] + '.c' c_node = valatask.vala_dir_node.find_or_declare(name) valatask.outputs.append(c_node) self.source.append(c_node) @extension('.vapi') def vapi_file(self, node): try: valatask = self.valatask except AttributeError: valatask = self.valatask = self.create_task('valac') self.init_vala_task() valatask.inputs.append(node) @conf def find_valac(self, valac_name, min_version): """ Find the valac program, and execute it to store the version number in *conf.env.VALAC_VERSION* :param valac_name: program name :type valac_name: string or list of string :param min_version: minimum version acceptable :type min_version: tuple of int """ valac = self.find_program(valac_name, var='VALAC') try: output = self.cmd_and_log(valac + ['--version']) except Errors.WafError: valac_version = None else: ver = re.search(r'\d+.\d+.\d+', output).group().split('.') valac_version = tuple([int(x) for x in ver]) self.msg('Checking for %s version >= %r' % (valac_name, min_version), valac_version, valac_version and valac_version >= min_version) if valac and valac_version < min_version: self.fatal("%s version %r is too old, need >= %r" % (valac_name, valac_version, min_version)) self.env.VALAC_VERSION = valac_version return valac @conf def check_vala(self, min_version=(0,8,0), branch=None): """ Check if vala compiler from a given branch exists of at least a given version. :param min_version: minimum version acceptable (0.8.0) :type min_version: tuple :param branch: first part of the version number, in case a snapshot is used (0, 8) :type branch: tuple of int """ if self.env.VALA_MINVER: min_version = self.env.VALA_MINVER if self.env.VALA_MINVER_BRANCH: branch = self.env.VALA_MINVER_BRANCH if not branch: branch = min_version[:2] try: find_valac(self, 'valac-%d.%d' % (branch[0], branch[1]), min_version) except self.errors.ConfigurationError: find_valac(self, 'valac', min_version) @conf def check_vala_deps(self): """ Load the gobject and gthread packages if they are missing. """ if not self.env.HAVE_GOBJECT: pkg_args = {'package': 'gobject-2.0', 'uselib_store': 'GOBJECT', 'args': '--cflags --libs'} if getattr(Options.options, 'vala_target_glib', None): pkg_args['atleast_version'] = Options.options.vala_target_glib self.check_cfg(**pkg_args) if not self.env.HAVE_GTHREAD: pkg_args = {'package': 'gthread-2.0', 'uselib_store': 'GTHREAD', 'args': '--cflags --libs'} if getattr(Options.options, 'vala_target_glib', None): pkg_args['atleast_version'] = Options.options.vala_target_glib self.check_cfg(**pkg_args) def configure(self): """ Use the following to enforce minimum vala version:: def configure(conf): conf.env.VALA_MINVER = (0, 10, 0) conf.load('vala') """ self.load('gnu_dirs') self.check_vala_deps() self.check_vala() self.add_os_flags('VALAFLAGS') self.env.append_unique('VALAFLAGS', ['-C']) def options(opt): """ Load the :py:mod:`waflib.Tools.gnu_dirs` tool and add the ``--vala-target-glib`` command-line option """ opt.load('gnu_dirs') valaopts = opt.add_option_group('Vala Compiler Options') valaopts.add_option('--vala-target-glib', default=None, dest='vala_target_glib', metavar='MAJOR.MINOR', help='Target version of glib for Vala GObject code generation') ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py0000660000000000000000000002240013573675414023132 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2006 # Thomas Nagy, 2010-2018 (ita) """ Unit testing system for C/C++/D and interpreted languages providing test execution: * in parallel, by using ``waf -j`` * partial (only the tests that have changed) or full (by using ``waf --alltests``) The tests are declared by adding the **test** feature to programs:: def options(opt): opt.load('compiler_cxx waf_unit_test') def configure(conf): conf.load('compiler_cxx waf_unit_test') def build(bld): bld(features='cxx cxxprogram test', source='main.cpp', target='app') # or bld.program(features='test', source='main2.cpp', target='app2') When the build is executed, the program 'test' will be built and executed without arguments. The success/failure is detected by looking at the return code. The status and the standard output/error are stored on the build context. The results can be displayed by registering a callback function. Here is how to call the predefined callback:: def build(bld): bld(features='cxx cxxprogram test', source='main.c', target='app') from waflib.Tools import waf_unit_test bld.add_post_fun(waf_unit_test.summary) By passing --dump-test-scripts the build outputs corresponding python files (with extension _run.py) that are useful for debugging purposes. """ import os, shlex, sys from waflib.TaskGen import feature, after_method, taskgen_method from waflib import Utils, Task, Logs, Options from waflib.Tools import ccroot testlock = Utils.threading.Lock() SCRIPT_TEMPLATE = """#! %(python)s import subprocess, sys cmd = %(cmd)r # if you want to debug with gdb: #cmd = ['gdb', '-args'] + cmd env = %(env)r status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str)) sys.exit(status) """ @taskgen_method def handle_ut_cwd(self, key): """ Task generator method, used internally to limit code duplication. This method may disappear anytime. """ cwd = getattr(self, key, None) if cwd: if isinstance(cwd, str): # we want a Node instance if os.path.isabs(cwd): self.ut_cwd = self.bld.root.make_node(cwd) else: self.ut_cwd = self.path.make_node(cwd) @feature('test_scripts') def make_interpreted_test(self): """Create interpreted unit tests.""" for x in ['test_scripts_source', 'test_scripts_template']: if not hasattr(self, x): Logs.warn('a test_scripts taskgen i missing %s' % x) return self.ut_run, lst = Task.compile_fun(self.test_scripts_template, shell=getattr(self, 'test_scripts_shell', False)) script_nodes = self.to_nodes(self.test_scripts_source) for script_node in script_nodes: tsk = self.create_task('utest', [script_node]) tsk.vars = lst + tsk.vars tsk.env['SCRIPT'] = script_node.path_from(tsk.get_cwd()) self.handle_ut_cwd('test_scripts_cwd') env = getattr(self, 'test_scripts_env', None) if env: self.ut_env = env else: self.ut_env = dict(os.environ) paths = getattr(self, 'test_scripts_paths', {}) for (k,v) in paths.items(): p = self.ut_env.get(k, '').split(os.pathsep) if isinstance(v, str): v = v.split(os.pathsep) self.ut_env[k] = os.pathsep.join(p + v) @feature('test') @after_method('apply_link', 'process_use') def make_test(self): """Create the unit test task. There can be only one unit test task by task generator.""" if not getattr(self, 'link_task', None): return tsk = self.create_task('utest', self.link_task.outputs) if getattr(self, 'ut_str', None): self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) tsk.vars = lst + tsk.vars self.handle_ut_cwd('ut_cwd') if not hasattr(self, 'ut_paths'): paths = [] for x in self.tmp_use_sorted: try: y = self.bld.get_tgen_by_name(x).link_task except AttributeError: pass else: if not isinstance(y, ccroot.stlink_task): paths.append(y.outputs[0].parent.abspath()) self.ut_paths = os.pathsep.join(paths) + os.pathsep if not hasattr(self, 'ut_env'): self.ut_env = dct = dict(os.environ) def add_path(var): dct[var] = self.ut_paths + dct.get(var,'') if Utils.is_win32: add_path('PATH') elif Utils.unversioned_sys_platform() == 'darwin': add_path('DYLD_LIBRARY_PATH') add_path('LD_LIBRARY_PATH') else: add_path('LD_LIBRARY_PATH') if not hasattr(self, 'ut_cmd'): self.ut_cmd = getattr(Options.options, 'testcmd', False) @taskgen_method def add_test_results(self, tup): """Override and return tup[1] to interrupt the build immediately if a test does not run""" Logs.debug("ut: %r", tup) try: self.utest_results.append(tup) except AttributeError: self.utest_results = [tup] try: self.bld.utest_results.append(tup) except AttributeError: self.bld.utest_results = [tup] @Task.deep_inputs class utest(Task.Task): """ Execute a unit test """ color = 'PINK' after = ['vnum', 'inst'] vars = [] def runnable_status(self): """ Always execute the task if `waf --alltests` was used or no tests if ``waf --notests`` was used """ if getattr(Options.options, 'no_tests', False): return Task.SKIP_ME ret = super(utest, self).runnable_status() if ret == Task.SKIP_ME: if getattr(Options.options, 'all_tests', False): return Task.RUN_ME return ret def get_test_env(self): """ In general, tests may require any library built anywhere in the project. Override this method if fewer paths are needed """ return self.generator.ut_env def post_run(self): super(utest, self).post_run() if getattr(Options.options, 'clear_failed_tests', False) and self.waf_unit_test_results[1]: self.generator.bld.task_sigs[self.uid()] = None def run(self): """ Execute the test. The execution is always successful, and the results are stored on ``self.generator.bld.utest_results`` for postprocessing. Override ``add_test_results`` to interrupt the build """ if hasattr(self.generator, 'ut_run'): return self.generator.ut_run(self) self.ut_exec = getattr(self.generator, 'ut_exec', [self.inputs[0].abspath()]) ut_cmd = getattr(self.generator, 'ut_cmd', False) if ut_cmd: self.ut_exec = shlex.split(ut_cmd % ' '.join(self.ut_exec)) return self.exec_command(self.ut_exec) def exec_command(self, cmd, **kw): self.generator.bld.log_command(cmd, kw) if getattr(Options.options, 'dump_test_scripts', False): script_code = SCRIPT_TEMPLATE % { 'python': sys.executable, 'env': self.get_test_env(), 'cwd': self.get_cwd().abspath(), 'cmd': cmd } script_file = self.inputs[0].abspath() + '_run.py' Utils.writef(script_file, script_code, encoding='utf-8') os.chmod(script_file, Utils.O755) if Logs.verbose > 1: Logs.info('Test debug file written as %r' % script_file) proc = Utils.subprocess.Popen(cmd, cwd=self.get_cwd().abspath(), env=self.get_test_env(), stderr=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE, shell=isinstance(cmd,str)) (stdout, stderr) = proc.communicate() self.waf_unit_test_results = tup = (self.inputs[0].abspath(), proc.returncode, stdout, stderr) testlock.acquire() try: return self.generator.add_test_results(tup) finally: testlock.release() def get_cwd(self): return getattr(self.generator, 'ut_cwd', self.inputs[0].parent) def summary(bld): """ Display an execution summary:: def build(bld): bld(features='cxx cxxprogram test', source='main.c', target='app') from waflib.Tools import waf_unit_test bld.add_post_fun(waf_unit_test.summary) """ lst = getattr(bld, 'utest_results', []) if lst: Logs.pprint('CYAN', 'execution summary') total = len(lst) tfail = len([x for x in lst if x[1]]) Logs.pprint('GREEN', ' tests that pass %d/%d' % (total-tfail, total)) for (f, code, out, err) in lst: if not code: Logs.pprint('GREEN', ' %s' % f) Logs.pprint('GREEN' if tfail == 0 else 'RED', ' tests that fail %d/%d' % (tfail, total)) for (f, code, out, err) in lst: if code: Logs.pprint('RED', ' %s' % f) def set_exit_code(bld): """ If any of the tests fail waf will exit with that exit code. This is useful if you have an automated build system which need to report on errors from the tests. You may use it like this: def build(bld): bld(features='cxx cxxprogram test', source='main.c', target='app') from waflib.Tools import waf_unit_test bld.add_post_fun(waf_unit_test.set_exit_code) """ lst = getattr(bld, 'utest_results', []) for (f, code, out, err) in lst: if code: msg = [] if out: msg.append('stdout:%s%s' % (os.linesep, out.decode('utf-8'))) if err: msg.append('stderr:%s%s' % (os.linesep, err.decode('utf-8'))) bld.fatal(os.linesep.join(msg)) def options(opt): """ Provide the ``--alltests``, ``--notests`` and ``--testcmd`` command-line options. """ opt.add_option('--notests', action='store_true', default=False, help='Exec no unit tests', dest='no_tests') opt.add_option('--alltests', action='store_true', default=False, help='Exec all unit tests', dest='all_tests') opt.add_option('--clear-failed', action='store_true', default=False, help='Force failed unit tests to run again next time', dest='clear_failed_tests') opt.add_option('--testcmd', action='store', default=False, dest='testcmd', help='Run the unit tests using the test-cmd string example "--testcmd="valgrind --error-exitcode=1 %s" to run under valgrind') opt.add_option('--dump-test-scripts', action='store_true', default=False, help='Create python scripts to help debug tests', dest='dump_test_scripts') ldb-2.0.8/third_party/waf/waflib/Tools/winres.py0000660000000000000000000000414113573675414021570 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Brant Young, 2007 "Process *.rc* files for C/C++: X{.rc -> [.res|.rc.o]}" import re from waflib import Task from waflib.TaskGen import extension from waflib.Tools import c_preproc @extension('.rc') def rc_file(self, node): """ Binds the .rc extension to a winrc task """ obj_ext = '.rc.o' if self.env.WINRC_TGT_F == '/fo': obj_ext = '.res' rctask = self.create_task('winrc', node, node.change_ext(obj_ext)) try: self.compiled_tasks.append(rctask) except AttributeError: self.compiled_tasks = [rctask] re_lines = re.compile( r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'\ r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)', re.IGNORECASE | re.MULTILINE) class rc_parser(c_preproc.c_parser): """ Calculates dependencies in .rc files """ def filter_comments(self, node): """ Overrides :py:meth:`waflib.Tools.c_preproc.c_parser.filter_comments` """ code = node.read() if c_preproc.use_trigraphs: for (a, b) in c_preproc.trig_def: code = code.split(a).join(b) code = c_preproc.re_nl.sub('', code) code = c_preproc.re_cpp.sub(c_preproc.repl, code) ret = [] for m in re.finditer(re_lines, code): if m.group(2): ret.append((m.group(2), m.group(3))) else: ret.append(('include', m.group(5))) return ret class winrc(Task.Task): """ Compiles resource files """ run_str = '${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}' color = 'BLUE' def scan(self): tmp = rc_parser(self.generator.includes_nodes) tmp.start(self.inputs[0], self.env) return (tmp.nodes, tmp.names) def configure(conf): """ Detects the programs RC or windres, depending on the C/C++ compiler in use """ v = conf.env if not v.WINRC: if v.CC_NAME == 'msvc': conf.find_program('RC', var='WINRC', path_list=v.PATH) v.WINRC_TGT_F = '/fo' v.WINRC_SRC_F = '' else: conf.find_program('windres', var='WINRC', path_list=v.PATH) v.WINRC_TGT_F = '-o' v.WINRC_SRC_F = '-i' ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py0000660000000000000000000000264113573675414021052 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 # Michael Kuhn, 2009 from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_xlc(conf): """ Detects the Aix C compiler """ cc = conf.find_program(['xlc_r', 'xlc'], var='CC') conf.get_xlc_version(cc) conf.env.CC_NAME = 'xlc' @conf def xlc_common_flags(conf): """ Flags required for executing the Aix C compiler """ v = conf.env v.CC_SRC_F = [] v.CC_TGT_F = ['-c', '-o'] if not v.LINK_CC: v.LINK_CC = v.CC v.CCLNK_SRC_F = [] v.CCLNK_TGT_F = ['-o'] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.RPATH_ST = '-Wl,-rpath,%s' v.SONAME_ST = [] v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.LINKFLAGS_cprogram = ['-Wl,-brtl'] v.cprogram_PATTERN = '%s' v.CFLAGS_cshlib = ['-fPIC'] v.LINKFLAGS_cshlib = ['-G', '-Wl,-brtl,-bexpfull'] v.cshlib_PATTERN = 'lib%s.so' v.LINKFLAGS_cstlib = [] v.cstlib_PATTERN = 'lib%s.a' def configure(conf): conf.find_xlc() conf.find_ar() conf.xlc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py0000660000000000000000000000267413573675414021440 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2018 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 # Michael Kuhn, 2009 from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_xlcxx(conf): """ Detects the Aix C++ compiler """ cxx = conf.find_program(['xlc++_r', 'xlc++'], var='CXX') conf.get_xlc_version(cxx) conf.env.CXX_NAME = 'xlc++' @conf def xlcxx_common_flags(conf): """ Flags required for executing the Aix C++ compiler """ v = conf.env v.CXX_SRC_F = [] v.CXX_TGT_F = ['-c', '-o'] if not v.LINK_CXX: v.LINK_CXX = v.CXX v.CXXLNK_SRC_F = [] v.CXXLNK_TGT_F = ['-o'] v.CPPPATH_ST = '-I%s' v.DEFINES_ST = '-D%s' v.LIB_ST = '-l%s' # template for adding libs v.LIBPATH_ST = '-L%s' # template for adding libpaths v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-L%s' v.RPATH_ST = '-Wl,-rpath,%s' v.SONAME_ST = [] v.SHLIB_MARKER = [] v.STLIB_MARKER = [] v.LINKFLAGS_cxxprogram= ['-Wl,-brtl'] v.cxxprogram_PATTERN = '%s' v.CXXFLAGS_cxxshlib = ['-fPIC'] v.LINKFLAGS_cxxshlib = ['-G', '-Wl,-brtl,-bexpfull'] v.cxxshlib_PATTERN = 'lib%s.so' v.LINKFLAGS_cxxstlib = [] v.cxxstlib_PATTERN = 'lib%s.a' def configure(conf): conf.find_xlcxx() conf.find_ar() conf.xlcxx_common_flags() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/Utils.py0000660000000000000000000006140113573675414020263 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) """ Utilities and platform-specific fixes The portability fixes try to provide a consistent behavior of the Waf API through Python versions 2.5 to 3.X and across different platforms (win32, linux, etc) """ from __future__ import with_statement import atexit, os, sys, errno, inspect, re, datetime, platform, base64, signal, functools, time try: import cPickle except ImportError: import pickle as cPickle # leave this if os.name == 'posix' and sys.version_info[0] < 3: try: import subprocess32 as subprocess except ImportError: import subprocess else: import subprocess try: TimeoutExpired = subprocess.TimeoutExpired except AttributeError: class TimeoutExpired(Exception): pass from collections import deque, defaultdict try: import _winreg as winreg except ImportError: try: import winreg except ImportError: winreg = None from waflib import Errors try: from hashlib import md5 except ImportError: try: from hashlib import sha1 as md5 except ImportError: # never fail to enable potential fixes from another module pass else: try: md5().digest() except ValueError: # Fips? #2213 from hashlib import sha1 as md5 try: import threading except ImportError: if not 'JOBS' in os.environ: # no threading :-( os.environ['JOBS'] = '1' class threading(object): """ A fake threading class for platforms lacking the threading module. Use ``waf -j1`` on those platforms """ pass class Lock(object): """Fake Lock class""" def acquire(self): pass def release(self): pass threading.Lock = threading.Thread = Lock SIG_NIL = 'SIG_NIL_SIG_NIL_'.encode() """Arbitrary null value for hashes. Modify this value according to the hash function in use""" O644 = 420 """Constant representing the permissions for regular files (0644 raises a syntax error on python 3)""" O755 = 493 """Constant representing the permissions for executable files (0755 raises a syntax error on python 3)""" rot_chr = ['\\', '|', '/', '-'] "List of characters to use when displaying the throbber (progress bar)" rot_idx = 0 "Index of the current throbber character (progress bar)" class ordered_iter_dict(dict): """Ordered dictionary that provides iteration from the most recently inserted keys first""" def __init__(self, *k, **kw): self.lst = deque() dict.__init__(self, *k, **kw) def clear(self): dict.clear(self) self.lst = deque() def __setitem__(self, key, value): if key in dict.keys(self): self.lst.remove(key) dict.__setitem__(self, key, value) self.lst.append(key) def __delitem__(self, key): dict.__delitem__(self, key) try: self.lst.remove(key) except ValueError: pass def __iter__(self): return reversed(self.lst) def keys(self): return reversed(self.lst) class lru_node(object): """ Used by :py:class:`waflib.Utils.lru_cache` """ __slots__ = ('next', 'prev', 'key', 'val') def __init__(self): self.next = self self.prev = self self.key = None self.val = None class lru_cache(object): """ A simple least-recently used cache with lazy allocation """ __slots__ = ('maxlen', 'table', 'head') def __init__(self, maxlen=100): self.maxlen = maxlen """ Maximum amount of elements in the cache """ self.table = {} """ Mapping key-value """ self.head = lru_node() self.head.next = self.head self.head.prev = self.head def __getitem__(self, key): node = self.table[key] # assert(key==node.key) if node is self.head: return node.val # detach the node found node.prev.next = node.next node.next.prev = node.prev # replace the head node.next = self.head.next node.prev = self.head self.head = node.next.prev = node.prev.next = node return node.val def __setitem__(self, key, val): if key in self.table: # update the value for an existing key node = self.table[key] node.val = val self.__getitem__(key) else: if len(self.table) < self.maxlen: # the very first item is unused until the maximum is reached node = lru_node() node.prev = self.head node.next = self.head.next node.prev.next = node.next.prev = node else: node = self.head = self.head.next try: # that's another key del self.table[node.key] except KeyError: pass node.key = key node.val = val self.table[key] = node class lazy_generator(object): def __init__(self, fun, params): self.fun = fun self.params = params def __iter__(self): return self def __next__(self): try: it = self.it except AttributeError: it = self.it = self.fun(*self.params) return next(it) next = __next__ is_win32 = os.sep == '\\' or sys.platform == 'win32' or os.name == 'nt' # msys2 """ Whether this system is a Windows series """ def readf(fname, m='r', encoding='latin-1'): """ Reads an entire file into a string. See also :py:meth:`waflib.Node.Node.readf`:: def build(ctx): from waflib import Utils txt = Utils.readf(self.path.find_node('wscript').abspath()) txt = ctx.path.find_node('wscript').read() :type fname: string :param fname: Path to file :type m: string :param m: Open mode :type encoding: string :param encoding: encoding value, only used for python 3 :rtype: string :return: Content of the file """ if sys.hexversion > 0x3000000 and not 'b' in m: m += 'b' with open(fname, m) as f: txt = f.read() if encoding: txt = txt.decode(encoding) else: txt = txt.decode() else: with open(fname, m) as f: txt = f.read() return txt def writef(fname, data, m='w', encoding='latin-1'): """ Writes an entire file from a string. See also :py:meth:`waflib.Node.Node.writef`:: def build(ctx): from waflib import Utils txt = Utils.writef(self.path.make_node('i_like_kittens').abspath(), 'some data') self.path.make_node('i_like_kittens').write('some data') :type fname: string :param fname: Path to file :type data: string :param data: The contents to write to the file :type m: string :param m: Open mode :type encoding: string :param encoding: encoding value, only used for python 3 """ if sys.hexversion > 0x3000000 and not 'b' in m: data = data.encode(encoding) m += 'b' with open(fname, m) as f: f.write(data) def h_file(fname): """ Computes a hash value for a file by using md5. Use the md5_tstamp extension to get faster build hashes if necessary. :type fname: string :param fname: path to the file to hash :return: hash of the file contents :rtype: string or bytes """ m = md5() with open(fname, 'rb') as f: while fname: fname = f.read(200000) m.update(fname) return m.digest() def readf_win32(f, m='r', encoding='latin-1'): flags = os.O_NOINHERIT | os.O_RDONLY if 'b' in m: flags |= os.O_BINARY if '+' in m: flags |= os.O_RDWR try: fd = os.open(f, flags) except OSError: raise IOError('Cannot read from %r' % f) if sys.hexversion > 0x3000000 and not 'b' in m: m += 'b' with os.fdopen(fd, m) as f: txt = f.read() if encoding: txt = txt.decode(encoding) else: txt = txt.decode() else: with os.fdopen(fd, m) as f: txt = f.read() return txt def writef_win32(f, data, m='w', encoding='latin-1'): if sys.hexversion > 0x3000000 and not 'b' in m: data = data.encode(encoding) m += 'b' flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT if 'b' in m: flags |= os.O_BINARY if '+' in m: flags |= os.O_RDWR try: fd = os.open(f, flags) except OSError: raise OSError('Cannot write to %r' % f) with os.fdopen(fd, m) as f: f.write(data) def h_file_win32(fname): try: fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT) except OSError: raise OSError('Cannot read from %r' % fname) m = md5() with os.fdopen(fd, 'rb') as f: while fname: fname = f.read(200000) m.update(fname) return m.digest() # always save these readf_unix = readf writef_unix = writef h_file_unix = h_file if hasattr(os, 'O_NOINHERIT') and sys.hexversion < 0x3040000: # replace the default functions readf = readf_win32 writef = writef_win32 h_file = h_file_win32 try: x = ''.encode('hex') except LookupError: import binascii def to_hex(s): ret = binascii.hexlify(s) if not isinstance(ret, str): ret = ret.decode('utf-8') return ret else: def to_hex(s): return s.encode('hex') to_hex.__doc__ = """ Return the hexadecimal representation of a string :param s: string to convert :type s: string """ def listdir_win32(s): """ Lists the contents of a folder in a portable manner. On Win32, returns the list of drive letters: ['C:', 'X:', 'Z:'] when an empty string is given. :type s: string :param s: a string, which can be empty on Windows """ if not s: try: import ctypes except ImportError: # there is nothing much we can do return [x + ':\\' for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] else: dlen = 4 # length of "?:\\x00" maxdrives = 26 buf = ctypes.create_string_buffer(maxdrives * dlen) ndrives = ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen, ctypes.byref(buf)) return [ str(buf.raw[4*i:4*i+2].decode('ascii')) for i in range(int(ndrives/dlen)) ] if len(s) == 2 and s[1] == ":": s += os.sep if not os.path.isdir(s): e = OSError('%s is not a directory' % s) e.errno = errno.ENOENT raise e return os.listdir(s) listdir = os.listdir if is_win32: listdir = listdir_win32 def num2ver(ver): """ Converts a string, tuple or version number into an integer. The number is supposed to have at most 4 digits:: from waflib.Utils import num2ver num2ver('1.3.2') == num2ver((1,3,2)) == num2ver((1,3,2,0)) :type ver: string or tuple of numbers :param ver: a version number """ if isinstance(ver, str): ver = tuple(ver.split('.')) if isinstance(ver, tuple): ret = 0 for i in range(4): if i < len(ver): ret += 256**(3 - i) * int(ver[i]) return ret return ver def to_list(val): """ Converts a string argument to a list by splitting it by spaces. Returns the object if not a string:: from waflib.Utils import to_list lst = to_list('a b c d') :param val: list of string or space-separated string :rtype: list :return: Argument converted to list """ if isinstance(val, str): return val.split() else: return val def console_encoding(): try: import ctypes except ImportError: pass else: try: codepage = ctypes.windll.kernel32.GetConsoleCP() except AttributeError: pass else: if codepage: return 'cp%d' % codepage return sys.stdout.encoding or ('cp1252' if is_win32 else 'latin-1') def split_path_unix(path): return path.split('/') def split_path_cygwin(path): if path.startswith('//'): ret = path.split('/')[2:] ret[0] = '/' + ret[0] return ret return path.split('/') re_sp = re.compile('[/\\\\]+') def split_path_win32(path): if path.startswith('\\\\'): ret = re_sp.split(path)[1:] ret[0] = '\\\\' + ret[0] if ret[0] == '\\\\?': return ret[1:] return ret return re_sp.split(path) msysroot = None def split_path_msys(path): if path.startswith(('/', '\\')) and not path.startswith(('//', '\\\\')): # msys paths can be in the form /usr/bin global msysroot if not msysroot: # msys has python 2.7 or 3, so we can use this msysroot = subprocess.check_output(['cygpath', '-w', '/']).decode(sys.stdout.encoding or 'latin-1') msysroot = msysroot.strip() path = os.path.normpath(msysroot + os.sep + path) return split_path_win32(path) if sys.platform == 'cygwin': split_path = split_path_cygwin elif is_win32: # Consider this an MSYSTEM environment if $MSYSTEM is set and python # reports is executable from a unix like path on a windows host. if os.environ.get('MSYSTEM') and sys.executable.startswith('/'): split_path = split_path_msys else: split_path = split_path_win32 else: split_path = split_path_unix split_path.__doc__ = """ Splits a path by / or \\; do not confuse this function with with ``os.path.split`` :type path: string :param path: path to split :return: list of string """ def check_dir(path): """ Ensures that a directory exists (similar to ``mkdir -p``). :type path: string :param path: Path to directory :raises: :py:class:`waflib.Errors.WafError` if the folder cannot be added. """ if not os.path.isdir(path): try: os.makedirs(path) except OSError as e: if not os.path.isdir(path): raise Errors.WafError('Cannot create the folder %r' % path, ex=e) def check_exe(name, env=None): """ Ensures that a program exists :type name: string :param name: path to the program :param env: configuration object :type env: :py:class:`waflib.ConfigSet.ConfigSet` :return: path of the program or None :raises: :py:class:`waflib.Errors.WafError` if the folder cannot be added. """ if not name: raise ValueError('Cannot execute an empty string!') def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) fpath, fname = os.path.split(name) if fpath and is_exe(name): return os.path.abspath(name) else: env = env or os.environ for path in env['PATH'].split(os.pathsep): path = path.strip('"') exe_file = os.path.join(path, name) if is_exe(exe_file): return os.path.abspath(exe_file) return None def def_attrs(cls, **kw): """ Sets default attributes on a class instance :type cls: class :param cls: the class to update the given attributes in. :type kw: dict :param kw: dictionary of attributes names and values. """ for k, v in kw.items(): if not hasattr(cls, k): setattr(cls, k, v) def quote_define_name(s): """ Converts a string into an identifier suitable for C defines. :type s: string :param s: String to convert :rtype: string :return: Identifier suitable for C defines """ fu = re.sub('[^a-zA-Z0-9]', '_', s) fu = re.sub('_+', '_', fu) fu = fu.upper() return fu re_sh = re.compile('\\s|\'|"') """ Regexp used for shell_escape below """ def shell_escape(cmd): """ Escapes a command: ['ls', '-l', 'arg space'] -> ls -l 'arg space' """ if isinstance(cmd, str): return cmd return ' '.join(repr(x) if re_sh.search(x) else x for x in cmd) def h_list(lst): """ Hashes lists of ordered data. Using hash(tup) for tuples would be much more efficient, but Python now enforces hash randomization :param lst: list to hash :type lst: list of strings :return: hash of the list """ return md5(repr(lst).encode()).digest() if sys.hexversion < 0x3000000: def h_list_python2(lst): return md5(repr(lst)).digest() h_list_python2.__doc__ = h_list.__doc__ h_list = h_list_python2 def h_fun(fun): """ Hash functions :param fun: function to hash :type fun: function :return: hash of the function :rtype: string or bytes """ try: return fun.code except AttributeError: if isinstance(fun, functools.partial): code = list(fun.args) # The method items() provides a sequence of tuples where the first element # represents an optional argument of the partial function application # # The sorting result outcome will be consistent because: # 1. tuples are compared in order of their elements # 2. optional argument namess are unique code.extend(sorted(fun.keywords.items())) code.append(h_fun(fun.func)) fun.code = h_list(code) return fun.code try: h = inspect.getsource(fun) except EnvironmentError: h = 'nocode' try: fun.code = h except AttributeError: pass return h def h_cmd(ins): """ Hashes objects recursively :param ins: input object :type ins: string or list or tuple or function :rtype: string or bytes """ # this function is not meant to be particularly fast if isinstance(ins, str): # a command is either a string ret = ins elif isinstance(ins, list) or isinstance(ins, tuple): # or a list of functions/strings ret = str([h_cmd(x) for x in ins]) else: # or just a python function ret = str(h_fun(ins)) if sys.hexversion > 0x3000000: ret = ret.encode('latin-1', 'xmlcharrefreplace') return ret reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") def subst_vars(expr, params): """ Replaces ${VAR} with the value of VAR taken from a dict or a config set:: from waflib import Utils s = Utils.subst_vars('${PREFIX}/bin', env) :type expr: string :param expr: String to perform substitution on :param params: Dictionary or config set to look up variable values. """ def repl_var(m): if m.group(1): return '\\' if m.group(2): return '$' try: # ConfigSet instances may contain lists return params.get_flat(m.group(3)) except AttributeError: return params[m.group(3)] # if you get a TypeError, it means that 'expr' is not a string... # Utils.subst_vars(None, env) will not work return reg_subst.sub(repl_var, expr) def destos_to_binfmt(key): """ Returns the binary format based on the unversioned platform name, and defaults to ``elf`` if nothing is found. :param key: platform name :type key: string :return: string representing the binary format """ if key == 'darwin': return 'mac-o' elif key in ('win32', 'cygwin', 'uwin', 'msys'): return 'pe' return 'elf' def unversioned_sys_platform(): """ Returns the unversioned platform name. Some Python platform names contain versions, that depend on the build environment, e.g. linux2, freebsd6, etc. This returns the name without the version number. Exceptions are os2 and win32, which are returned verbatim. :rtype: string :return: Unversioned platform name """ s = sys.platform if s.startswith('java'): # The real OS is hidden under the JVM. from java.lang import System s = System.getProperty('os.name') # see http://lopica.sourceforge.net/os.html for a list of possible values if s == 'Mac OS X': return 'darwin' elif s.startswith('Windows '): return 'win32' elif s == 'OS/2': return 'os2' elif s == 'HP-UX': return 'hp-ux' elif s in ('SunOS', 'Solaris'): return 'sunos' else: s = s.lower() # powerpc == darwin for our purposes if s == 'powerpc': return 'darwin' if s == 'win32' or s == 'os2': return s if s == 'cli' and os.name == 'nt': # ironpython is only on windows as far as we know return 'win32' return re.split(r'\d+$', s)[0] def nada(*k, **kw): """ Does nothing :return: None """ pass class Timer(object): """ Simple object for timing the execution of commands. Its string representation is the duration:: from waflib.Utils import Timer timer = Timer() a_few_operations() s = str(timer) """ def __init__(self): self.start_time = self.now() def __str__(self): delta = self.now() - self.start_time if not isinstance(delta, datetime.timedelta): delta = datetime.timedelta(seconds=delta) days = delta.days hours, rem = divmod(delta.seconds, 3600) minutes, seconds = divmod(rem, 60) seconds += delta.microseconds * 1e-6 result = '' if days: result += '%dd' % days if days or hours: result += '%dh' % hours if days or hours or minutes: result += '%dm' % minutes return '%s%.3fs' % (result, seconds) def now(self): return datetime.datetime.utcnow() if hasattr(time, 'perf_counter'): def now(self): return time.perf_counter() def read_la_file(path): """ Reads property files, used by msvc.py :param path: file to read :type path: string """ sp = re.compile(r'^([^=]+)=\'(.*)\'$') dc = {} for line in readf(path).splitlines(): try: _, left, right, _ = sp.split(line.strip()) dc[left] = right except ValueError: pass return dc def run_once(fun): """ Decorator: let a function cache its results, use like this:: @run_once def foo(k): return 345*2343 .. note:: in practice this can cause memory leaks, prefer a :py:class:`waflib.Utils.lru_cache` :param fun: function to execute :type fun: function :return: the return value of the function executed """ cache = {} def wrap(*k): try: return cache[k] except KeyError: ret = fun(*k) cache[k] = ret return ret wrap.__cache__ = cache wrap.__name__ = fun.__name__ return wrap def get_registry_app_path(key, filename): """ Returns the value of a registry key for an executable :type key: string :type filename: list of string """ if not winreg: return None try: result = winreg.QueryValue(key, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe" % filename[0]) except OSError: pass else: if os.path.isfile(result): return result def lib64(): """ Guess the default ``/usr/lib`` extension for 64-bit applications :return: '64' or '' :rtype: string """ # default settings for /usr/lib if os.sep == '/': if platform.architecture()[0] == '64bit': if os.path.exists('/usr/lib64') and not os.path.exists('/usr/lib32'): return '64' return '' def sane_path(p): # private function for the time being! return os.path.abspath(os.path.expanduser(p)) process_pool = [] """ List of processes started to execute sub-process commands """ def get_process(): """ Returns a process object that can execute commands as sub-processes :rtype: subprocess.Popen """ try: return process_pool.pop() except IndexError: filepath = os.path.dirname(os.path.abspath(__file__)) + os.sep + 'processor.py' cmd = [sys.executable, '-c', readf(filepath)] return subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, bufsize=0, close_fds=not is_win32) def run_prefork_process(cmd, kwargs, cargs): """ Delegates process execution to a pre-forked process instance. """ if not 'env' in kwargs: kwargs['env'] = dict(os.environ) try: obj = base64.b64encode(cPickle.dumps([cmd, kwargs, cargs])) except (TypeError, AttributeError): return run_regular_process(cmd, kwargs, cargs) proc = get_process() if not proc: return run_regular_process(cmd, kwargs, cargs) proc.stdin.write(obj) proc.stdin.write('\n'.encode()) proc.stdin.flush() obj = proc.stdout.readline() if not obj: raise OSError('Preforked sub-process %r died' % proc.pid) process_pool.append(proc) lst = cPickle.loads(base64.b64decode(obj)) # Jython wrapper failures (bash/execvp) assert len(lst) == 5 ret, out, err, ex, trace = lst if ex: if ex == 'OSError': raise OSError(trace) elif ex == 'ValueError': raise ValueError(trace) elif ex == 'TimeoutExpired': exc = TimeoutExpired(cmd, timeout=cargs['timeout'], output=out) exc.stderr = err raise exc else: raise Exception(trace) return ret, out, err def lchown(path, user=-1, group=-1): """ Change the owner/group of a path, raises an OSError if the ownership change fails. :param user: user to change :type user: int or str :param group: group to change :type group: int or str """ if isinstance(user, str): import pwd entry = pwd.getpwnam(user) if not entry: raise OSError('Unknown user %r' % user) user = entry[2] if isinstance(group, str): import grp entry = grp.getgrnam(group) if not entry: raise OSError('Unknown group %r' % group) group = entry[2] return os.lchown(path, user, group) def run_regular_process(cmd, kwargs, cargs={}): """ Executes a subprocess command by using subprocess.Popen """ proc = subprocess.Popen(cmd, **kwargs) if kwargs.get('stdout') or kwargs.get('stderr'): try: out, err = proc.communicate(**cargs) except TimeoutExpired: if kwargs.get('start_new_session') and hasattr(os, 'killpg'): os.killpg(proc.pid, signal.SIGKILL) else: proc.kill() out, err = proc.communicate() exc = TimeoutExpired(proc.args, timeout=cargs['timeout'], output=out) exc.stderr = err raise exc status = proc.returncode else: out, err = (None, None) try: status = proc.wait(**cargs) except TimeoutExpired as e: if kwargs.get('start_new_session') and hasattr(os, 'killpg'): os.killpg(proc.pid, signal.SIGKILL) else: proc.kill() proc.wait() raise e return status, out, err def run_process(cmd, kwargs, cargs={}): """ Executes a subprocess by using a pre-forked process when possible or falling back to subprocess.Popen. See :py:func:`waflib.Utils.run_prefork_process` and :py:func:`waflib.Utils.run_regular_process` """ if kwargs.get('stdout') and kwargs.get('stderr'): return run_prefork_process(cmd, kwargs, cargs) else: return run_regular_process(cmd, kwargs, cargs) def alloc_process_pool(n, force=False): """ Allocates an amount of processes to the default pool so its size is at least *n*. It is useful to call this function early so that the pre-forked processes use as little memory as possible. :param n: pool size :type n: integer :param force: if True then *n* more processes are added to the existing pool :type force: bool """ # mandatory on python2, unnecessary on python >= 3.2 global run_process, get_process, alloc_process_pool if not force: n = max(n - len(process_pool), 0) try: lst = [get_process() for x in range(n)] except OSError: run_process = run_regular_process get_process = alloc_process_pool = nada else: for x in lst: process_pool.append(x) def atexit_pool(): for k in process_pool: try: os.kill(k.pid, 9) except OSError: pass else: k.wait() # see #1889 if (sys.hexversion<0x207000f and not is_win32) or sys.hexversion>=0x306000f: atexit.register(atexit_pool) if os.environ.get('WAF_NO_PREFORK') or sys.platform == 'cli' or not sys.executable: run_process = run_regular_process get_process = alloc_process_pool = nada ldb-2.0.8/third_party/waf/waflib/__init__.py0000660000000000000000000000010713573675414020716 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2018 (ita) ldb-2.0.8/third_party/waf/waflib/ansiterm.py0000660000000000000000000002527313573675414021014 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 """ Emulate a vt100 terminal in cmd.exe By wrapping sys.stdout / sys.stderr with Ansiterm, the vt100 escape characters will be interpreted and the equivalent actions will be performed with Win32 console commands. """ import os, re, sys from waflib import Utils wlock = Utils.threading.Lock() try: from ctypes import Structure, windll, c_short, c_ushort, c_ulong, c_int, byref, c_wchar, POINTER, c_long except ImportError: class AnsiTerm(object): def __init__(self, stream): self.stream = stream try: self.errors = self.stream.errors except AttributeError: pass # python 2.5 self.encoding = self.stream.encoding def write(self, txt): try: wlock.acquire() self.stream.write(txt) self.stream.flush() finally: wlock.release() def fileno(self): return self.stream.fileno() def flush(self): self.stream.flush() def isatty(self): return self.stream.isatty() else: class COORD(Structure): _fields_ = [("X", c_short), ("Y", c_short)] class SMALL_RECT(Structure): _fields_ = [("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short)] class CONSOLE_SCREEN_BUFFER_INFO(Structure): _fields_ = [("Size", COORD), ("CursorPosition", COORD), ("Attributes", c_ushort), ("Window", SMALL_RECT), ("MaximumWindowSize", COORD)] class CONSOLE_CURSOR_INFO(Structure): _fields_ = [('dwSize', c_ulong), ('bVisible', c_int)] try: _type = unicode except NameError: _type = str to_int = lambda number, default: number and int(number) or default STD_OUTPUT_HANDLE = -11 STD_ERROR_HANDLE = -12 windll.kernel32.GetStdHandle.argtypes = [c_ulong] windll.kernel32.GetStdHandle.restype = c_ulong windll.kernel32.GetConsoleScreenBufferInfo.argtypes = [c_ulong, POINTER(CONSOLE_SCREEN_BUFFER_INFO)] windll.kernel32.GetConsoleScreenBufferInfo.restype = c_long windll.kernel32.SetConsoleTextAttribute.argtypes = [c_ulong, c_ushort] windll.kernel32.SetConsoleTextAttribute.restype = c_long windll.kernel32.FillConsoleOutputCharacterW.argtypes = [c_ulong, c_wchar, c_ulong, POINTER(COORD), POINTER(c_ulong)] windll.kernel32.FillConsoleOutputCharacterW.restype = c_long windll.kernel32.FillConsoleOutputAttribute.argtypes = [c_ulong, c_ushort, c_ulong, POINTER(COORD), POINTER(c_ulong) ] windll.kernel32.FillConsoleOutputAttribute.restype = c_long windll.kernel32.SetConsoleCursorPosition.argtypes = [c_ulong, POINTER(COORD) ] windll.kernel32.SetConsoleCursorPosition.restype = c_long windll.kernel32.SetConsoleCursorInfo.argtypes = [c_ulong, POINTER(CONSOLE_CURSOR_INFO)] windll.kernel32.SetConsoleCursorInfo.restype = c_long class AnsiTerm(object): """ emulate a vt100 terminal in cmd.exe """ def __init__(self, s): self.stream = s try: self.errors = s.errors except AttributeError: pass # python2.5 self.encoding = s.encoding self.cursor_history = [] handle = (s.fileno() == 2) and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE self.hconsole = windll.kernel32.GetStdHandle(handle) self._sbinfo = CONSOLE_SCREEN_BUFFER_INFO() self._csinfo = CONSOLE_CURSOR_INFO() windll.kernel32.GetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) # just to double check that the console is usable self._orig_sbinfo = CONSOLE_SCREEN_BUFFER_INFO() r = windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._orig_sbinfo)) self._isatty = r == 1 def screen_buffer_info(self): """ Updates self._sbinfo and returns it """ windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._sbinfo)) return self._sbinfo def clear_line(self, param): mode = param and int(param) or 0 sbinfo = self.screen_buffer_info() if mode == 1: # Clear from beginning of line to cursor position line_start = COORD(0, sbinfo.CursorPosition.Y) line_length = sbinfo.Size.X elif mode == 2: # Clear entire line line_start = COORD(sbinfo.CursorPosition.X, sbinfo.CursorPosition.Y) line_length = sbinfo.Size.X - sbinfo.CursorPosition.X else: # Clear from cursor position to end of line line_start = sbinfo.CursorPosition line_length = sbinfo.Size.X - sbinfo.CursorPosition.X chars_written = c_ulong() windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), line_length, line_start, byref(chars_written)) windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, line_length, line_start, byref(chars_written)) def clear_screen(self, param): mode = to_int(param, 0) sbinfo = self.screen_buffer_info() if mode == 1: # Clear from beginning of screen to cursor position clear_start = COORD(0, 0) clear_length = sbinfo.CursorPosition.X * sbinfo.CursorPosition.Y elif mode == 2: # Clear entire screen and return cursor to home clear_start = COORD(0, 0) clear_length = sbinfo.Size.X * sbinfo.Size.Y windll.kernel32.SetConsoleCursorPosition(self.hconsole, clear_start) else: # Clear from cursor position to end of screen clear_start = sbinfo.CursorPosition clear_length = ((sbinfo.Size.X - sbinfo.CursorPosition.X) + sbinfo.Size.X * (sbinfo.Size.Y - sbinfo.CursorPosition.Y)) chars_written = c_ulong() windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), clear_length, clear_start, byref(chars_written)) windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, clear_length, clear_start, byref(chars_written)) def push_cursor(self, param): sbinfo = self.screen_buffer_info() self.cursor_history.append(sbinfo.CursorPosition) def pop_cursor(self, param): if self.cursor_history: old_pos = self.cursor_history.pop() windll.kernel32.SetConsoleCursorPosition(self.hconsole, old_pos) def set_cursor(self, param): y, sep, x = param.partition(';') x = to_int(x, 1) - 1 y = to_int(y, 1) - 1 sbinfo = self.screen_buffer_info() new_pos = COORD( min(max(0, x), sbinfo.Size.X), min(max(0, y), sbinfo.Size.Y) ) windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) def set_column(self, param): x = to_int(param, 1) - 1 sbinfo = self.screen_buffer_info() new_pos = COORD( min(max(0, x), sbinfo.Size.X), sbinfo.CursorPosition.Y ) windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) def move_cursor(self, x_offset=0, y_offset=0): sbinfo = self.screen_buffer_info() new_pos = COORD( min(max(0, sbinfo.CursorPosition.X + x_offset), sbinfo.Size.X), min(max(0, sbinfo.CursorPosition.Y + y_offset), sbinfo.Size.Y) ) windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) def move_up(self, param): self.move_cursor(y_offset = -to_int(param, 1)) def move_down(self, param): self.move_cursor(y_offset = to_int(param, 1)) def move_left(self, param): self.move_cursor(x_offset = -to_int(param, 1)) def move_right(self, param): self.move_cursor(x_offset = to_int(param, 1)) def next_line(self, param): sbinfo = self.screen_buffer_info() self.move_cursor( x_offset = -sbinfo.CursorPosition.X, y_offset = to_int(param, 1) ) def prev_line(self, param): sbinfo = self.screen_buffer_info() self.move_cursor( x_offset = -sbinfo.CursorPosition.X, y_offset = -to_int(param, 1) ) def rgb2bgr(self, c): return ((c&1) << 2) | (c&2) | ((c&4)>>2) def set_color(self, param): cols = param.split(';') sbinfo = self.screen_buffer_info() attr = sbinfo.Attributes for c in cols: c = to_int(c, 0) if 29 < c < 38: # fgcolor attr = (attr & 0xfff0) | self.rgb2bgr(c - 30) elif 39 < c < 48: # bgcolor attr = (attr & 0xff0f) | (self.rgb2bgr(c - 40) << 4) elif c == 0: # reset attr = self._orig_sbinfo.Attributes elif c == 1: # strong attr |= 0x08 elif c == 4: # blink not available -> bg intensity attr |= 0x80 elif c == 7: # negative attr = (attr & 0xff88) | ((attr & 0x70) >> 4) | ((attr & 0x07) << 4) windll.kernel32.SetConsoleTextAttribute(self.hconsole, attr) def show_cursor(self,param): self._csinfo.bVisible = 1 windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) def hide_cursor(self,param): self._csinfo.bVisible = 0 windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) ansi_command_table = { 'A': move_up, 'B': move_down, 'C': move_right, 'D': move_left, 'E': next_line, 'F': prev_line, 'G': set_column, 'H': set_cursor, 'f': set_cursor, 'J': clear_screen, 'K': clear_line, 'h': show_cursor, 'l': hide_cursor, 'm': set_color, 's': push_cursor, 'u': pop_cursor, } # Match either the escape sequence or text not containing escape sequence ansi_tokens = re.compile(r'(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))') def write(self, text): try: wlock.acquire() if self._isatty: for param, cmd, txt in self.ansi_tokens.findall(text): if cmd: cmd_func = self.ansi_command_table.get(cmd) if cmd_func: cmd_func(self, param) else: self.writeconsole(txt) else: # no support for colors in the console, just output the text: # eclipse or msys may be able to interpret the escape sequences self.stream.write(text) finally: wlock.release() def writeconsole(self, txt): chars_written = c_ulong() writeconsole = windll.kernel32.WriteConsoleA if isinstance(txt, _type): writeconsole = windll.kernel32.WriteConsoleW # MSDN says that there is a shared buffer of 64 KB for the console # writes. Attempt to not get ERROR_NOT_ENOUGH_MEMORY, see waf issue #746 done = 0 todo = len(txt) chunk = 32<<10 while todo != 0: doing = min(chunk, todo) buf = txt[done:done+doing] r = writeconsole(self.hconsole, buf, doing, byref(chars_written), None) if r == 0: chunk >>= 1 continue done += doing todo -= doing def fileno(self): return self.stream.fileno() def flush(self): pass def isatty(self): return self._isatty if sys.stdout.isatty() or sys.stderr.isatty(): handle = sys.stdout.isatty() and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE console = windll.kernel32.GetStdHandle(handle) sbinfo = CONSOLE_SCREEN_BUFFER_INFO() def get_term_cols(): windll.kernel32.GetConsoleScreenBufferInfo(console, byref(sbinfo)) # Issue 1401 - the progress bar cannot reach the last character return sbinfo.Size.X - 1 # just try and see try: import struct, fcntl, termios except ImportError: pass else: if (sys.stdout.isatty() or sys.stderr.isatty()) and os.environ.get('TERM', '') not in ('dumb', 'emacs'): FD = sys.stdout.isatty() and sys.stdout.fileno() or sys.stderr.fileno() def fun(): return struct.unpack("HHHH", fcntl.ioctl(FD, termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)))[1] try: fun() except Exception as e: pass else: get_term_cols = fun ldb-2.0.8/third_party/waf/waflib/extras/__init__.py0000660000000000000000000000010713573675414022224 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py0000660000000000000000000001112613573675414022527 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2015 (ita) """ Instead of compiling object files one by one, c/c++ compilers are often able to compile at once: cc -c ../file1.c ../file2.c ../file3.c Files are output on the directory where the compiler is called, and dependencies are more difficult to track (do not run the command on all source files if only one file changes) As such, we do as if the files were compiled one by one, but no command is actually run: replace each cc/cpp Task by a TaskSlave. A new task called TaskMaster collects the signatures from each slave and finds out the command-line to run. Just import this module to start using it: def build(bld): bld.load('batched_cc') Note that this is provided as an example, unity builds are recommended for best performance results (fewer tasks and fewer jobs to execute). See waflib/extras/unity.py. """ from waflib import Task, Utils from waflib.TaskGen import extension, feature, after_method from waflib.Tools import c, cxx MAX_BATCH = 50 c_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${tsk.batch_incpaths()} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED} ${CPPFLAGS}' c_fun, _ = Task.compile_fun_noshell(c_str) cxx_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${tsk.batch_incpaths()} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED} ${CPPFLAGS}' cxx_fun, _ = Task.compile_fun_noshell(cxx_str) count = 70000 class batch(Task.Task): color = 'PINK' after = ['c', 'cxx'] before = ['cprogram', 'cshlib', 'cstlib', 'cxxprogram', 'cxxshlib', 'cxxstlib'] def uid(self): return Utils.h_list([Task.Task.uid(self), self.generator.idx, self.generator.path.abspath(), self.generator.target]) def __str__(self): return 'Batch compilation for %d slaves' % len(self.slaves) def __init__(self, *k, **kw): Task.Task.__init__(self, *k, **kw) self.slaves = [] self.inputs = [] self.hasrun = 0 global count count += 1 self.idx = count def add_slave(self, slave): self.slaves.append(slave) self.set_run_after(slave) def runnable_status(self): for t in self.run_after: if not t.hasrun: return Task.ASK_LATER for t in self.slaves: #if t.executed: if t.hasrun != Task.SKIPPED: return Task.RUN_ME return Task.SKIP_ME def get_cwd(self): return self.slaves[0].outputs[0].parent def batch_incpaths(self): st = self.env.CPPPATH_ST return [st % node.abspath() for node in self.generator.includes_nodes] def run(self): self.outputs = [] srclst = [] slaves = [] for t in self.slaves: if t.hasrun != Task.SKIPPED: slaves.append(t) srclst.append(t.inputs[0].abspath()) self.env.SRCLST = srclst if self.slaves[0].__class__.__name__ == 'c': ret = c_fun(self) else: ret = cxx_fun(self) if ret: return ret for t in slaves: t.old_post_run() def hook(cls_type): def n_hook(self, node): ext = '.obj' if self.env.CC_NAME == 'msvc' else '.o' name = node.name k = name.rfind('.') if k >= 0: basename = name[:k] + ext else: basename = name + ext outdir = node.parent.get_bld().make_node('%d' % self.idx) outdir.mkdir() out = outdir.find_or_declare(basename) task = self.create_task(cls_type, node, out) try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] if not getattr(self, 'masters', None): self.masters = {} self.allmasters = [] def fix_path(tsk): if self.env.CC_NAME == 'msvc': tsk.env.append_unique('CXX_TGT_F_BATCHED', '/Fo%s\\' % outdir.abspath()) if not node.parent in self.masters: m = self.masters[node.parent] = self.master = self.create_task('batch') fix_path(m) self.allmasters.append(m) else: m = self.masters[node.parent] if len(m.slaves) > MAX_BATCH: m = self.masters[node.parent] = self.master = self.create_task('batch') fix_path(m) self.allmasters.append(m) m.add_slave(task) return task return n_hook extension('.c')(hook('c')) extension('.cpp','.cc','.cxx','.C','.c++')(hook('cxx')) @feature('cprogram', 'cshlib', 'cstaticlib', 'cxxprogram', 'cxxshlib', 'cxxstlib') @after_method('apply_link') def link_after_masters(self): if getattr(self, 'allmasters', None): for m in self.allmasters: self.link_task.set_run_after(m) # Modify the c and cxx task classes - in theory it would be best to # create subclasses and to re-map the c/c++ extensions for x in ('c', 'cxx'): t = Task.classes[x] def run(self): pass def post_run(self): pass setattr(t, 'oldrun', getattr(t, 'run', None)) setattr(t, 'run', run) setattr(t, 'old_post_run', t.post_run) setattr(t, 'post_run', post_run) ldb-2.0.8/third_party/waf/waflib/extras/biber.py0000660000000000000000000000313513573675414021554 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 (ita) """ Latex processing using "biber" """ import os from waflib import Task, Logs from waflib.Tools import tex as texmodule class tex(texmodule.tex): biber_fun, _ = Task.compile_fun('${BIBER} ${BIBERFLAGS} ${SRCFILE}',shell=False) biber_fun.__doc__ = """ Execute the program **biber** """ def bibfile(self): return None def bibunits(self): self.env.env = {} self.env.env.update(os.environ) self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) self.env.SRCFILE = self.aux_nodes[0].name[:-4] if not self.env['PROMPT_LATEX']: self.env.append_unique('BIBERFLAGS', '--quiet') path = self.aux_nodes[0].abspath()[:-4] + '.bcf' if os.path.isfile(path): Logs.warn('calling biber') self.check_status('error when calling biber, check %s.blg for errors' % (self.env.SRCFILE), self.biber_fun()) else: super(tex, self).bibfile() super(tex, self).bibunits() class latex(tex): texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False) class pdflatex(tex): texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False) class xelatex(tex): texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False) def configure(self): """ Almost the same as in tex.py, but try to detect 'biber' """ v = self.env for p in ' biber tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split(): try: self.find_program(p, var=p.upper()) except self.errors.ConfigurationError: pass v['DVIPSFLAGS'] = '-Ppdf' ldb-2.0.8/third_party/waf/waflib/extras/bjam.py0000660000000000000000000000746513573675414021414 0ustar rootroot00000000000000#! /usr/bin/env python # per rosengren 2011 from os import sep, readlink from waflib import Logs from waflib.TaskGen import feature, after_method from waflib.Task import Task, always_run def options(opt): grp = opt.add_option_group('Bjam Options') grp.add_option('--bjam_src', default=None, help='You can find it in /tools/jam/src') grp.add_option('--bjam_uname', default='linuxx86_64', help='bjam is built in /bin./bjam') grp.add_option('--bjam_config', default=None) grp.add_option('--bjam_toolset', default=None) def configure(cnf): if not cnf.env.BJAM_SRC: cnf.env.BJAM_SRC = cnf.options.bjam_src if not cnf.env.BJAM_UNAME: cnf.env.BJAM_UNAME = cnf.options.bjam_uname try: cnf.find_program('bjam', path_list=[ cnf.env.BJAM_SRC + sep + 'bin.' + cnf.env.BJAM_UNAME ]) except Exception: cnf.env.BJAM = None if not cnf.env.BJAM_CONFIG: cnf.env.BJAM_CONFIG = cnf.options.bjam_config if not cnf.env.BJAM_TOOLSET: cnf.env.BJAM_TOOLSET = cnf.options.bjam_toolset @feature('bjam') @after_method('process_rule') def process_bjam(self): if not self.bld.env.BJAM: self.create_task('bjam_creator') self.create_task('bjam_build') self.create_task('bjam_installer') if getattr(self, 'always', False): always_run(bjam_creator) always_run(bjam_build) always_run(bjam_installer) class bjam_creator(Task): ext_out = 'bjam_exe' vars=['BJAM_SRC', 'BJAM_UNAME'] def run(self): env = self.env gen = self.generator bjam = gen.bld.root.find_dir(env.BJAM_SRC) if not bjam: Logs.error('Can not find bjam source') return -1 bjam_exe_relpath = 'bin.' + env.BJAM_UNAME + '/bjam' bjam_exe = bjam.find_resource(bjam_exe_relpath) if bjam_exe: env.BJAM = bjam_exe.srcpath() return 0 bjam_cmd = ['./build.sh'] Logs.debug('runner: ' + bjam.srcpath() + '> ' + str(bjam_cmd)) result = self.exec_command(bjam_cmd, cwd=bjam.srcpath()) if not result == 0: Logs.error('bjam failed') return -1 bjam_exe = bjam.find_resource(bjam_exe_relpath) if bjam_exe: env.BJAM = bjam_exe.srcpath() return 0 Logs.error('bjam failed') return -1 class bjam_build(Task): ext_in = 'bjam_exe' ext_out = 'install' vars = ['BJAM_TOOLSET'] def run(self): env = self.env gen = self.generator path = gen.path bld = gen.bld if hasattr(gen, 'root'): build_root = path.find_node(gen.root) else: build_root = path jam = bld.srcnode.find_resource(env.BJAM_CONFIG) if jam: Logs.debug('bjam: Using jam configuration from ' + jam.srcpath()) jam_rel = jam.relpath_gen(build_root) else: Logs.warn('No build configuration in build_config/user-config.jam. Using default') jam_rel = None bjam_exe = bld.srcnode.find_node(env.BJAM) if not bjam_exe: Logs.error('env.BJAM is not set') return -1 bjam_exe_rel = bjam_exe.relpath_gen(build_root) cmd = ([bjam_exe_rel] + (['--user-config=' + jam_rel] if jam_rel else []) + ['--stagedir=' + path.get_bld().path_from(build_root)] + ['--debug-configuration'] + ['--with-' + lib for lib in self.generator.target] + (['toolset=' + env.BJAM_TOOLSET] if env.BJAM_TOOLSET else []) + ['link=' + 'shared'] + ['variant=' + 'release'] ) Logs.debug('runner: ' + build_root.srcpath() + '> ' + str(cmd)) ret = self.exec_command(cmd, cwd=build_root.srcpath()) if ret != 0: return ret self.set_outputs(path.get_bld().ant_glob('lib/*') + path.get_bld().ant_glob('bin/*')) return 0 class bjam_installer(Task): ext_in = 'install' def run(self): gen = self.generator path = gen.path for idir, pat in (('${LIBDIR}', 'lib/*'), ('${BINDIR}', 'bin/*')): files = [] for n in path.get_bld().ant_glob(pat): try: t = readlink(n.srcpath()) gen.bld.symlink_as(sep.join([idir, n.name]), t, postpone=False) except OSError: files.append(n) gen.bld.install_files(idir, files, postpone=False) return 0 ldb-2.0.8/third_party/waf/waflib/extras/blender.py0000660000000000000000000000577513573675414022120 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Michal Proszek, 2014 (poxip) """ Detect the version of Blender, path and install the extension: def options(opt): opt.load('blender') def configure(cnf): cnf.load('blender') def build(bld): bld(name='io_mesh_raw', feature='blender', files=['file1.py', 'file2.py'] ) If name variable is empty, files are installed in scripts/addons, otherwise scripts/addons/name Use ./waf configure --system to set the installation directory to system path """ import os import re from getpass import getuser from waflib import Utils from waflib.TaskGen import feature from waflib.Configure import conf def options(opt): opt.add_option( '-s', '--system', dest='directory_system', default=False, action='store_true', help='determines installation directory (default: user)' ) @conf def find_blender(ctx): '''Return version number of blender, if not exist return None''' blender = ctx.find_program('blender') output = ctx.cmd_and_log(blender + ['--version']) m = re.search(r'Blender\s*((\d+(\.|))*)', output) if not m: ctx.fatal('Could not retrieve blender version') try: blender_version = m.group(1) except IndexError: ctx.fatal('Could not retrieve blender version') ctx.env['BLENDER_VERSION'] = blender_version return blender @conf def configure_paths(ctx): """Setup blender paths""" # Get the username user = getuser() _platform = Utils.unversioned_sys_platform() config_path = {'user': '', 'system': ''} if _platform.startswith('linux'): config_path['user'] = '/home/%s/.config/blender/' % user config_path['system'] = '/usr/share/blender/' elif _platform == 'darwin': # MAC OS X config_path['user'] = \ '/Users/%s/Library/Application Support/Blender/' % user config_path['system'] = '/Library/Application Support/Blender/' elif Utils.is_win32: # Windows appdata_path = ctx.getenv('APPDATA').replace('\\', '/') homedrive = ctx.getenv('HOMEDRIVE').replace('\\', '/') config_path['user'] = '%s/Blender Foundation/Blender/' % appdata_path config_path['system'] = \ '%sAll Users/AppData/Roaming/Blender Foundation/Blender/' % homedrive else: ctx.fatal( 'Unsupported platform. ' 'Available platforms: Linux, OSX, MS-Windows.' ) blender_version = ctx.env['BLENDER_VERSION'] config_path['user'] += blender_version + '/' config_path['system'] += blender_version + '/' ctx.env['BLENDER_CONFIG_DIR'] = os.path.abspath(config_path['user']) if ctx.options.directory_system: ctx.env['BLENDER_CONFIG_DIR'] = config_path['system'] ctx.env['BLENDER_ADDONS_DIR'] = os.path.join( ctx.env['BLENDER_CONFIG_DIR'], 'scripts/addons' ) Utils.check_dir(ctx.env['BLENDER_ADDONS_DIR']) def configure(ctx): ctx.find_blender() ctx.configure_paths() @feature('blender_list') def blender(self): # Two ways to install a blender extension: as a module or just .py files dest_dir = os.path.join(self.env.BLENDER_ADDONS_DIR, self.get_name()) Utils.check_dir(dest_dir) self.add_install_files(install_to=dest_dir, install_from=getattr(self, 'files', '.')) ldb-2.0.8/third_party/waf/waflib/extras/boo.py0000660000000000000000000000435013573675414021250 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Yannick LM 2011 """ Support for the boo programming language, for example:: bld(features = "boo", # necessary feature source = "src.boo", # list of boo files gen = "world.dll", # target type = "library", # library/exe ("-target:xyz" flag) name = "world" # necessary if the target is referenced by 'use' ) """ from waflib import Task from waflib.Configure import conf from waflib.TaskGen import feature, after_method, before_method, extension @extension('.boo') def boo_hook(self, node): # Nothing here yet ... # TODO filter the non-boo source files in 'apply_booc' and remove this method pass @feature('boo') @before_method('process_source') def apply_booc(self): """Create a booc task """ src_nodes = self.to_nodes(self.source) out_node = self.path.find_or_declare(self.gen) self.boo_task = self.create_task('booc', src_nodes, [out_node]) # Set variables used by the 'booc' task self.boo_task.env.OUT = '-o:%s' % out_node.abspath() # type is "exe" by default type = getattr(self, "type", "exe") self.boo_task.env.BOO_TARGET_TYPE = "-target:%s" % type @feature('boo') @after_method('apply_boo') def use_boo(self): """" boo applications honor the **use** keyword:: """ dep_names = self.to_list(getattr(self, 'use', [])) for dep_name in dep_names: dep_task_gen = self.bld.get_tgen_by_name(dep_name) if not dep_task_gen: continue dep_task_gen.post() dep_task = getattr(dep_task_gen, 'boo_task', None) if not dep_task: # Try a cs task: dep_task = getattr(dep_task_gen, 'cs_task', None) if not dep_task: # Try a link task: dep_task = getattr(dep_task, 'link_task', None) if not dep_task: # Abort ... continue self.boo_task.set_run_after(dep_task) # order self.boo_task.dep_nodes.extend(dep_task.outputs) # dependency self.boo_task.env.append_value('BOO_FLAGS', '-reference:%s' % dep_task.outputs[0].abspath()) class booc(Task.Task): """Compiles .boo files """ color = 'YELLOW' run_str = '${BOOC} ${BOO_FLAGS} ${BOO_TARGET_TYPE} ${OUT} ${SRC}' @conf def check_booc(self): self.find_program('booc', 'BOOC') self.env.BOO_FLAGS = ['-nologo'] def configure(self): """Check that booc is available """ self.check_booc() ldb-2.0.8/third_party/waf/waflib/extras/boost.py0000660000000000000000000004402513573675414021622 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # # partially based on boost.py written by Gernot Vormayr # written by Ruediger Sonderfeld , 2008 # modified by Bjoern Michaelsen, 2008 # modified by Luca Fossati, 2008 # rewritten for waf 1.5.1, Thomas Nagy, 2008 # rewritten for waf 1.6.2, Sylvain Rouquette, 2011 ''' This is an extra tool, not bundled with the default waf binary. To add the boost tool to the waf file: $ ./waf-light --tools=compat15,boost or, if you have waf >= 1.6.2 $ ./waf update --files=boost When using this tool, the wscript will look like: def options(opt): opt.load('compiler_cxx boost') def configure(conf): conf.load('compiler_cxx boost') conf.check_boost(lib='system filesystem') def build(bld): bld(source='main.cpp', target='app', use='BOOST') Options are generated, in order to specify the location of boost includes/libraries. The `check_boost` configuration function allows to specify the used boost libraries. It can also provide default arguments to the --boost-mt command-line arguments. Everything will be packaged together in a BOOST component that you can use. When using MSVC, a lot of compilation flags need to match your BOOST build configuration: - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined. Errors: C4530 - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC So before calling `conf.check_boost` you might want to disabling by adding conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB'] Errors: - boost might also be compiled with /MT, which links the runtime statically. If you have problems with redefined symbols, self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc'] Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases. ''' import sys import re from waflib import Utils, Logs, Errors from waflib.Configure import conf from waflib.TaskGen import feature, after_method BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib'] BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include'] BOOST_VERSION_FILE = 'boost/version.hpp' BOOST_VERSION_CODE = ''' #include #include int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; } ''' BOOST_ERROR_CODE = ''' #include int main() { boost::system::error_code c; } ''' PTHREAD_CODE = ''' #include static void* f(void*) { return 0; } int main() { pthread_t th; pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&th, &attr, &f, 0); pthread_join(th, 0); pthread_cleanup_push(0, 0); pthread_cleanup_pop(0); pthread_attr_destroy(&attr); } ''' BOOST_THREAD_CODE = ''' #include int main() { boost::thread t; } ''' BOOST_LOG_CODE = ''' #include #include #include int main() { using namespace boost::log; add_common_attributes(); add_console_log(std::clog, keywords::format = "%Message%"); BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl; } ''' # toolsets from {boost_dir}/tools/build/v2/tools/common.jam PLATFORM = Utils.unversioned_sys_platform() detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il' detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang' detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc' BOOST_TOOLSETS = { 'borland': 'bcb', 'clang': detect_clang, 'como': 'como', 'cw': 'cw', 'darwin': 'xgcc', 'edg': 'edg', 'g++': detect_mingw, 'gcc': detect_mingw, 'icpc': detect_intel, 'intel': detect_intel, 'kcc': 'kcc', 'kylix': 'bck', 'mipspro': 'mp', 'mingw': 'mgw', 'msvc': 'vc', 'qcc': 'qcc', 'sun': 'sw', 'sunc++': 'sw', 'tru64cxx': 'tru', 'vacpp': 'xlc' } def options(opt): opt = opt.add_option_group('Boost Options') opt.add_option('--boost-includes', type='string', default='', dest='boost_includes', help='''path to the directory where the boost includes are, e.g., /path/to/boost_1_55_0/stage/include''') opt.add_option('--boost-libs', type='string', default='', dest='boost_libs', help='''path to the directory where the boost libs are, e.g., path/to/boost_1_55_0/stage/lib''') opt.add_option('--boost-mt', action='store_true', default=False, dest='boost_mt', help='select multi-threaded libraries') opt.add_option('--boost-abi', type='string', default='', dest='boost_abi', help='''select libraries with tags (gd for debug, static is automatically added), see doc Boost, Getting Started, chapter 6.1''') opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect', help="auto-detect boost linkage options (don't get used to it / might break other stuff)") opt.add_option('--boost-toolset', type='string', default='', dest='boost_toolset', help='force a toolset e.g. msvc, vc90, \ gcc, mingw, mgw45 (default: auto)') py_version = '%d%d' % (sys.version_info[0], sys.version_info[1]) opt.add_option('--boost-python', type='string', default=py_version, dest='boost_python', help='select the lib python with this version \ (default: %s)' % py_version) @conf def __boost_get_version_file(self, d): if not d: return None dnode = self.root.find_dir(d) if dnode: return dnode.find_node(BOOST_VERSION_FILE) return None @conf def boost_get_version(self, d): """silently retrieve the boost version number""" node = self.__boost_get_version_file(d) if node: try: txt = node.read() except EnvironmentError: Logs.error("Could not read the file %r", node.abspath()) else: re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M) m1 = re_but1.search(txt) re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M) m2 = re_but2.search(txt) if m1 and m2: return (m1.group(1), m2.group(1)) return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":") @conf def boost_get_includes(self, *k, **kw): includes = k and k[0] or kw.get('includes') if includes and self.__boost_get_version_file(includes): return includes for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES: if self.__boost_get_version_file(d): return d if includes: self.end_msg('headers not found in %s' % includes) self.fatal('The configuration failed') else: self.end_msg('headers not found, please provide a --boost-includes argument (see help)') self.fatal('The configuration failed') @conf def boost_get_toolset(self, cc): toolset = cc if not cc: build_platform = Utils.unversioned_sys_platform() if build_platform in BOOST_TOOLSETS: cc = build_platform else: cc = self.env.CXX_NAME if cc in BOOST_TOOLSETS: toolset = BOOST_TOOLSETS[cc] return isinstance(toolset, str) and toolset or toolset(self.env) @conf def __boost_get_libs_path(self, *k, **kw): ''' return the lib path and all the files in it ''' if 'files' in kw: return self.root.find_dir('.'), Utils.to_list(kw['files']) libs = k and k[0] or kw.get('libs') if libs: path = self.root.find_dir(libs) files = path.ant_glob('*boost_*') if not libs or not files: for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS: if not d: continue path = self.root.find_dir(d) if path: files = path.ant_glob('*boost_*') if files: break path = self.root.find_dir(d + '64') if path: files = path.ant_glob('*boost_*') if files: break if not path: if libs: self.end_msg('libs not found in %s' % libs) self.fatal('The configuration failed') else: self.end_msg('libs not found, please provide a --boost-libs argument (see help)') self.fatal('The configuration failed') self.to_log('Found the boost path in %r with the libraries:' % path) for x in files: self.to_log(' %r' % x) return path, files @conf def boost_get_libs(self, *k, **kw): ''' return the lib path and the required libs according to the parameters ''' path, files = self.__boost_get_libs_path(**kw) files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True) toolset = self.boost_get_toolset(kw.get('toolset', '')) toolset_pat = '(-%s[0-9]{0,3})' % toolset version = '-%s' % self.env.BOOST_VERSION def find_lib(re_lib, files): for file in files: if re_lib.search(file.name): self.to_log('Found boost lib %s' % file) return file return None def format_lib_name(name): if name.startswith('lib') and self.env.CC_NAME != 'msvc': name = name[3:] return name[:name.rfind('.')] def match_libs(lib_names, is_static): libs = [] lib_names = Utils.to_list(lib_names) if not lib_names: return libs t = [] if kw.get('mt', False): t.append('-mt') if kw.get('abi'): t.append('%s%s' % (is_static and '-s' or '-', kw['abi'])) elif is_static: t.append('-s') tags_pat = t and ''.join(t) or '' ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN for lib in lib_names: if lib == 'python': # for instance, with python='27', # accepts '-py27', '-py2', '27', '-2.7' and '2' # but will reject '-py3', '-py26', '26' and '3' tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|(-{1}.{3})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'], kw['python'][1]) else: tags = tags_pat # Trying libraries, from most strict match to least one for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext), 'boost_%s%s%s%s$' % (lib, tags, version, ext), # Give up trying to find the right version 'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext), 'boost_%s%s%s$' % (lib, tags, ext), 'boost_%s%s$' % (lib, ext), 'boost_%s' % lib]: self.to_log('Trying pattern %s' % pattern) file = find_lib(re.compile(pattern), files) if file: libs.append(format_lib_name(file.name)) break else: self.end_msg('lib %s not found in %s' % (lib, path.abspath())) self.fatal('The configuration failed') return libs return path.abspath(), match_libs(kw.get('lib'), False), match_libs(kw.get('stlib'), True) @conf def _check_pthread_flag(self, *k, **kw): ''' Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3, boost/thread.hpp will trigger a #error if -pthread isn't used: boost/config/requires_threads.hpp:47:5: #error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4 ''' var = kw.get('uselib_store', 'BOOST') self.start_msg('Checking the flags needed to use pthreads') # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # (none): in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -lpthreads: AIX (must check this before -lpthread) # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads) # -pthreads: Solaris/GCC # -mthreads: MinGW32/GCC, Lynx/GCC # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # -lpthread: GNU Linux, etc. # --thread-safe: KAI C++ if Utils.unversioned_sys_platform() == "sunos": # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"] else: boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread", "-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"] for boost_pthread_flag in boost_pthread_flags: try: self.env.stash() self.env.append_value('CXXFLAGS_%s' % var, boost_pthread_flag) self.env.append_value('LINKFLAGS_%s' % var, boost_pthread_flag) self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False) self.end_msg(boost_pthread_flag) return except self.errors.ConfigurationError: self.env.revert() self.end_msg('None') @conf def check_boost(self, *k, **kw): """ Initialize boost libraries to be used. Keywords: you can pass the same parameters as with the command line (without "--boost-"). Note that the command line has the priority, and should preferably be used. """ if not self.env['CXX']: self.fatal('load a c++ compiler first, conf.load("compiler_cxx")') params = { 'lib': k and k[0] or kw.get('lib'), 'stlib': kw.get('stlib') } for key, value in self.options.__dict__.items(): if not key.startswith('boost_'): continue key = key[len('boost_'):] params[key] = value and value or kw.get(key, '') var = kw.get('uselib_store', 'BOOST') self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False) if self.env.DPKG_ARCHITECTURE: deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH']) BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip()) self.start_msg('Checking boost includes') self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params) versions = self.boost_get_version(inc) self.env.BOOST_VERSION = versions[0] self.env.BOOST_VERSION_NUMBER = int(versions[1]) self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000, int(versions[1]) / 100 % 1000, int(versions[1]) % 100)) if Logs.verbose: Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var]) if not params['lib'] and not params['stlib']: return if 'static' in kw or 'static' in params: Logs.warn('boost: static parameter is deprecated, use stlib instead.') self.start_msg('Checking boost libs') path, libs, stlibs = self.boost_get_libs(**params) self.env['LIBPATH_%s' % var] = [path] self.env['STLIBPATH_%s' % var] = [path] self.env['LIB_%s' % var] = libs self.env['STLIB_%s' % var] = stlibs self.end_msg('ok') if Logs.verbose: Logs.pprint('CYAN', ' path : %s' % path) Logs.pprint('CYAN', ' shared libs : %s' % libs) Logs.pprint('CYAN', ' static libs : %s' % stlibs) def has_shlib(lib): return params['lib'] and lib in params['lib'] def has_stlib(lib): return params['stlib'] and lib in params['stlib'] def has_lib(lib): return has_shlib(lib) or has_stlib(lib) if has_lib('thread'): # not inside try_link to make check visible in the output self._check_pthread_flag(k, kw) def try_link(): if has_lib('system'): self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False) if has_lib('thread'): self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False) if has_lib('log'): if not has_lib('thread'): self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS'] if has_shlib('log'): self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK'] self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False) if params.get('linkage_autodetect', False): self.start_msg("Attempting to detect boost linkage flags") toolset = self.boost_get_toolset(kw.get('toolset', '')) if toolset in ('vc',): # disable auto-linking feature, causing error LNK1181 # because the code wants to be linked against self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] # if no dlls are present, we guess the .lib files are not stubs has_dlls = False for x in Utils.listdir(path): if x.endswith(self.env.cxxshlib_PATTERN % ''): has_dlls = True break if not has_dlls: self.env['STLIBPATH_%s' % var] = [path] self.env['STLIB_%s' % var] = libs del self.env['LIB_%s' % var] del self.env['LIBPATH_%s' % var] # we attempt to play with some known-to-work CXXFLAGS combinations for cxxflags in (['/MD', '/EHsc'], []): self.env.stash() self.env["CXXFLAGS_%s" % var] += cxxflags try: try_link() except Errors.ConfigurationError as e: self.env.revert() exc = e else: self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var])) exc = None self.env.commit() break if exc is not None: self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc) self.fatal('The configuration failed') else: self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain") self.fatal('The configuration failed') else: self.start_msg('Checking for boost linkage') try: try_link() except Errors.ConfigurationError as e: self.end_msg("Could not link against boost libraries using supplied options") self.fatal('The configuration failed') self.end_msg('ok') @feature('cxx') @after_method('apply_link') def install_boost(self): if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'): return install_boost.done = True inst_to = getattr(self, 'install_path', '${BINDIR}') for lib in self.env.LIB_BOOST: try: file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST) self.add_install_files(install_to=inst_to, install_from=self.bld.root.find_node(file)) except: continue install_boost.done = False ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py0000660000000000000000000000160213573675414024277 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2015 """ Force files to depend on the timestamps of those located in the build directory. You may want to use this to force partial rebuilds, see playground/track_output_files/ for a working example. Note that there is a variety of ways to implement this, one may want use timestamps on source files too for example, or one may want to hash the files in the source directory only under certain conditions (md5_tstamp tool) or to hash the file in the build directory with its timestamp """ import os from waflib import Node, Utils def get_bld_sig(self): if not self.is_bld() or self.ctx.bldnode is self.ctx.srcnode: return Utils.h_file(self.abspath()) try: # add the creation time to the signature return self.sig + str(os.stat(self.abspath()).st_mtime) except AttributeError: return None Node.Node.get_bld_sig = get_bld_sig ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py0000660000000000000000000000541013573675414022612 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2013 (ita) """ A system for recording all outputs to a log file. Just add the following to your wscript file:: def init(ctx): ctx.load('build_logs') """ import atexit, sys, time, os, shutil, threading from waflib import ansiterm, Logs, Context # adding the logs under the build/ directory will clash with the clean/ command try: up = os.path.dirname(Context.g_module.__file__) except AttributeError: up = '.' LOGFILE = os.path.join(up, 'logs', time.strftime('%Y_%m_%d_%H_%M.log')) wlock = threading.Lock() class log_to_file(object): def __init__(self, stream, fileobj, filename): self.stream = stream self.encoding = self.stream.encoding self.fileobj = fileobj self.filename = filename self.is_valid = True def replace_colors(self, data): for x in Logs.colors_lst.values(): if isinstance(x, str): data = data.replace(x, '') return data def write(self, data): try: wlock.acquire() self.stream.write(data) self.stream.flush() if self.is_valid: self.fileobj.write(self.replace_colors(data)) finally: wlock.release() def fileno(self): return self.stream.fileno() def flush(self): self.stream.flush() if self.is_valid: self.fileobj.flush() def isatty(self): return self.stream.isatty() def init(ctx): global LOGFILE filename = os.path.abspath(LOGFILE) try: os.makedirs(os.path.dirname(os.path.abspath(filename))) except OSError: pass if hasattr(os, 'O_NOINHERIT'): fd = os.open(LOGFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT) fileobj = os.fdopen(fd, 'w') else: fileobj = open(LOGFILE, 'w') old_stderr = sys.stderr # sys.stdout has already been replaced, so __stdout__ will be faster #sys.stdout = log_to_file(sys.stdout, fileobj, filename) #sys.stderr = log_to_file(sys.stderr, fileobj, filename) def wrap(stream): if stream.isatty(): return ansiterm.AnsiTerm(stream) return stream sys.stdout = log_to_file(wrap(sys.__stdout__), fileobj, filename) sys.stderr = log_to_file(wrap(sys.__stderr__), fileobj, filename) # now mess with the logging module... for x in Logs.log.handlers: try: stream = x.stream except AttributeError: pass else: if id(stream) == id(old_stderr): x.stream = sys.stderr def exit_cleanup(): try: fileobj = sys.stdout.fileobj except AttributeError: pass else: sys.stdout.is_valid = False sys.stderr.is_valid = False fileobj.close() filename = sys.stdout.filename Logs.info('Output logged to %r', filename) # then copy the log file to "latest.log" if possible up = os.path.dirname(os.path.abspath(filename)) try: shutil.copy(filename, os.path.join(up, 'latest.log')) except OSError: # this may fail on windows due to processes spawned pass atexit.register(exit_cleanup) ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py0000660000000000000000000000526013573675414022464 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Calle Rosenquist, 2017 (xbreak) """ Create task that copies source files to the associated build node. This is useful to e.g. construct a complete Python package so it can be unit tested without installation. Source files to be copied can be specified either in `buildcopy_source` attribute, or `source` attribute. If both are specified `buildcopy_source` has priority. Examples:: def build(bld): bld(name = 'bar', features = 'py buildcopy', source = bld.path.ant_glob('src/bar/*.py')) bld(name = 'py baz', features = 'buildcopy', buildcopy_source = bld.path.ant_glob('src/bar/*.py') + ['src/bar/resource.txt']) """ import os, shutil from waflib import Errors, Task, TaskGen, Utils, Node, Logs @TaskGen.before_method('process_source') @TaskGen.feature('buildcopy') def make_buildcopy(self): """ Creates the buildcopy task. """ def to_src_nodes(lst): """Find file nodes only in src, TaskGen.to_nodes will not work for this since it gives preference to nodes in build. """ if isinstance(lst, Node.Node): if not lst.is_src(): raise Errors.WafError('buildcopy: node %s is not in src'%lst) if not os.path.isfile(lst.abspath()): raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%lst) return lst if isinstance(lst, str): lst = [x for x in Utils.split_path(lst) if x and x != '.'] node = self.bld.path.get_src().search_node(lst) if node: if not os.path.isfile(node.abspath()): raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%node) return node node = self.bld.path.get_src().find_node(lst) if node: if not os.path.isfile(node.abspath()): raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%node) return node raise Errors.WafError('buildcopy: File not found in src: %s'%os.path.join(*lst)) nodes = [ to_src_nodes(n) for n in getattr(self, 'buildcopy_source', getattr(self, 'source', [])) ] if not nodes: Logs.warn('buildcopy: No source files provided to buildcopy in %s (set `buildcopy_source` or `source`)', self) return node_pairs = [(n, n.get_bld()) for n in nodes] self.create_task('buildcopy', [n[0] for n in node_pairs], [n[1] for n in node_pairs], node_pairs=node_pairs) class buildcopy(Task.Task): """ Copy for each pair `n` in `node_pairs`: n[0] -> n[1]. Attribute `node_pairs` should contain a list of tuples describing source and target: node_pairs = [(in, out), ...] """ color = 'PINK' def keyword(self): return 'Copying' def run(self): for f,t in self.node_pairs: t.parent.mkdir() shutil.copy2(f.abspath(), t.abspath()) ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py0000660000000000000000000000130213573675414022064 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de """ IBM XL Compiler for Blue Gene """ from waflib.Tools import ccroot,ar from waflib.Configure import conf from waflib.Tools import xlc # method xlc_common_flags from waflib.Tools.compiler_c import c_compiler c_compiler['linux'].append('c_bgxlc') @conf def find_bgxlc(conf): cc = conf.find_program(['bgxlc_r','bgxlc'], var='CC') conf.get_xlc_version(cc) conf.env.CC = cc conf.env.CC_NAME = 'bgxlc' def configure(conf): conf.find_bgxlc() conf.find_ar() conf.xlc_common_flags() conf.env.LINKFLAGS_cshlib = ['-G','-Wl,-bexpfull'] conf.env.LINKFLAGS_cprogram = [] conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py0000660000000000000000000000316213573675414023315 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) """ Dumb C/C++ preprocessor for finding dependencies It will look at all include files it can find after removing the comments, so the following will always add the dependency on both "a.h" and "b.h":: #include "a.h" #ifdef B #include "b.h" #endif int main() { return 0; } To use:: def configure(conf): conf.load('compiler_c') conf.load('c_dumbpreproc') """ import re from waflib.Tools import c_preproc re_inc = re.compile( '^[ \t]*(#|%:)[ \t]*(include)[ \t]*[<"](.*)[>"]\r*$', re.IGNORECASE | re.MULTILINE) def lines_includes(node): code = node.read() if c_preproc.use_trigraphs: for (a, b) in c_preproc.trig_def: code = code.split(a).join(b) code = c_preproc.re_nl.sub('', code) code = c_preproc.re_cpp.sub(c_preproc.repl, code) return [(m.group(2), m.group(3)) for m in re.finditer(re_inc, code)] parser = c_preproc.c_parser class dumb_parser(parser): def addlines(self, node): if node in self.nodes[:-1]: return self.currentnode_stack.append(node.parent) # Avoid reading the same files again try: lines = self.parse_cache[node] except KeyError: lines = self.parse_cache[node] = lines_includes(node) self.lines = lines + [(c_preproc.POPFILE, '')] + self.lines def start(self, node, env): try: self.parse_cache = node.ctx.parse_cache except AttributeError: self.parse_cache = node.ctx.parse_cache = {} self.addlines(node) while self.lines: (x, y) = self.lines.pop(0) if x == c_preproc.POPFILE: self.currentnode_stack.pop() continue self.tryfind(y) c_preproc.c_parser = dumb_parser ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py0000660000000000000000000000474013573675414023147 0ustar rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 vi:ts=4:noexpandtab import subprocess, shlex, sys from waflib.Tools import ccroot, gcc, gxx from waflib.Configure import conf from waflib.TaskGen import after_method, feature from waflib.Tools.compiler_c import c_compiler from waflib.Tools.compiler_cxx import cxx_compiler for supported_os in ('linux', 'darwin', 'gnu', 'aix'): c_compiler[supported_os].append('c_emscripten') cxx_compiler[supported_os].append('c_emscripten') @conf def get_emscripten_version(conf, cc): """ Emscripten doesn't support processing '-' like clang/gcc """ dummy = conf.cachedir.parent.make_node("waf-emscripten.c") dummy.write("") cmd = cc + ['-dM', '-E', '-x', 'c', dummy.abspath()] env = conf.env.env or None try: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) out = p.communicate()[0] except Exception as e: conf.fatal('Could not determine emscripten version %r: %s' % (cmd, e)) if not isinstance(out, str): out = out.decode(sys.stdout.encoding or 'latin-1') k = {} out = out.splitlines() for line in out: lst = shlex.split(line) if len(lst)>2: key = lst[1] val = lst[2] k[key] = val if not ('__clang__' in k and 'EMSCRIPTEN' in k): conf.fatal('Could not determine the emscripten compiler version.') conf.env.DEST_OS = 'generic' conf.env.DEST_BINFMT = 'elf' conf.env.DEST_CPU = 'asm-js' conf.env.CC_VERSION = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) return k @conf def find_emscripten(conf): cc = conf.find_program(['emcc'], var='CC') conf.get_emscripten_version(cc) conf.env.CC = cc conf.env.CC_NAME = 'emscripten' cxx = conf.find_program(['em++'], var='CXX') conf.env.CXX = cxx conf.env.CXX_NAME = 'emscripten' conf.find_program(['emar'], var='AR') def configure(conf): conf.find_emscripten() conf.find_ar() conf.gcc_common_flags() conf.gxx_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() conf.env.ARFLAGS = ['rcs'] conf.env.cshlib_PATTERN = '%s.js' conf.env.cxxshlib_PATTERN = '%s.js' conf.env.cstlib_PATTERN = '%s.a' conf.env.cxxstlib_PATTERN = '%s.a' conf.env.cprogram_PATTERN = '%s.html' conf.env.cxxprogram_PATTERN = '%s.html' conf.env.CXX_TGT_F = ['-c', '-o', ''] conf.env.CC_TGT_F = ['-c', '-o', ''] conf.env.CXXLNK_TGT_F = ['-o', ''] conf.env.CCLNK_TGT_F = ['-o', ''] conf.env.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py0000660000000000000000000000337513573675414021546 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de """ NEC SX Compiler for SX vector systems """ import re from waflib import Utils from waflib.Tools import ccroot,ar from waflib.Configure import conf from waflib.Tools import xlc # method xlc_common_flags from waflib.Tools.compiler_c import c_compiler c_compiler['linux'].append('c_nec') @conf def find_sxc(conf): cc = conf.find_program(['sxcc'], var='CC') conf.get_sxc_version(cc) conf.env.CC = cc conf.env.CC_NAME = 'sxcc' @conf def get_sxc_version(conf, fc): version_re = re.compile(r"C\+\+/SX\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search cmd = fc + ['-V'] p = Utils.subprocess.Popen(cmd, stdin=False, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=None) out, err = p.communicate() if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not determine the NEC C compiler version.') k = match.groupdict() conf.env['C_VERSION'] = (k['major'], k['minor']) @conf def sxc_common_flags(conf): v=conf.env v['CC_SRC_F']=[] v['CC_TGT_F']=['-c','-o'] if not v['LINK_CC']: v['LINK_CC']=v['CC'] v['CCLNK_SRC_F']=[] v['CCLNK_TGT_F']=['-o'] v['CPPPATH_ST']='-I%s' v['DEFINES_ST']='-D%s' v['LIB_ST']='-l%s' v['LIBPATH_ST']='-L%s' v['STLIB_ST']='-l%s' v['STLIBPATH_ST']='-L%s' v['RPATH_ST']='' v['SONAME_ST']=[] v['SHLIB_MARKER']=[] v['STLIB_MARKER']=[] v['LINKFLAGS_cprogram']=[''] v['cprogram_PATTERN']='%s' v['CFLAGS_cshlib']=['-fPIC'] v['LINKFLAGS_cshlib']=[''] v['cshlib_PATTERN']='lib%s.so' v['LINKFLAGS_cstlib']=[] v['cstlib_PATTERN']='lib%s.a' def configure(conf): conf.find_sxc() conf.find_program('sxar',VAR='AR') conf.sxc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/extras/cabal.py0000660000000000000000000001205513573675414021534 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Anton Feldmann, 2012 # "Base for cabal" from waflib import Task, Utils from waflib.TaskGen import extension from waflib.Utils import threading from shutil import rmtree lock = threading.Lock() registering = False def configure(self): self.find_program('cabal', var='CABAL') self.find_program('ghc-pkg', var='GHCPKG') pkgconfd = self.bldnode.abspath() + '/package.conf.d' self.env.PREFIX = self.bldnode.abspath() + '/dist' self.env.PKGCONFD = pkgconfd if self.root.find_node(pkgconfd + '/package.cache'): self.msg('Using existing package database', pkgconfd, color='CYAN') else: pkgdir = self.root.find_dir(pkgconfd) if pkgdir: self.msg('Deleting corrupt package database', pkgdir.abspath(), color ='RED') rmtree(pkgdir.abspath()) pkgdir = None self.cmd_and_log(self.env.GHCPKG + ['init', pkgconfd]) self.msg('Created package database', pkgconfd, color = 'YELLOW' if pkgdir else 'GREEN') @extension('.cabal') def process_cabal(self, node): out_dir_node = self.bld.root.find_dir(self.bld.out_dir) package_node = node.change_ext('.package') package_node = out_dir_node.find_or_declare(package_node.name) build_node = node.parent.get_bld() build_path = build_node.abspath() config_node = build_node.find_or_declare('setup-config') inplace_node = build_node.find_or_declare('package.conf.inplace') config_task = self.create_task('cabal_configure', node) config_task.cwd = node.parent.abspath() config_task.depends_on = getattr(self, 'depends_on', '') config_task.build_path = build_path config_task.set_outputs(config_node) build_task = self.create_task('cabal_build', config_node) build_task.cwd = node.parent.abspath() build_task.build_path = build_path build_task.set_outputs(inplace_node) copy_task = self.create_task('cabal_copy', inplace_node) copy_task.cwd = node.parent.abspath() copy_task.depends_on = getattr(self, 'depends_on', '') copy_task.build_path = build_path last_task = copy_task task_list = [config_task, build_task, copy_task] if (getattr(self, 'register', False)): register_task = self.create_task('cabal_register', inplace_node) register_task.cwd = node.parent.abspath() register_task.set_run_after(copy_task) register_task.build_path = build_path pkgreg_task = self.create_task('ghcpkg_register', inplace_node) pkgreg_task.cwd = node.parent.abspath() pkgreg_task.set_run_after(register_task) pkgreg_task.build_path = build_path last_task = pkgreg_task task_list += [register_task, pkgreg_task] touch_task = self.create_task('cabal_touch', inplace_node) touch_task.set_run_after(last_task) touch_task.set_outputs(package_node) touch_task.build_path = build_path task_list += [touch_task] return task_list def get_all_src_deps(node): hs_deps = node.ant_glob('**/*.hs') hsc_deps = node.ant_glob('**/*.hsc') lhs_deps = node.ant_glob('**/*.lhs') c_deps = node.ant_glob('**/*.c') cpp_deps = node.ant_glob('**/*.cpp') proto_deps = node.ant_glob('**/*.proto') return sum([hs_deps, hsc_deps, lhs_deps, c_deps, cpp_deps, proto_deps], []) class Cabal(Task.Task): def scan(self): return (get_all_src_deps(self.generator.path), ()) class cabal_configure(Cabal): run_str = '${CABAL} configure -v0 --prefix=${PREFIX} --global --user --package-db=${PKGCONFD} --builddir=${tsk.build_path}' shell = True def scan(self): out_node = self.generator.bld.root.find_dir(self.generator.bld.out_dir) deps = [out_node.find_or_declare(dep).change_ext('.package') for dep in Utils.to_list(self.depends_on)] return (deps, ()) class cabal_build(Cabal): run_str = '${CABAL} build -v1 --builddir=${tsk.build_path}/' shell = True class cabal_copy(Cabal): run_str = '${CABAL} copy -v0 --builddir=${tsk.build_path}' shell = True class cabal_register(Cabal): run_str = '${CABAL} register -v0 --gen-pkg-config=${tsk.build_path}/pkg.config --builddir=${tsk.build_path}' shell = True class ghcpkg_register(Cabal): run_str = '${GHCPKG} update -v0 --global --user --package-conf=${PKGCONFD} ${tsk.build_path}/pkg.config' shell = True def runnable_status(self): global lock, registering val = False lock.acquire() val = registering lock.release() if val: return Task.ASK_LATER ret = Task.Task.runnable_status(self) if ret == Task.RUN_ME: lock.acquire() registering = True lock.release() return ret def post_run(self): global lock, registering lock.acquire() registering = False lock.release() return Task.Task.post_run(self) class cabal_touch(Cabal): run_str = 'touch ${TGT}' ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py0000660000000000000000000000541113573675414023503 0ustar rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Tool to extend c_config.check_cfg() __author__ = __maintainer__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2014" """ This tool allows to work around the absence of ``*-config`` programs on systems, by keeping the same clean configuration syntax but inferring values or permitting their modification via the options interface. Note that pkg-config can also support setting ``PKG_CONFIG_PATH``, so you can put custom files in a folder containing new .pc files. This tool could also be implemented by taking advantage of this fact. Usage:: def options(opt): opt.load('c_config_alt') opt.add_package_option('package') def configure(cfg): conf.load('c_config_alt') conf.check_cfg(...) Known issues: - Behavior with different build contexts... """ import os import functools from waflib import Configure, Options, Errors def name_to_dest(x): return x.lower().replace('-', '_') def options(opt): def x(opt, param): dest = name_to_dest(param) gr = opt.get_option_group("configure options") gr.add_option('--%s-root' % dest, help="path containing include and lib subfolders for %s" \ % param, ) opt.add_package_option = functools.partial(x, opt) check_cfg_old = getattr(Configure.ConfigurationContext, 'check_cfg') @Configure.conf def check_cfg(conf, *k, **kw): if k: lst = k[0].split() kw['package'] = lst[0] kw['args'] = ' '.join(lst[1:]) if not 'package' in kw: return check_cfg_old(conf, **kw) package = kw['package'] package_lo = name_to_dest(package) package_hi = package.upper().replace('-', '_') # TODO FIXME package_hi = kw.get('uselib_store', package_hi) def check_folder(path, name): try: assert os.path.isdir(path) except AssertionError: raise Errors.ConfigurationError( "%s_%s (%s) is not a folder!" \ % (package_lo, name, path)) return path root = getattr(Options.options, '%s_root' % package_lo, None) if root is None: return check_cfg_old(conf, **kw) else: def add_manual_var(k, v): conf.start_msg('Adding for %s a manual var' % (package)) conf.env["%s_%s" % (k, package_hi)] = v conf.end_msg("%s = %s" % (k, v)) check_folder(root, 'root') pkg_inc = check_folder(os.path.join(root, "include"), 'inc') add_manual_var('INCLUDES', [pkg_inc]) pkg_lib = check_folder(os.path.join(root, "lib"), 'libpath') add_manual_var('LIBPATH', [pkg_lib]) add_manual_var('LIB', [package]) for x in kw.get('manual_deps', []): for k, v in sorted(conf.env.get_merged_dict().items()): if k.endswith('_%s' % x): k = k.replace('_%s' % x, '') conf.start_msg('Adding for %s a manual dep' \ %(package)) conf.env["%s_%s" % (k, package_hi)] += v conf.end_msg('%s += %s' % (k, v)) return True ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py0000660000000000000000000000511213573675414025774 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Christoph Koke, 2013 """ Writes the c and cpp compile commands into build/compile_commands.json see http://clang.llvm.org/docs/JSONCompilationDatabase.html Usage: def configure(conf): conf.load('compiler_cxx') ... conf.load('clang_compilation_database') """ import sys, os, json, shlex, pipes from waflib import Logs, TaskGen, Task Task.Task.keep_last_cmd = True @TaskGen.feature('c', 'cxx') @TaskGen.after_method('process_use') def collect_compilation_db_tasks(self): "Add a compilation database entry for compiled tasks" try: clang_db = self.bld.clang_compilation_database_tasks except AttributeError: clang_db = self.bld.clang_compilation_database_tasks = [] self.bld.add_post_fun(write_compilation_database) tup = tuple(y for y in [Task.classes.get(x) for x in ('c', 'cxx')] if y) for task in getattr(self, 'compiled_tasks', []): if isinstance(task, tup): clang_db.append(task) def write_compilation_database(ctx): "Write the clang compilation database as JSON" database_file = ctx.bldnode.make_node('compile_commands.json') Logs.info('Build commands will be stored in %s', database_file.path_from(ctx.path)) try: root = json.load(database_file) except IOError: root = [] clang_db = dict((x['file'], x) for x in root) for task in getattr(ctx, 'clang_compilation_database_tasks', []): try: cmd = task.last_cmd except AttributeError: continue directory = getattr(task, 'cwd', ctx.variant_dir) f_node = task.inputs[0] filename = os.path.relpath(f_node.abspath(), directory) entry = { "directory": directory, "arguments": cmd, "file": filename, } clang_db[filename] = entry root = list(clang_db.values()) database_file.write(json.dumps(root, indent=2)) # Override the runnable_status function to do a dummy/dry run when the file doesn't need to be compiled. # This will make sure compile_commands.json is always fully up to date. # Previously you could end up with a partial compile_commands.json if the build failed. for x in ('c', 'cxx'): if x not in Task.classes: continue t = Task.classes[x] def runnable_status(self): def exec_command(cmd, **kw): pass run_status = self.old_runnable_status() if run_status == Task.SKIP_ME: setattr(self, 'old_exec_command', getattr(self, 'exec_command', None)) setattr(self, 'exec_command', exec_command) self.run() setattr(self, 'exec_command', getattr(self, 'old_exec_command', None)) return run_status setattr(t, 'old_runnable_status', getattr(t, 'runnable_status', None)) setattr(t, 'runnable_status', runnable_status) ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py0000660000000000000000000000476613573675414023001 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Krzysztof Kosiński 2014 # DragoonX6 2018 """ Detect the Clang C compiler This version is an attempt at supporting the -target and -sysroot flag of Clang. """ from waflib.Tools import ccroot, ar, gcc from waflib.Configure import conf import waflib.Context import waflib.extras.clang_cross_common def options(opt): """ Target triplet for clang:: $ waf configure --clang-target-triple=x86_64-pc-linux-gnu """ cc_compiler_opts = opt.add_option_group('Configuration options') cc_compiler_opts.add_option('--clang-target-triple', default=None, help='Target triple for clang', dest='clang_target_triple') cc_compiler_opts.add_option('--clang-sysroot', default=None, help='Sysroot for clang', dest='clang_sysroot') @conf def find_clang(conf): """ Finds the program clang and executes it to ensure it really is clang """ import os cc = conf.find_program('clang', var='CC') if conf.options.clang_target_triple != None: conf.env.append_value('CC', ['-target', conf.options.clang_target_triple]) if conf.options.clang_sysroot != None: sysroot = str() if os.path.isabs(conf.options.clang_sysroot): sysroot = conf.options.clang_sysroot else: sysroot = os.path.normpath(os.path.join(os.getcwd(), conf.options.clang_sysroot)) conf.env.append_value('CC', ['--sysroot', sysroot]) conf.get_cc_version(cc, clang=True) conf.env.CC_NAME = 'clang' @conf def clang_modifier_x86_64_w64_mingw32(conf): conf.gcc_modifier_win32() @conf def clang_modifier_i386_w64_mingw32(conf): conf.gcc_modifier_win32() @conf def clang_modifier_x86_64_windows_msvc(conf): conf.clang_modifier_msvc() # Allow the user to override any flags if they so desire. clang_modifier_user_func = getattr(conf, 'clang_modifier_x86_64_windows_msvc_user', None) if clang_modifier_user_func: clang_modifier_user_func() @conf def clang_modifier_i386_windows_msvc(conf): conf.clang_modifier_msvc() # Allow the user to override any flags if they so desire. clang_modifier_user_func = getattr(conf, 'clang_modifier_i386_windows_msvc_user', None) if clang_modifier_user_func: clang_modifier_user_func() def configure(conf): conf.find_clang() conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gcc_common_flags() # Allow the user to provide flags for the target platform. conf.gcc_modifier_platform() # And allow more fine grained control based on the compiler's triplet. conf.clang_modifier_target_triple() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py0000660000000000000000000000654213573675414024343 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # DragoonX6 2018 """ Common routines for cross_clang.py and cross_clangxx.py """ from waflib.Configure import conf import waflib.Context def normalize_target_triple(target_triple): target_triple = target_triple[:-1] normalized_triple = target_triple.replace('--', '-unknown-') if normalized_triple.startswith('-'): normalized_triple = 'unknown' + normalized_triple if normalized_triple.endswith('-'): normalized_triple += 'unknown' # Normalize MinGW builds to *arch*-w64-mingw32 if normalized_triple.endswith('windows-gnu'): normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-w64-mingw32' # Strip the vendor when doing msvc builds, since it's unused anyway. if normalized_triple.endswith('windows-msvc'): normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-windows-msvc' return normalized_triple.replace('-', '_') @conf def clang_modifier_msvc(conf): import os """ Really basic setup to use clang in msvc mode. We actually don't really want to do a lot, even though clang is msvc compatible in this mode, that doesn't mean we're actually using msvc. It's probably the best to leave it to the user, we can assume msvc mode if the user uses the clang-cl frontend, but this module only concerns itself with the gcc-like frontend. """ v = conf.env v.cprogram_PATTERN = '%s.exe' v.cshlib_PATTERN = '%s.dll' v.implib_PATTERN = '%s.lib' v.IMPLIB_ST = '-Wl,-IMPLIB:%s' v.SHLIB_MARKER = [] v.CFLAGS_cshlib = [] v.LINKFLAGS_cshlib = ['-Wl,-DLL'] v.cstlib_PATTERN = '%s.lib' v.STLIB_MARKER = [] del(v.AR) conf.find_program(['llvm-lib', 'lib'], var='AR') v.ARFLAGS = ['-nologo'] v.AR_TGT_F = ['-out:'] # Default to the linker supplied with llvm instead of link.exe or ld v.LINK_CC = v.CC + ['-fuse-ld=lld', '-nostdlib'] v.CCLNK_TGT_F = ['-o'] v.def_PATTERN = '-Wl,-def:%s' v.LINKFLAGS = [] v.LIB_ST = '-l%s' v.LIBPATH_ST = '-Wl,-LIBPATH:%s' v.STLIB_ST = '-l%s' v.STLIBPATH_ST = '-Wl,-LIBPATH:%s' CFLAGS_CRT_COMMON = [ '-Xclang', '--dependent-lib=oldnames', '-Xclang', '-fno-rtti-data', '-D_MT' ] v.CFLAGS_CRT_MULTITHREADED = CFLAGS_CRT_COMMON + [ '-Xclang', '-flto-visibility-public-std', '-Xclang', '--dependent-lib=libcmt', ] v.CXXFLAGS_CRT_MULTITHREADED = v.CFLAGS_CRT_MULTITHREADED v.CFLAGS_CRT_MULTITHREADED_DBG = CFLAGS_CRT_COMMON + [ '-D_DEBUG', '-Xclang', '-flto-visibility-public-std', '-Xclang', '--dependent-lib=libcmtd', ] v.CXXFLAGS_CRT_MULTITHREADED_DBG = v.CFLAGS_CRT_MULTITHREADED_DBG v.CFLAGS_CRT_MULTITHREADED_DLL = CFLAGS_CRT_COMMON + [ '-D_DLL', '-Xclang', '--dependent-lib=msvcrt' ] v.CXXFLAGS_CRT_MULTITHREADED_DLL = v.CFLAGS_CRT_MULTITHREADED_DLL v.CFLAGS_CRT_MULTITHREADED_DLL_DBG = CFLAGS_CRT_COMMON + [ '-D_DLL', '-D_DEBUG', '-Xclang', '--dependent-lib=msvcrtd', ] v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG = v.CFLAGS_CRT_MULTITHREADED_DLL_DBG @conf def clang_modifier_target_triple(conf, cpp=False): compiler = conf.env.CXX if cpp else conf.env.CC output = conf.cmd_and_log(compiler + ['-dumpmachine'], output=waflib.Context.STDOUT) modifier = ('clangxx' if cpp else 'clang') + '_modifier_' clang_modifier_func = getattr(conf, modifier + normalize_target_triple(output), None) if clang_modifier_func: clang_modifier_func() ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py0000660000000000000000000000571213573675414023351 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy 2009-2018 (ita) # DragoonX6 2018 """ Detect the Clang++ C++ compiler This version is an attempt at supporting the -target and -sysroot flag of Clang++. """ from waflib.Tools import ccroot, ar, gxx from waflib.Configure import conf import waflib.extras.clang_cross_common def options(opt): """ Target triplet for clang++:: $ waf configure --clangxx-target-triple=x86_64-pc-linux-gnu """ cxx_compiler_opts = opt.add_option_group('Configuration options') cxx_compiler_opts.add_option('--clangxx-target-triple', default=None, help='Target triple for clang++', dest='clangxx_target_triple') cxx_compiler_opts.add_option('--clangxx-sysroot', default=None, help='Sysroot for clang++', dest='clangxx_sysroot') @conf def find_clangxx(conf): """ Finds the program clang++, and executes it to ensure it really is clang++ """ import os cxx = conf.find_program('clang++', var='CXX') if conf.options.clangxx_target_triple != None: conf.env.append_value('CXX', ['-target', conf.options.clangxx_target_triple]) if conf.options.clangxx_sysroot != None: sysroot = str() if os.path.isabs(conf.options.clangxx_sysroot): sysroot = conf.options.clangxx_sysroot else: sysroot = os.path.normpath(os.path.join(os.getcwd(), conf.options.clangxx_sysroot)) conf.env.append_value('CXX', ['--sysroot', sysroot]) conf.get_cc_version(cxx, clang=True) conf.env.CXX_NAME = 'clang' @conf def clangxx_modifier_x86_64_w64_mingw32(conf): conf.gcc_modifier_win32() @conf def clangxx_modifier_i386_w64_mingw32(conf): conf.gcc_modifier_win32() @conf def clangxx_modifier_msvc(conf): v = conf.env v.cxxprogram_PATTERN = v.cprogram_PATTERN v.cxxshlib_PATTERN = v.cshlib_PATTERN v.CXXFLAGS_cxxshlib = [] v.LINKFLAGS_cxxshlib = v.LINKFLAGS_cshlib v.cxxstlib_PATTERN = v.cstlib_PATTERN v.LINK_CXX = v.CXX + ['-fuse-ld=lld', '-nostdlib'] v.CXXLNK_TGT_F = v.CCLNK_TGT_F @conf def clangxx_modifier_x86_64_windows_msvc(conf): conf.clang_modifier_msvc() conf.clangxx_modifier_msvc() # Allow the user to override any flags if they so desire. clang_modifier_user_func = getattr(conf, 'clangxx_modifier_x86_64_windows_msvc_user', None) if clang_modifier_user_func: clang_modifier_user_func() @conf def clangxx_modifier_i386_windows_msvc(conf): conf.clang_modifier_msvc() conf.clangxx_modifier_msvc() # Allow the user to override any flags if they so desire. clang_modifier_user_func = getattr(conf, 'clangxx_modifier_i386_windows_msvc_user', None) if clang_modifier_user_func: clang_modifier_user_func() def configure(conf): conf.find_clangxx() conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gxx_common_flags() # Allow the user to provide flags for the target platform. conf.gxx_modifier_platform() # And allow more fine grained control based on the compiler's triplet. conf.clang_modifier_target_triple(cpp=True) conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/extras/codelite.py0000660000000000000000000010214013573675414022255 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # CodeLite Project # Christian Klein (chrikle@berlios.de) # Created: Jan 2012 # As templete for this file I used the msvs.py # I hope this template will work proper """ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ """ To add this tool to your project: def options(conf): opt.load('codelite') It can be a good idea to add the sync_exec tool too. To generate solution files: $ waf configure codelite To customize the outputs, provide subclasses in your wscript files: from waflib.extras import codelite class vsnode_target(codelite.vsnode_target): def get_build_command(self, props): # likely to be required return "waf.bat build" def collect_source(self): # likely to be required ... class codelite_bar(codelite.codelite_generator): def init(self): codelite.codelite_generator.init(self) self.vsnode_target = vsnode_target The codelite class re-uses the same build() function for reading the targets (task generators), you may therefore specify codelite settings on the context object: def build(bld): bld.codelite_solution_name = 'foo.workspace' bld.waf_command = 'waf.bat' bld.projects_dir = bld.srcnode.make_node('') bld.projects_dir.mkdir() ASSUMPTIONS: * a project can be either a directory or a target, project files are written only for targets that have source files * each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path """ import os, re, sys import uuid # requires python 2.5 from waflib.Build import BuildContext from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' PROJECT_TEMPLATE = r''' ${for x in project.source} ${if (project.get_key(x)=="sourcefile")} ${endif} ${endfor} ${for x in project.source} ${if (project.get_key(x)=="headerfile")} ${endif} ${endfor} $b = project.build_properties[0]} ${xml:project.get_rebuild_command(project.build_properties[0])} ${xml:project.get_clean_command(project.build_properties[0])} ${xml:project.get_build_command(project.build_properties[0])} ${xml:project.get_install_command(project.build_properties[0])} ${xml:project.get_build_and_install_command(project.build_properties[0])} ${xml:project.get_build_all_command(project.build_properties[0])} ${xml:project.get_rebuild_all_command(project.build_properties[0])} ${xml:project.get_clean_all_command(project.build_properties[0])} ${xml:project.get_build_and_install_all_command(project.build_properties[0])} None ''' SOLUTION_TEMPLATE = ''' ${for p in project.all_projects} ${endfor} ${for p in project.all_projects} ${endfor} ''' COMPILE_TEMPLATE = '''def f(project): lst = [] def xml_escape(value): return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") %s #f = open('cmd.txt', 'w') #f.write(str(lst)) #f.close() return ''.join(lst) ''' reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) def compile_template(line): """ Compile a template expression into a python function (like jsps, but way shorter) """ extr = [] def repl(match): g = match.group if g('dollar'): return "$" elif g('backslash'): return "\\" elif g('subst'): extr.append(g('code')) return "<<|@|>>" return None line2 = reg_act.sub(repl, line) params = line2.split('<<|@|>>') assert(extr) indent = 0 buf = [] app = buf.append def app(txt): buf.append(indent * '\t' + txt) for x in range(len(extr)): if params[x]: app("lst.append(%r)" % params[x]) f = extr[x] if f.startswith(('if', 'for')): app(f + ':') indent += 1 elif f.startswith('py:'): app(f[3:]) elif f.startswith(('endif', 'endfor')): indent -= 1 elif f.startswith(('else', 'elif')): indent -= 1 app(f + ':') indent += 1 elif f.startswith('xml:'): app('lst.append(xml_escape(%s))' % f[4:]) else: #app('lst.append((%s) or "cannot find %s")' % (f, f)) app('lst.append(%s)' % f) if extr: if params[-1]: app("lst.append(%r)" % params[-1]) fun = COMPILE_TEMPLATE % "\n\t".join(buf) #print(fun) return Task.funex(fun) re_blank = re.compile('(\n|\r|\\s)*\n', re.M) def rm_blank_lines(txt): txt = re_blank.sub('\r\n', txt) return txt BOM = '\xef\xbb\xbf' try: BOM = bytes(BOM, 'latin-1') # python 3 except (TypeError, NameError): pass def stealth_write(self, data, flags='wb'): try: unicode except NameError: data = data.encode('utf-8') # python 3 else: data = data.decode(sys.getfilesystemencoding(), 'replace') data = data.encode('utf-8') if self.name.endswith('.project'): data = BOM + data try: txt = self.read(flags='rb') if txt != data: raise ValueError('must write') except (IOError, ValueError): self.write(data, flags=flags) else: Logs.debug('codelite: skipping %r', self) Node.Node.stealth_write = stealth_write re_quote = re.compile("[^a-zA-Z0-9-]") def quote(s): return re_quote.sub("_", s) def xml_escape(value): return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") def make_uuid(v, prefix = None): """ simple utility function """ if isinstance(v, dict): keys = list(v.keys()) keys.sort() tmp = str([(k, v[k]) for k in keys]) else: tmp = str(v) d = Utils.md5(tmp.encode()).hexdigest().upper() if prefix: d = '%s%s' % (prefix, d[8:]) gid = uuid.UUID(d, version = 4) return str(gid).upper() def diff(node, fromnode): # difference between two nodes, but with "(..)" instead of ".." c1 = node c2 = fromnode c1h = c1.height() c2h = c2.height() lst = [] up = 0 while c1h > c2h: lst.append(c1.name) c1 = c1.parent c1h -= 1 while c2h > c1h: up += 1 c2 = c2.parent c2h -= 1 while id(c1) != id(c2): lst.append(c1.name) up += 1 c1 = c1.parent c2 = c2.parent for i in range(up): lst.append('(..)') lst.reverse() return tuple(lst) class build_property(object): pass class vsnode(object): """ Abstract class representing visual studio elements We assume that all visual studio nodes have a uuid and a parent """ def __init__(self, ctx): self.ctx = ctx # codelite context self.name = '' # string, mandatory self.vspath = '' # path in visual studio (name for dirs, absolute path for projects) self.uuid = '' # string, mandatory self.parent = None # parent node for visual studio nesting def get_waf(self): """ Override in subclasses... """ return '%s/%s' % (self.ctx.srcnode.abspath(), getattr(self.ctx, 'waf_command', 'waf')) def ptype(self): """ Return a special uuid for projects written in the solution file """ pass def write(self): """ Write the project file, by default, do nothing """ pass def make_uuid(self, val): """ Alias for creating uuid values easily (the templates cannot access global variables) """ return make_uuid(val) class vsnode_vsdir(vsnode): """ Nodes representing visual studio folders (which do not match the filesystem tree!) """ VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8" def __init__(self, ctx, uuid, name, vspath=''): vsnode.__init__(self, ctx) self.title = self.name = name self.uuid = uuid self.vspath = vspath or name def ptype(self): return self.VS_GUID_SOLUTIONFOLDER class vsnode_project(vsnode): """ Abstract class representing visual studio project elements A project is assumed to be writable, and has a node representing the file to write to """ VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" def ptype(self): return self.VS_GUID_VCPROJ def __init__(self, ctx, node): vsnode.__init__(self, ctx) self.path = node self.uuid = make_uuid(node.abspath()) self.name = node.name self.title = self.path.abspath() self.source = [] # list of node objects self.build_properties = [] # list of properties (nmake commands, output dir, etc) def dirs(self): """ Get the list of parent folders of the source files (header files included) for writing the filters """ lst = [] def add(x): if x.height() > self.tg.path.height() and x not in lst: lst.append(x) add(x.parent) for x in self.source: add(x.parent) return lst def write(self): Logs.debug('codelite: creating %r', self.path) #print "self.name:",self.name # first write the project file template1 = compile_template(PROJECT_TEMPLATE) proj_str = template1(self) proj_str = rm_blank_lines(proj_str) self.path.stealth_write(proj_str) # then write the filter #template2 = compile_template(FILTER_TEMPLATE) #filter_str = template2(self) #filter_str = rm_blank_lines(filter_str) #tmp = self.path.parent.make_node(self.path.name + '.filters') #tmp.stealth_write(filter_str) def get_key(self, node): """ required for writing the source files """ name = node.name if name.endswith(('.cpp', '.c')): return 'sourcefile' return 'headerfile' def collect_properties(self): """ Returns a list of triplet (configuration, platform, output_directory) """ ret = [] for c in self.ctx.configurations: for p in self.ctx.platforms: x = build_property() x.outdir = '' x.configuration = c x.platform = p x.preprocessor_definitions = '' x.includes_search_path = '' # can specify "deploy_dir" too ret.append(x) self.build_properties = ret def get_build_params(self, props): opt = '' return (self.get_waf(), opt) def get_build_command(self, props): return "%s build %s" % self.get_build_params(props) def get_clean_command(self, props): return "%s clean %s" % self.get_build_params(props) def get_rebuild_command(self, props): return "%s clean build %s" % self.get_build_params(props) def get_install_command(self, props): return "%s install %s" % self.get_build_params(props) def get_build_and_install_command(self, props): return "%s build install %s" % self.get_build_params(props) def get_build_and_install_all_command(self, props): return "%s build install" % self.get_build_params(props)[0] def get_clean_all_command(self, props): return "%s clean" % self.get_build_params(props)[0] def get_build_all_command(self, props): return "%s build" % self.get_build_params(props)[0] def get_rebuild_all_command(self, props): return "%s clean build" % self.get_build_params(props)[0] def get_filter_name(self, node): lst = diff(node, self.tg.path) return '\\'.join(lst) or '.' class vsnode_alias(vsnode_project): def __init__(self, ctx, node, name): vsnode_project.__init__(self, ctx, node) self.name = name self.output_file = '' class vsnode_build_all(vsnode_alias): """ Fake target used to emulate the behaviour of "make all" (starting one process by target is slow) This is the only alias enabled by default """ def __init__(self, ctx, node, name='build_all_projects'): vsnode_alias.__init__(self, ctx, node, name) self.is_active = True class vsnode_install_all(vsnode_alias): """ Fake target used to emulate the behaviour of "make install" """ def __init__(self, ctx, node, name='install_all_projects'): vsnode_alias.__init__(self, ctx, node, name) def get_build_command(self, props): return "%s build install %s" % self.get_build_params(props) def get_clean_command(self, props): return "%s clean %s" % self.get_build_params(props) def get_rebuild_command(self, props): return "%s clean build install %s" % self.get_build_params(props) class vsnode_project_view(vsnode_alias): """ Fake target used to emulate a file system view """ def __init__(self, ctx, node, name='project_view'): vsnode_alias.__init__(self, ctx, node, name) self.tg = self.ctx() # fake one, cannot remove self.exclude_files = Node.exclude_regs + ''' waf-2* waf3-2*/** .waf-2* .waf3-2*/** **/*.sdf **/*.suo **/*.ncb **/%s ''' % Options.lockfile def collect_source(self): # this is likely to be slow self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files) def get_build_command(self, props): params = self.get_build_params(props) + (self.ctx.cmd,) return "%s %s %s" % params def get_clean_command(self, props): return "" def get_rebuild_command(self, props): return self.get_build_command(props) class vsnode_target(vsnode_project): """ CodeLite project representing a targets (programs, libraries, etc) and bound to a task generator """ def __init__(self, ctx, tg): """ A project is more or less equivalent to a file/folder """ base = getattr(ctx, 'projects_dir', None) or tg.path node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node vsnode_project.__init__(self, ctx, node) self.name = quote(tg.name) self.tg = tg # task generator def get_build_params(self, props): """ Override the default to add the target name """ opt = '' if getattr(self, 'tg', None): opt += " --targets=%s" % self.tg.name return (self.get_waf(), opt) def collect_source(self): tg = self.tg source_files = tg.to_nodes(getattr(tg, 'source', [])) include_dirs = Utils.to_list(getattr(tg, 'codelite_includes', [])) include_files = [] for x in include_dirs: if isinstance(x, str): x = tg.path.find_node(x) if x: lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)] include_files.extend(lst) # remove duplicates self.source.extend(list(set(source_files + include_files))) self.source.sort(key=lambda x: x.abspath()) def collect_properties(self): """ CodeLite projects are associated with platforms and configurations (for building especially) """ super(vsnode_target, self).collect_properties() for x in self.build_properties: x.outdir = self.path.parent.abspath() x.preprocessor_definitions = '' x.includes_search_path = '' try: tsk = self.tg.link_task except AttributeError: pass else: x.output_file = tsk.outputs[0].abspath() x.preprocessor_definitions = ';'.join(tsk.env.DEFINES) x.includes_search_path = ';'.join(self.tg.env.INCPATHS) class codelite_generator(BuildContext): '''generates a CodeLite workspace''' cmd = 'codelite' fun = 'build' def init(self): """ Some data that needs to be present """ if not getattr(self, 'configurations', None): self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc if not getattr(self, 'platforms', None): self.platforms = ['Win32'] if not getattr(self, 'all_projects', None): self.all_projects = [] if not getattr(self, 'project_extension', None): self.project_extension = '.project' if not getattr(self, 'projects_dir', None): self.projects_dir = self.srcnode.make_node('') self.projects_dir.mkdir() # bind the classes to the object, so that subclass can provide custom generators if not getattr(self, 'vsnode_vsdir', None): self.vsnode_vsdir = vsnode_vsdir if not getattr(self, 'vsnode_target', None): self.vsnode_target = vsnode_target if not getattr(self, 'vsnode_build_all', None): self.vsnode_build_all = vsnode_build_all if not getattr(self, 'vsnode_install_all', None): self.vsnode_install_all = vsnode_install_all if not getattr(self, 'vsnode_project_view', None): self.vsnode_project_view = vsnode_project_view self.numver = '11.00' self.vsver = '2010' def execute(self): """ Entry point """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) # user initialization self.init() # two phases for creating the solution self.collect_projects() # add project objects into "self.all_projects" self.write_files() # write the corresponding project and solution files def collect_projects(self): """ Fill the list self.all_projects with project objects Fill the list of build targets """ self.collect_targets() #self.add_aliases() #self.collect_dirs() default_project = getattr(self, 'default_project', None) def sortfun(x): if x.name == default_project: return '' return getattr(x, 'path', None) and x.path.abspath() or x.name self.all_projects.sort(key=sortfun) def write_files(self): """ Write the project and solution files from the data collected so far. It is unlikely that you will want to change this """ for p in self.all_projects: p.write() # and finally write the solution file node = self.get_solution_node() node.parent.mkdir() Logs.warn('Creating %r', node) #a = dir(self.root) #for b in a: # print b #print self.group_names #print "Hallo2: ",self.root.listdir() #print getattr(self, 'codelite_solution_name', None) template1 = compile_template(SOLUTION_TEMPLATE) sln_str = template1(self) sln_str = rm_blank_lines(sln_str) node.stealth_write(sln_str) def get_solution_node(self): """ The solution filename is required when writing the .vcproj files return self.solution_node and if it does not exist, make one """ try: return self.solution_node except: pass codelite_solution_name = getattr(self, 'codelite_solution_name', None) if not codelite_solution_name: codelite_solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.workspace' setattr(self, 'codelite_solution_name', codelite_solution_name) if os.path.isabs(codelite_solution_name): self.solution_node = self.root.make_node(codelite_solution_name) else: self.solution_node = self.srcnode.make_node(codelite_solution_name) return self.solution_node def project_configurations(self): """ Helper that returns all the pairs (config,platform) """ ret = [] for c in self.configurations: for p in self.platforms: ret.append((c, p)) return ret def collect_targets(self): """ Process the list of task generators """ for g in self.groups: for tg in g: if not isinstance(tg, TaskGen.task_gen): continue if not hasattr(tg, 'codelite_includes'): tg.codelite_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', [])) tg.post() if not getattr(tg, 'link_task', None): continue p = self.vsnode_target(self, tg) p.collect_source() # delegate this processing p.collect_properties() self.all_projects.append(p) def add_aliases(self): """ Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7 We also add an alias for "make install" (disabled by default) """ base = getattr(self, 'projects_dir', None) or self.tg.path node_project = base.make_node('build_all_projects' + self.project_extension) # Node p_build = self.vsnode_build_all(self, node_project) p_build.collect_properties() self.all_projects.append(p_build) node_project = base.make_node('install_all_projects' + self.project_extension) # Node p_install = self.vsnode_install_all(self, node_project) p_install.collect_properties() self.all_projects.append(p_install) node_project = base.make_node('project_view' + self.project_extension) # Node p_view = self.vsnode_project_view(self, node_project) p_view.collect_source() p_view.collect_properties() self.all_projects.append(p_view) n = self.vsnode_vsdir(self, make_uuid(self.srcnode.abspath() + 'build_aliases'), "build_aliases") p_build.parent = p_install.parent = p_view.parent = n self.all_projects.append(n) def collect_dirs(self): """ Create the folder structure in the CodeLite project view """ seen = {} def make_parents(proj): # look at a project, try to make a parent if getattr(proj, 'parent', None): # aliases already have parents return x = proj.iter_path if x in seen: proj.parent = seen[x] return # There is not vsnode_vsdir for x. # So create a project representing the folder "x" n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.abspath()), x.name) n.iter_path = x.parent self.all_projects.append(n) # recurse up to the project directory if x.height() > self.srcnode.height() + 1: make_parents(n) for p in self.all_projects[:]: # iterate over a copy of all projects if not getattr(p, 'tg', None): # but only projects that have a task generator continue # make a folder for each task generator p.iter_path = p.tg.path make_parents(p) ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py0000660000000000000000000000216613573675414022426 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Replaces the default formatter by one which understands GCC output and colorizes it. __author__ = __maintainer__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2012" import sys from waflib import Logs class ColorGCCFormatter(Logs.formatter): def __init__(self, colors): self.colors = colors Logs.formatter.__init__(self) def format(self, rec): frame = sys._getframe() while frame: func = frame.f_code.co_name if func == 'exec_command': cmd = frame.f_locals.get('cmd') if isinstance(cmd, list) and ('gcc' in cmd[0] or 'g++' in cmd[0]): lines = [] for line in rec.msg.splitlines(): if 'warning: ' in line: lines.append(self.colors.YELLOW + line) elif 'error: ' in line: lines.append(self.colors.RED + line) elif 'note: ' in line: lines.append(self.colors.CYAN + line) else: lines.append(line) rec.msg = "\n".join(lines) frame = frame.f_back return Logs.formatter.format(self, rec) def options(opt): Logs.log.handlers[0].setFormatter(ColorGCCFormatter(Logs.colors)) ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py0000660000000000000000000000343513573675414022642 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Replaces the default formatter by one which understands MSVC output and colorizes it. # Modified from color_gcc.py __author__ = __maintainer__ = "Alibek Omarov " __copyright__ = "Alibek Omarov, 2019" import sys from waflib import Logs class ColorMSVCFormatter(Logs.formatter): def __init__(self, colors): self.colors = colors Logs.formatter.__init__(self) def parseMessage(self, line, color): # Split messaage from 'disk:filepath: type: message' arr = line.split(':', 3) if len(arr) < 4: return line colored = self.colors.BOLD + arr[0] + ':' + arr[1] + ':' + self.colors.NORMAL colored += color + arr[2] + ':' + self.colors.NORMAL colored += arr[3] return colored def format(self, rec): frame = sys._getframe() while frame: func = frame.f_code.co_name if func == 'exec_command': cmd = frame.f_locals.get('cmd') if isinstance(cmd, list): # Fix file case, it may be CL.EXE or cl.exe argv0 = cmd[0].lower() if 'cl.exe' in argv0: lines = [] # This will not work with "localized" versions # of MSVC for line in rec.msg.splitlines(): if ': warning ' in line: lines.append(self.parseMessage(line, self.colors.YELLOW)) elif ': error ' in line: lines.append(self.parseMessage(line, self.colors.RED)) elif ': fatal error ' in line: lines.append(self.parseMessage(line, self.colors.RED + self.colors.BOLD)) elif ': note: ' in line: lines.append(self.parseMessage(line, self.colors.CYAN)) else: lines.append(line) rec.msg = "\n".join(lines) frame = frame.f_back return Logs.formatter.format(self, rec) def options(opt): Logs.log.handlers[0].setFormatter(ColorMSVCFormatter(Logs.colors)) ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py0000660000000000000000000000244513573675414022650 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Replaces the default formatter by one which understands RVCT output and colorizes it. __author__ = __maintainer__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2012" import sys import atexit from waflib import Logs errors = [] def show_errors(): for i, e in enumerate(errors): if i > 5: break print("Error: %s" % e) atexit.register(show_errors) class RcvtFormatter(Logs.formatter): def __init__(self, colors): Logs.formatter.__init__(self) self.colors = colors def format(self, rec): frame = sys._getframe() while frame: func = frame.f_code.co_name if func == 'exec_command': cmd = frame.f_locals['cmd'] if isinstance(cmd, list) and ('armcc' in cmd[0] or 'armld' in cmd[0]): lines = [] for line in rec.msg.splitlines(): if 'Warning: ' in line: lines.append(self.colors.YELLOW + line) elif 'Error: ' in line: lines.append(self.colors.RED + line) errors.append(line) elif 'note: ' in line: lines.append(self.colors.CYAN + line) else: lines.append(line) rec.msg = "\n".join(lines) frame = frame.f_back return Logs.formatter.format(self, rec) def options(opt): Logs.log.handlers[0].setFormatter(RcvtFormatter(Logs.colors)) ldb-2.0.8/third_party/waf/waflib/extras/compat15.py0000660000000000000000000002704513573675414022130 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010 (ita) """ This file is provided to enable compatibility with waf 1.5 It was enabled by default in waf 1.6, but it is not used in waf 1.7 """ import sys from waflib import ConfigSet, Logs, Options, Scripting, Task, Build, Configure, Node, Runner, TaskGen, Utils, Errors, Context # the following is to bring some compatibility with waf 1.5 "import waflib.Configure → import Configure" sys.modules['Environment'] = ConfigSet ConfigSet.Environment = ConfigSet.ConfigSet sys.modules['Logs'] = Logs sys.modules['Options'] = Options sys.modules['Scripting'] = Scripting sys.modules['Task'] = Task sys.modules['Build'] = Build sys.modules['Configure'] = Configure sys.modules['Node'] = Node sys.modules['Runner'] = Runner sys.modules['TaskGen'] = TaskGen sys.modules['Utils'] = Utils sys.modules['Constants'] = Context Context.SRCDIR = '' Context.BLDDIR = '' from waflib.Tools import c_preproc sys.modules['preproc'] = c_preproc from waflib.Tools import c_config sys.modules['config_c'] = c_config ConfigSet.ConfigSet.copy = ConfigSet.ConfigSet.derive ConfigSet.ConfigSet.set_variant = Utils.nada Utils.pproc = Utils.subprocess Build.BuildContext.add_subdirs = Build.BuildContext.recurse Build.BuildContext.new_task_gen = Build.BuildContext.__call__ Build.BuildContext.is_install = 0 Node.Node.relpath_gen = Node.Node.path_from Utils.pproc = Utils.subprocess Utils.get_term_cols = Logs.get_term_cols def cmd_output(cmd, **kw): silent = False if 'silent' in kw: silent = kw['silent'] del(kw['silent']) if 'e' in kw: tmp = kw['e'] del(kw['e']) kw['env'] = tmp kw['shell'] = isinstance(cmd, str) kw['stdout'] = Utils.subprocess.PIPE if silent: kw['stderr'] = Utils.subprocess.PIPE try: p = Utils.subprocess.Popen(cmd, **kw) output = p.communicate()[0] except OSError as e: raise ValueError(str(e)) if p.returncode: if not silent: msg = "command execution failed: %s -> %r" % (cmd, str(output)) raise ValueError(msg) output = '' return output Utils.cmd_output = cmd_output def name_to_obj(self, s, env=None): if Logs.verbose: Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"') return self.get_tgen_by_name(s) Build.BuildContext.name_to_obj = name_to_obj def env_of_name(self, name): try: return self.all_envs[name] except KeyError: Logs.error('no such environment: '+name) return None Build.BuildContext.env_of_name = env_of_name def set_env_name(self, name, env): self.all_envs[name] = env return env Configure.ConfigurationContext.set_env_name = set_env_name def retrieve(self, name, fromenv=None): try: env = self.all_envs[name] except KeyError: env = ConfigSet.ConfigSet() self.prepare_env(env) self.all_envs[name] = env else: if fromenv: Logs.warn('The environment %s may have been configured already', name) return env Configure.ConfigurationContext.retrieve = retrieve Configure.ConfigurationContext.sub_config = Configure.ConfigurationContext.recurse Configure.ConfigurationContext.check_tool = Configure.ConfigurationContext.load Configure.conftest = Configure.conf Configure.ConfigurationError = Errors.ConfigurationError Utils.WafError = Errors.WafError Options.OptionsContext.sub_options = Options.OptionsContext.recurse Options.OptionsContext.tool_options = Context.Context.load Options.Handler = Options.OptionsContext Task.simple_task_type = Task.task_type_from_func = Task.task_factory Task.Task.classes = Task.classes def setitem(self, key, value): if key.startswith('CCFLAGS'): key = key[1:] self.table[key] = value ConfigSet.ConfigSet.__setitem__ = setitem @TaskGen.feature('d') @TaskGen.before('apply_incpaths') def old_importpaths(self): if getattr(self, 'importpaths', []): self.includes = self.importpaths from waflib import Context eld = Context.load_tool def load_tool(*k, **kw): ret = eld(*k, **kw) if 'set_options' in ret.__dict__: if Logs.verbose: Logs.warn('compat: rename "set_options" to options') ret.options = ret.set_options if 'detect' in ret.__dict__: if Logs.verbose: Logs.warn('compat: rename "detect" to "configure"') ret.configure = ret.detect return ret Context.load_tool = load_tool def get_curdir(self): return self.path.abspath() Context.Context.curdir = property(get_curdir, Utils.nada) def get_srcdir(self): return self.srcnode.abspath() Configure.ConfigurationContext.srcdir = property(get_srcdir, Utils.nada) def get_blddir(self): return self.bldnode.abspath() Configure.ConfigurationContext.blddir = property(get_blddir, Utils.nada) Configure.ConfigurationContext.check_message_1 = Configure.ConfigurationContext.start_msg Configure.ConfigurationContext.check_message_2 = Configure.ConfigurationContext.end_msg rev = Context.load_module def load_module(path, encoding=None): ret = rev(path, encoding) if 'set_options' in ret.__dict__: if Logs.verbose: Logs.warn('compat: rename "set_options" to "options" (%r)', path) ret.options = ret.set_options if 'srcdir' in ret.__dict__: if Logs.verbose: Logs.warn('compat: rename "srcdir" to "top" (%r)', path) ret.top = ret.srcdir if 'blddir' in ret.__dict__: if Logs.verbose: Logs.warn('compat: rename "blddir" to "out" (%r)', path) ret.out = ret.blddir Utils.g_module = Context.g_module Options.launch_dir = Context.launch_dir return ret Context.load_module = load_module old_post = TaskGen.task_gen.post def post(self): self.features = self.to_list(self.features) if 'cc' in self.features: if Logs.verbose: Logs.warn('compat: the feature cc does not exist anymore (use "c")') self.features.remove('cc') self.features.append('c') if 'cstaticlib' in self.features: if Logs.verbose: Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")') self.features.remove('cstaticlib') self.features.append(('cxx' in self.features) and 'cxxstlib' or 'cstlib') if getattr(self, 'ccflags', None): if Logs.verbose: Logs.warn('compat: "ccflags" was renamed to "cflags"') self.cflags = self.ccflags return old_post(self) TaskGen.task_gen.post = post def waf_version(*k, **kw): Logs.warn('wrong version (waf_version was removed in waf 1.6)') Utils.waf_version = waf_version import os @TaskGen.feature('c', 'cxx', 'd') @TaskGen.before('apply_incpaths', 'propagate_uselib_vars') @TaskGen.after('apply_link', 'process_source') def apply_uselib_local(self): """ process the uselib_local attribute execute after apply_link because of the execution order set on 'link_task' """ env = self.env from waflib.Tools.ccroot import stlink_task # 1. the case of the libs defined in the project (visit ancestors first) # the ancestors external libraries (uselib) will be prepended self.uselib = self.to_list(getattr(self, 'uselib', [])) self.includes = self.to_list(getattr(self, 'includes', [])) names = self.to_list(getattr(self, 'uselib_local', [])) get = self.bld.get_tgen_by_name seen = set() seen_uselib = set() tmp = Utils.deque(names) # consume a copy of the list of names if tmp: if Logs.verbose: Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') while tmp: lib_name = tmp.popleft() # visit dependencies only once if lib_name in seen: continue y = get(lib_name) y.post() seen.add(lib_name) # object has ancestors to process (shared libraries): add them to the end of the list if getattr(y, 'uselib_local', None): for x in self.to_list(getattr(y, 'uselib_local', [])): obj = get(x) obj.post() if getattr(obj, 'link_task', None): if not isinstance(obj.link_task, stlink_task): tmp.append(x) # link task and flags if getattr(y, 'link_task', None): link_name = y.target[y.target.rfind(os.sep) + 1:] if isinstance(y.link_task, stlink_task): env.append_value('STLIB', [link_name]) else: # some linkers can link against programs env.append_value('LIB', [link_name]) # the order self.link_task.set_run_after(y.link_task) # for the recompilation self.link_task.dep_nodes += y.link_task.outputs # add the link path too tmp_path = y.link_task.outputs[0].parent.bldpath() if not tmp_path in env['LIBPATH']: env.prepend_value('LIBPATH', [tmp_path]) # add ancestors uselib too - but only propagate those that have no staticlib defined for v in self.to_list(getattr(y, 'uselib', [])): if v not in seen_uselib: seen_uselib.add(v) if not env['STLIB_' + v]: if not v in self.uselib: self.uselib.insert(0, v) # if the library task generator provides 'export_includes', add to the include path # the export_includes must be a list of paths relative to the other library if getattr(y, 'export_includes', None): self.includes.extend(y.to_incnodes(y.export_includes)) @TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib') @TaskGen.after('apply_link') def apply_objdeps(self): "add the .o files produced by some other object files in the same manner as uselib_local" names = getattr(self, 'add_objects', []) if not names: return names = self.to_list(names) get = self.bld.get_tgen_by_name seen = [] while names: x = names[0] # visit dependencies only once if x in seen: names = names[1:] continue # object does not exist ? y = get(x) # object has ancestors to process first ? update the list of names if getattr(y, 'add_objects', None): added = 0 lst = y.to_list(y.add_objects) lst.reverse() for u in lst: if u in seen: continue added = 1 names = [u]+names if added: continue # list of names modified, loop # safe to process the current object y.post() seen.append(x) for t in getattr(y, 'compiled_tasks', []): self.link_task.inputs.extend(t.outputs) @TaskGen.after('apply_link') def process_obj_files(self): if not hasattr(self, 'obj_files'): return for x in self.obj_files: node = self.path.find_resource(x) self.link_task.inputs.append(node) @TaskGen.taskgen_method def add_obj_file(self, file): """Small example on how to link object files as if they were source obj = bld.create_obj('cc') obj.add_obj_file('foo.o')""" if not hasattr(self, 'obj_files'): self.obj_files = [] if not 'process_obj_files' in self.meths: self.meths.append('process_obj_files') self.obj_files.append(file) old_define = Configure.ConfigurationContext.__dict__['define'] @Configure.conf def define(self, key, val, quote=True, comment=''): old_define(self, key, val, quote, comment) if key.startswith('HAVE_'): self.env[key] = 1 old_undefine = Configure.ConfigurationContext.__dict__['undefine'] @Configure.conf def undefine(self, key, comment=''): old_undefine(self, key, comment) if key.startswith('HAVE_'): self.env[key] = 0 # some people might want to use export_incdirs, but it was renamed def set_incdirs(self, val): Logs.warn('compat: change "export_incdirs" by "export_includes"') self.export_includes = val TaskGen.task_gen.export_incdirs = property(None, set_incdirs) def install_dir(self, path): if not path: return [] destpath = Utils.subst_vars(path, self.env) if self.is_install > 0: Logs.info('* creating %s', destpath) Utils.check_dir(destpath) elif self.is_install < 0: Logs.info('* removing %s', destpath) try: os.remove(destpath) except OSError: pass Build.BuildContext.install_dir = install_dir # before/after names repl = {'apply_core': 'process_source', 'apply_lib_vars': 'process_source', 'apply_obj_vars': 'propagate_uselib_vars', 'exec_rule': 'process_rule' } def after(*k): k = [repl.get(key, key) for key in k] return TaskGen.after_method(*k) def before(*k): k = [repl.get(key, key) for key in k] return TaskGen.before_method(*k) TaskGen.before = before ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py0000660000000000000000000004320413573675414022252 0ustar rootroot00000000000000#! /usr/bin/env python # -*- encoding: utf-8 -*- # Michel Mooij, michel.mooij7@gmail.com """ Tool Description ================ This module provides a waf wrapper (i.e. waftool) around the C/C++ source code checking tool 'cppcheck'. See http://cppcheck.sourceforge.net/ for more information on the cppcheck tool itself. Note that many linux distributions already provide a ready to install version of cppcheck. On fedora, for instance, it can be installed using yum: 'sudo yum install cppcheck' Usage ===== In order to use this waftool simply add it to the 'options' and 'configure' functions of your main waf script as shown in the example below: def options(opt): opt.load('cppcheck', tooldir='./waftools') def configure(conf): conf.load('cppcheck') Note that example shown above assumes that the cppcheck waftool is located in the sub directory named 'waftools'. When configured as shown in the example above, cppcheck will automatically perform a source code analysis on all C/C++ build tasks that have been defined in your waf build system. The example shown below for a C program will be used as input for cppcheck when building the task. def build(bld): bld.program(name='foo', src='foobar.c') The result of the source code analysis will be stored both as xml and html files in the build location for the task. Should any error be detected by cppcheck the build will be aborted and a link to the html report will be shown. By default, one index.html file is created for each task generator. A global index.html file can be obtained by setting the following variable in the configuration section: conf.env.CPPCHECK_SINGLE_HTML = False When needed source code checking by cppcheck can be disabled per task, per detected error or warning for a particular task. It can be also be disabled for all tasks. In order to exclude a task from source code checking add the skip option to the task as shown below: def build(bld): bld.program( name='foo', src='foobar.c' cppcheck_skip=True ) When needed problems detected by cppcheck may be suppressed using a file containing a list of suppression rules. The relative or absolute path to this file can be added to the build task as shown in the example below: bld.program( name='bar', src='foobar.c', cppcheck_suppress='bar.suppress' ) A cppcheck suppress file should contain one suppress rule per line. Each of these rules will be passed as an '--suppress=' argument to cppcheck. Dependencies ================ This waftool depends on the python pygments module, it is used for source code syntax highlighting when creating the html reports. see http://pygments.org/ for more information on this package. Remarks ================ The generation of the html report is originally based on the cppcheck-htmlreport.py script that comes shipped with the cppcheck tool. """ import sys import xml.etree.ElementTree as ElementTree from waflib import Task, TaskGen, Logs, Context, Options PYGMENTS_EXC_MSG= ''' The required module 'pygments' could not be found. Please install it using your platform package manager (e.g. apt-get or yum), using 'pip' or 'easy_install', see 'http://pygments.org/download/' for installation instructions. ''' try: import pygments from pygments import formatters, lexers except ImportError as e: Logs.warn(PYGMENTS_EXC_MSG) raise e def options(opt): opt.add_option('--cppcheck-skip', dest='cppcheck_skip', default=False, action='store_true', help='do not check C/C++ sources (default=False)') opt.add_option('--cppcheck-err-resume', dest='cppcheck_err_resume', default=False, action='store_true', help='continue in case of errors (default=False)') opt.add_option('--cppcheck-bin-enable', dest='cppcheck_bin_enable', default='warning,performance,portability,style,unusedFunction', action='store', help="cppcheck option '--enable=' for binaries (default=warning,performance,portability,style,unusedFunction)") opt.add_option('--cppcheck-lib-enable', dest='cppcheck_lib_enable', default='warning,performance,portability,style', action='store', help="cppcheck option '--enable=' for libraries (default=warning,performance,portability,style)") opt.add_option('--cppcheck-std-c', dest='cppcheck_std_c', default='c99', action='store', help='cppcheck standard to use when checking C (default=c99)') opt.add_option('--cppcheck-std-cxx', dest='cppcheck_std_cxx', default='c++03', action='store', help='cppcheck standard to use when checking C++ (default=c++03)') opt.add_option('--cppcheck-check-config', dest='cppcheck_check_config', default=False, action='store_true', help='forced check for missing buildin include files, e.g. stdio.h (default=False)') opt.add_option('--cppcheck-max-configs', dest='cppcheck_max_configs', default='20', action='store', help='maximum preprocessor (--max-configs) define iterations (default=20)') opt.add_option('--cppcheck-jobs', dest='cppcheck_jobs', default='1', action='store', help='number of jobs (-j) to do the checking work (default=1)') def configure(conf): if conf.options.cppcheck_skip: conf.env.CPPCHECK_SKIP = [True] conf.env.CPPCHECK_STD_C = conf.options.cppcheck_std_c conf.env.CPPCHECK_STD_CXX = conf.options.cppcheck_std_cxx conf.env.CPPCHECK_MAX_CONFIGS = conf.options.cppcheck_max_configs conf.env.CPPCHECK_BIN_ENABLE = conf.options.cppcheck_bin_enable conf.env.CPPCHECK_LIB_ENABLE = conf.options.cppcheck_lib_enable conf.env.CPPCHECK_JOBS = conf.options.cppcheck_jobs if conf.options.cppcheck_jobs != '1' and ('unusedFunction' in conf.options.cppcheck_bin_enable or 'unusedFunction' in conf.options.cppcheck_lib_enable or 'all' in conf.options.cppcheck_bin_enable or 'all' in conf.options.cppcheck_lib_enable): Logs.warn('cppcheck: unusedFunction cannot be used with multiple threads, cppcheck will disable it automatically') conf.find_program('cppcheck', var='CPPCHECK') # set to True to get a single index.html file conf.env.CPPCHECK_SINGLE_HTML = False @TaskGen.feature('c') @TaskGen.feature('cxx') def cppcheck_execute(self): if hasattr(self.bld, 'conf'): return if len(self.env.CPPCHECK_SKIP) or Options.options.cppcheck_skip: return if getattr(self, 'cppcheck_skip', False): return task = self.create_task('cppcheck') task.cmd = _tgen_create_cmd(self) task.fatal = [] if not Options.options.cppcheck_err_resume: task.fatal.append('error') def _tgen_create_cmd(self): features = getattr(self, 'features', []) std_c = self.env.CPPCHECK_STD_C std_cxx = self.env.CPPCHECK_STD_CXX max_configs = self.env.CPPCHECK_MAX_CONFIGS bin_enable = self.env.CPPCHECK_BIN_ENABLE lib_enable = self.env.CPPCHECK_LIB_ENABLE jobs = self.env.CPPCHECK_JOBS cmd = self.env.CPPCHECK args = ['--inconclusive','--report-progress','--verbose','--xml','--xml-version=2'] args.append('--max-configs=%s' % max_configs) args.append('-j %s' % jobs) if 'cxx' in features: args.append('--language=c++') args.append('--std=%s' % std_cxx) else: args.append('--language=c') args.append('--std=%s' % std_c) if Options.options.cppcheck_check_config: args.append('--check-config') if set(['cprogram','cxxprogram']) & set(features): args.append('--enable=%s' % bin_enable) else: args.append('--enable=%s' % lib_enable) for src in self.to_list(getattr(self, 'source', [])): if not isinstance(src, str): src = repr(src) args.append(src) for inc in self.to_incnodes(self.to_list(getattr(self, 'includes', []))): if not isinstance(inc, str): inc = repr(inc) args.append('-I%s' % inc) for inc in self.to_incnodes(self.to_list(self.env.INCLUDES)): if not isinstance(inc, str): inc = repr(inc) args.append('-I%s' % inc) return cmd + args class cppcheck(Task.Task): quiet = True def run(self): stderr = self.generator.bld.cmd_and_log(self.cmd, quiet=Context.STDERR, output=Context.STDERR) self._save_xml_report(stderr) defects = self._get_defects(stderr) index = self._create_html_report(defects) self._errors_evaluate(defects, index) return 0 def _save_xml_report(self, s): '''use cppcheck xml result string, add the command string used to invoke cppcheck and save as xml file. ''' header = '%s\n' % s.splitlines()[0] root = ElementTree.fromstring(s) cmd = ElementTree.SubElement(root.find('cppcheck'), 'cmd') cmd.text = str(self.cmd) body = ElementTree.tostring(root).decode('us-ascii') body_html_name = 'cppcheck-%s.xml' % self.generator.get_name() if self.env.CPPCHECK_SINGLE_HTML: body_html_name = 'cppcheck.xml' node = self.generator.path.get_bld().find_or_declare(body_html_name) node.write(header + body) def _get_defects(self, xml_string): '''evaluate the xml string returned by cppcheck (on sdterr) and use it to create a list of defects. ''' defects = [] for error in ElementTree.fromstring(xml_string).iter('error'): defect = {} defect['id'] = error.get('id') defect['severity'] = error.get('severity') defect['msg'] = str(error.get('msg')).replace('<','<') defect['verbose'] = error.get('verbose') for location in error.findall('location'): defect['file'] = location.get('file') defect['line'] = str(int(location.get('line')) - 1) defects.append(defect) return defects def _create_html_report(self, defects): files, css_style_defs = self._create_html_files(defects) index = self._create_html_index(files) self._create_css_file(css_style_defs) return index def _create_html_files(self, defects): sources = {} defects = [defect for defect in defects if 'file' in defect] for defect in defects: name = defect['file'] if not name in sources: sources[name] = [defect] else: sources[name].append(defect) files = {} css_style_defs = None bpath = self.generator.path.get_bld().abspath() names = list(sources.keys()) for i in range(0,len(names)): name = names[i] if self.env.CPPCHECK_SINGLE_HTML: htmlfile = 'cppcheck/%i.html' % (i) else: htmlfile = 'cppcheck/%s%i.html' % (self.generator.get_name(),i) errors = sources[name] files[name] = { 'htmlfile': '%s/%s' % (bpath, htmlfile), 'errors': errors } css_style_defs = self._create_html_file(name, htmlfile, errors) return files, css_style_defs def _create_html_file(self, sourcefile, htmlfile, errors): name = self.generator.get_name() root = ElementTree.fromstring(CPPCHECK_HTML_FILE) title = root.find('head/title') title.text = 'cppcheck - report - %s' % name body = root.find('body') for div in body.findall('div'): if div.get('id') == 'page': page = div break for div in page.findall('div'): if div.get('id') == 'header': h1 = div.find('h1') h1.text = 'cppcheck report - %s' % name if div.get('id') == 'menu': indexlink = div.find('a') if self.env.CPPCHECK_SINGLE_HTML: indexlink.attrib['href'] = 'index.html' else: indexlink.attrib['href'] = 'index-%s.html' % name if div.get('id') == 'content': content = div srcnode = self.generator.bld.root.find_node(sourcefile) hl_lines = [e['line'] for e in errors if 'line' in e] formatter = CppcheckHtmlFormatter(linenos=True, style='colorful', hl_lines=hl_lines, lineanchors='line') formatter.errors = [e for e in errors if 'line' in e] css_style_defs = formatter.get_style_defs('.highlight') lexer = pygments.lexers.guess_lexer_for_filename(sourcefile, "") s = pygments.highlight(srcnode.read(), lexer, formatter) table = ElementTree.fromstring(s) content.append(table) s = ElementTree.tostring(root, method='html').decode('us-ascii') s = CCPCHECK_HTML_TYPE + s node = self.generator.path.get_bld().find_or_declare(htmlfile) node.write(s) return css_style_defs def _create_html_index(self, files): name = self.generator.get_name() root = ElementTree.fromstring(CPPCHECK_HTML_FILE) title = root.find('head/title') title.text = 'cppcheck - report - %s' % name body = root.find('body') for div in body.findall('div'): if div.get('id') == 'page': page = div break for div in page.findall('div'): if div.get('id') == 'header': h1 = div.find('h1') h1.text = 'cppcheck report - %s' % name if div.get('id') == 'content': content = div self._create_html_table(content, files) if div.get('id') == 'menu': indexlink = div.find('a') if self.env.CPPCHECK_SINGLE_HTML: indexlink.attrib['href'] = 'index.html' else: indexlink.attrib['href'] = 'index-%s.html' % name s = ElementTree.tostring(root, method='html').decode('us-ascii') s = CCPCHECK_HTML_TYPE + s index_html_name = 'cppcheck/index-%s.html' % name if self.env.CPPCHECK_SINGLE_HTML: index_html_name = 'cppcheck/index.html' node = self.generator.path.get_bld().find_or_declare(index_html_name) node.write(s) return node def _create_html_table(self, content, files): table = ElementTree.fromstring(CPPCHECK_HTML_TABLE) for name, val in files.items(): f = val['htmlfile'] s = '%s\n' % (f,name) row = ElementTree.fromstring(s) table.append(row) errors = sorted(val['errors'], key=lambda e: int(e['line']) if 'line' in e else sys.maxint) for e in errors: if not 'line' in e: s = '%s%s%s\n' % (e['id'], e['severity'], e['msg']) else: attr = '' if e['severity'] == 'error': attr = 'class="error"' s = '%s' % (f, e['line'], e['line']) s+= '%s%s%s\n' % (e['id'], e['severity'], attr, e['msg']) row = ElementTree.fromstring(s) table.append(row) content.append(table) def _create_css_file(self, css_style_defs): css = str(CPPCHECK_CSS_FILE) if css_style_defs: css = "%s\n%s\n" % (css, css_style_defs) node = self.generator.path.get_bld().find_or_declare('cppcheck/style.css') node.write(css) def _errors_evaluate(self, errors, http_index): name = self.generator.get_name() fatal = self.fatal severity = [err['severity'] for err in errors] problems = [err for err in errors if err['severity'] != 'information'] if set(fatal) & set(severity): exc = "\n" exc += "\nccpcheck detected fatal error(s) in task '%s', see report for details:" % name exc += "\n file://%r" % (http_index) exc += "\n" self.generator.bld.fatal(exc) elif len(problems): msg = "\nccpcheck detected (possible) problem(s) in task '%s', see report for details:" % name msg += "\n file://%r" % http_index msg += "\n" Logs.error(msg) class CppcheckHtmlFormatter(pygments.formatters.HtmlFormatter): errors = [] def wrap(self, source, outfile): line_no = 1 for i, t in super(CppcheckHtmlFormatter, self).wrap(source, outfile): # If this is a source code line we want to add a span tag at the end. if i == 1: for error in self.errors: if int(error['line']) == line_no: t = t.replace('\n', CPPCHECK_HTML_ERROR % error['msg']) line_no += 1 yield i, t CCPCHECK_HTML_TYPE = \ '\n' CPPCHECK_HTML_FILE = """ ]> cppcheck - report - XXX
 
""" CPPCHECK_HTML_TABLE = """
Line Id Severity Message
""" CPPCHECK_HTML_ERROR = \ '<--- %s\n' CPPCHECK_CSS_FILE = """ body.body { font-family: Arial; font-size: 13px; background-color: black; padding: 0px; margin: 0px; } .error { font-family: Arial; font-size: 13px; background-color: #ffb7b7; padding: 0px; margin: 0px; } th, td { min-width: 100px; text-align: left; } #page-header { clear: both; width: 1200px; margin: 20px auto 0px auto; height: 10px; border-bottom-width: 2px; border-bottom-style: solid; border-bottom-color: #aaaaaa; } #page { width: 1160px; margin: auto; border-left-width: 2px; border-left-style: solid; border-left-color: #aaaaaa; border-right-width: 2px; border-right-style: solid; border-right-color: #aaaaaa; background-color: White; padding: 20px; } #page-footer { clear: both; width: 1200px; margin: auto; height: 10px; border-top-width: 2px; border-top-style: solid; border-top-color: #aaaaaa; } #header { width: 100%; height: 70px; background-image: url(logo.png); background-repeat: no-repeat; background-position: left top; border-bottom-style: solid; border-bottom-width: thin; border-bottom-color: #aaaaaa; } #menu { margin-top: 5px; text-align: left; float: left; width: 100px; height: 300px; } #menu > a { margin-left: 10px; display: block; } #content { float: left; width: 1020px; margin: 5px; padding: 0px 10px 10px 10px; border-left-style: solid; border-left-width: thin; border-left-color: #aaaaaa; } #footer { padding-bottom: 5px; padding-top: 5px; border-top-style: solid; border-top-width: thin; border-top-color: #aaaaaa; clear: both; font-size: 10px; } #footer > div { float: left; width: 33%; } """ ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py0000660000000000000000000001654213573675414022150 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # # written by Sylvain Rouquette, 2014 ''' This is an extra tool, not bundled with the default waf binary. To add the cpplint tool to the waf file: $ ./waf-light --tools=compat15,cpplint this tool also requires cpplint for python. If you have PIP, you can install it like this: pip install cpplint When using this tool, the wscript will look like: def options(opt): opt.load('compiler_cxx cpplint') def configure(conf): conf.load('compiler_cxx cpplint') # optional, you can also specify them on the command line conf.env.CPPLINT_FILTERS = ','.join(( '-whitespace/newline', # c++11 lambda '-readability/braces', # c++11 constructor '-whitespace/braces', # c++11 constructor '-build/storage_class', # c++11 for-range '-whitespace/blank_line', # user pref '-whitespace/labels' # user pref )) def build(bld): bld(features='cpplint', source='main.cpp', target='app') # add include files, because they aren't usually built bld(features='cpplint', source=bld.path.ant_glob('**/*.hpp')) ''' from __future__ import absolute_import import sys, re import logging from waflib import Errors, Task, TaskGen, Logs, Options, Node, Utils critical_errors = 0 CPPLINT_FORMAT = '[CPPLINT] %(filename)s:\nline %(linenum)s, severity %(confidence)s, category: %(category)s\n%(message)s\n' RE_EMACS = re.compile(r'(?P.*):(?P\d+): (?P.*) \[(?P.*)\] \[(?P\d+)\]') CPPLINT_RE = { 'waf': RE_EMACS, 'emacs': RE_EMACS, 'vs7': re.compile(r'(?P.*)\((?P\d+)\): (?P.*) \[(?P.*)\] \[(?P\d+)\]'), 'eclipse': re.compile(r'(?P.*):(?P\d+): warning: (?P.*) \[(?P.*)\] \[(?P\d+)\]'), } CPPLINT_STR = ('${CPPLINT} ' '--verbose=${CPPLINT_LEVEL} ' '--output=${CPPLINT_OUTPUT} ' '--filter=${CPPLINT_FILTERS} ' '--root=${CPPLINT_ROOT} ' '--linelength=${CPPLINT_LINE_LENGTH} ') def options(opt): opt.add_option('--cpplint-filters', type='string', default='', dest='CPPLINT_FILTERS', help='add filters to cpplint') opt.add_option('--cpplint-length', type='int', default=80, dest='CPPLINT_LINE_LENGTH', help='specify the line length (default: 80)') opt.add_option('--cpplint-level', default=1, type='int', dest='CPPLINT_LEVEL', help='specify the log level (default: 1)') opt.add_option('--cpplint-break', default=5, type='int', dest='CPPLINT_BREAK', help='break the build if error >= level (default: 5)') opt.add_option('--cpplint-root', type='string', default='', dest='CPPLINT_ROOT', help='root directory used to derive header guard') opt.add_option('--cpplint-skip', action='store_true', default=False, dest='CPPLINT_SKIP', help='skip cpplint during build') opt.add_option('--cpplint-output', type='string', default='waf', dest='CPPLINT_OUTPUT', help='select output format (waf, emacs, vs7, eclipse)') def configure(conf): try: conf.find_program('cpplint', var='CPPLINT') except Errors.ConfigurationError: conf.env.CPPLINT_SKIP = True class cpplint_formatter(Logs.formatter, object): def __init__(self, fmt): logging.Formatter.__init__(self, CPPLINT_FORMAT) self.fmt = fmt def format(self, rec): if self.fmt == 'waf': result = CPPLINT_RE[self.fmt].match(rec.msg).groupdict() rec.msg = CPPLINT_FORMAT % result if rec.levelno <= logging.INFO: rec.c1 = Logs.colors.CYAN return super(cpplint_formatter, self).format(rec) class cpplint_handler(Logs.log_handler, object): def __init__(self, stream=sys.stderr, **kw): super(cpplint_handler, self).__init__(stream, **kw) self.stream = stream def emit(self, rec): rec.stream = self.stream self.emit_override(rec) self.flush() class cpplint_wrapper(object): def __init__(self, logger, threshold, fmt): self.logger = logger self.threshold = threshold self.fmt = fmt def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): if isinstance(exc_value, Utils.subprocess.CalledProcessError): messages = [m for m in exc_value.output.splitlines() if 'Done processing' not in m and 'Total errors found' not in m] for message in messages: self.write(message) return True def write(self, message): global critical_errors result = CPPLINT_RE[self.fmt].match(message) if not result: return level = int(result.groupdict()['confidence']) if level >= self.threshold: critical_errors += 1 if level <= 2: self.logger.info(message) elif level <= 4: self.logger.warning(message) else: self.logger.error(message) cpplint_logger = None def get_cpplint_logger(fmt): global cpplint_logger if cpplint_logger: return cpplint_logger cpplint_logger = logging.getLogger('cpplint') hdlr = cpplint_handler() hdlr.setFormatter(cpplint_formatter(fmt)) cpplint_logger.addHandler(hdlr) cpplint_logger.setLevel(logging.DEBUG) return cpplint_logger class cpplint(Task.Task): color = 'PINK' def __init__(self, *k, **kw): super(cpplint, self).__init__(*k, **kw) def run(self): global critical_errors with cpplint_wrapper(get_cpplint_logger(self.env.CPPLINT_OUTPUT), self.env.CPPLINT_BREAK, self.env.CPPLINT_OUTPUT): params = {key: str(self.env[key]) for key in self.env if 'CPPLINT_' in key} if params['CPPLINT_OUTPUT'] is 'waf': params['CPPLINT_OUTPUT'] = 'emacs' params['CPPLINT'] = self.env.get_flat('CPPLINT') cmd = Utils.subst_vars(CPPLINT_STR, params) env = self.env.env or None Utils.subprocess.check_output(cmd + self.inputs[0].abspath(), stderr=Utils.subprocess.STDOUT, env=env, shell=True) return critical_errors @TaskGen.extension('.h', '.hh', '.hpp', '.hxx') def cpplint_includes(self, node): pass @TaskGen.feature('cpplint') @TaskGen.before_method('process_source') def post_cpplint(self): if not self.env.CPPLINT_INITIALIZED: for key, value in Options.options.__dict__.items(): if not key.startswith('CPPLINT_') or self.env[key]: continue self.env[key] = value self.env.CPPLINT_INITIALIZED = True if self.env.CPPLINT_SKIP: return if not self.env.CPPLINT_OUTPUT in CPPLINT_RE: return for src in self.to_list(getattr(self, 'source', [])): if isinstance(src, Node.Node): node = src else: node = self.path.find_or_declare(src) if not node: self.bld.fatal('Could not find %r' % src) self.create_task('cpplint', node) ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py0000660000000000000000000001373513573675414022502 0ustar rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 vi:ts=4:noexpandtab # Tool to provide dedicated variables for cross-compilation __author__ = __maintainer__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2014" """ This tool allows to use environment variables to define cross-compilation variables intended for build variants. The variables are obtained from the environment in 3 ways: 1. By defining CHOST, they can be derived as ${CHOST}-${TOOL} 2. By defining HOST_x 3. By defining ${CHOST//-/_}_x else one can set ``cfg.env.CHOST`` in ``wscript`` before loading ``cross_gnu``. Usage: - In your build script:: def configure(cfg): ... for variant in x_variants: setenv(variant) conf.load('cross_gnu') conf.xcheck_host_var('POUET') ... - Then:: CHOST=arm-hardfloat-linux-gnueabi waf configure env arm-hardfloat-linux-gnueabi-CC="clang -..." waf configure CFLAGS=... CHOST=arm-hardfloat-linux-gnueabi HOST_CFLAGS=-g waf configure HOST_CC="clang -..." waf configure This example ``wscript`` compiles to Microchip PIC (xc16-gcc-xyz must be in PATH): .. code:: python from waflib import Configure #from https://gist.github.com/rpuntaie/2bddfb5d7b77db26415ee14371289971 import waf_variants variants='pc fw/variant1 fw/variant2'.split() top = "." out = "../build" PIC = '33FJ128GP804' #dsPICxxx @Configure.conf def gcc_modifier_xc16(cfg): v = cfg.env v.cprogram_PATTERN = '%s.elf' v.LINKFLAGS_cprogram = ','.join(['-Wl','','','--defsym=__MPLAB_BUILD=0','','--script=p'+PIC+'.gld', '--stack=16','--check-sections','--data-init','--pack-data','--handles','--isr','--no-gc-sections', '--fill-upper=0','--stackguard=16','--no-force-link','--smart-io']) #,'--report-mem']) v.CFLAGS_cprogram=['-mcpu='+PIC,'-omf=elf','-mlarge-code','-msmart-io=1', '-msfr-warn=off','-mno-override-inline','-finline','-Winline'] def configure(cfg): if 'fw' in cfg.variant: #firmware cfg.env.DEST_OS = 'xc16' #cfg.env.CHOST = 'xc16' #works too cfg.load('c cross_gnu') #cfg.env.CHOST becomes ['xc16'] ... else: #configure for pc SW ... def build(bld): if 'fw' in bld.variant: #firmware bld.program(source='maintst.c', target='maintst'); bld(source='maintst.elf', target='maintst.hex', rule="xc16-bin2hex ${SRC} -a -omf=elf") else: #build for pc SW ... """ import os from waflib import Utils, Configure from waflib.Tools import ccroot, gcc try: from shlex import quote except ImportError: from pipes import quote def get_chost_stuff(conf): """ Get the CHOST environment variable contents """ chost = None chost_envar = None if conf.env.CHOST: chost = conf.env.CHOST[0] chost_envar = chost.replace('-', '_') return chost, chost_envar @Configure.conf def xcheck_var(conf, name, wafname=None, cross=False): wafname = wafname or name if wafname in conf.env: value = conf.env[wafname] if isinstance(value, str): value = [value] else: envar = os.environ.get(name) if not envar: return value = Utils.to_list(envar) if envar != '' else [envar] conf.env[wafname] = value if cross: pretty = 'cross-compilation %s' % wafname else: pretty = wafname conf.msg('Will use %s' % pretty, " ".join(quote(x) for x in value)) @Configure.conf def xcheck_host_prog(conf, name, tool, wafname=None): wafname = wafname or name chost, chost_envar = get_chost_stuff(conf) specific = None if chost: specific = os.environ.get('%s_%s' % (chost_envar, name)) if specific: value = Utils.to_list(specific) conf.env[wafname] += value conf.msg('Will use cross-compilation %s from %s_%s' % (name, chost_envar, name), " ".join(quote(x) for x in value)) return else: envar = os.environ.get('HOST_%s' % name) if envar is not None: value = Utils.to_list(envar) conf.env[wafname] = value conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name), " ".join(quote(x) for x in value)) return if conf.env[wafname]: return value = None if chost: value = '%s-%s' % (chost, tool) if value: conf.env[wafname] = value conf.msg('Will use cross-compilation %s from CHOST' % wafname, value) @Configure.conf def xcheck_host_envar(conf, name, wafname=None): wafname = wafname or name chost, chost_envar = get_chost_stuff(conf) specific = None if chost: specific = os.environ.get('%s_%s' % (chost_envar, name)) if specific: value = Utils.to_list(specific) conf.env[wafname] += value conf.msg('Will use cross-compilation %s from %s_%s' \ % (name, chost_envar, name), " ".join(quote(x) for x in value)) return envar = os.environ.get('HOST_%s' % name) if envar is None: return value = Utils.to_list(envar) if envar != '' else [envar] conf.env[wafname] = value conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name), " ".join(quote(x) for x in value)) @Configure.conf def xcheck_host(conf): conf.xcheck_var('CHOST', cross=True) conf.env.CHOST = conf.env.CHOST or [conf.env.DEST_OS] conf.env.DEST_OS = conf.env.CHOST[0].replace('-','_') conf.xcheck_host_prog('CC', 'gcc') conf.xcheck_host_prog('CXX', 'g++') conf.xcheck_host_prog('LINK_CC', 'gcc') conf.xcheck_host_prog('LINK_CXX', 'g++') conf.xcheck_host_prog('AR', 'ar') conf.xcheck_host_prog('AS', 'as') conf.xcheck_host_prog('LD', 'ld') conf.xcheck_host_envar('CFLAGS') conf.xcheck_host_envar('CXXFLAGS') conf.xcheck_host_envar('LDFLAGS', 'LINKFLAGS') conf.xcheck_host_envar('LIB') conf.xcheck_host_envar('PKG_CONFIG_LIBDIR') conf.xcheck_host_envar('PKG_CONFIG_PATH') if not conf.env.env: conf.env.env = {} conf.env.env.update(os.environ) if conf.env.PKG_CONFIG_LIBDIR: conf.env.env['PKG_CONFIG_LIBDIR'] = conf.env.PKG_CONFIG_LIBDIR[0] if conf.env.PKG_CONFIG_PATH: conf.env.env['PKG_CONFIG_PATH'] = conf.env.PKG_CONFIG_PATH[0] def configure(conf): """ Configuration example for gcc, it will not work for g++/clang/clang++ """ conf.xcheck_host() conf.gcc_common_flags() conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/extras/cython.py0000660000000000000000000001014513573675414021774 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010-2015 import re from waflib import Task, Logs from waflib.TaskGen import extension cy_api_pat = re.compile(r'\s*?cdef\s*?(public|api)\w*') re_cyt = re.compile(r""" ^\s* # must begin with some whitespace characters (?:from\s+(\w+)(?:\.\w+)*\s+)? # optionally match "from foo(.baz)" and capture foo c?import\s(\w+|[*]) # require "import bar" and capture bar """, re.M | re.VERBOSE) @extension('.pyx') def add_cython_file(self, node): """ Process a *.pyx* file given in the list of source files. No additional feature is required:: def build(bld): bld(features='c cshlib pyext', source='main.c foo.pyx', target='app') """ ext = '.c' if 'cxx' in self.features: self.env.append_unique('CYTHONFLAGS', '--cplus') ext = '.cc' for x in getattr(self, 'cython_includes', []): # TODO re-use these nodes in "scan" below d = self.path.find_dir(x) if d: self.env.append_unique('CYTHONFLAGS', '-I%s' % d.abspath()) tsk = self.create_task('cython', node, node.change_ext(ext)) self.source += tsk.outputs class cython(Task.Task): run_str = '${CYTHON} ${CYTHONFLAGS} -o ${TGT[0].abspath()} ${SRC}' color = 'GREEN' vars = ['INCLUDES'] """ Rebuild whenever the INCLUDES change. The variables such as CYTHONFLAGS will be appended by the metaclass. """ ext_out = ['.h'] """ The creation of a .h file is known only after the build has begun, so it is not possible to compute a build order just by looking at the task inputs/outputs. """ def runnable_status(self): """ Perform a double-check to add the headers created by cython to the output nodes. The scanner is executed only when the cython task must be executed (optimization). """ ret = super(cython, self).runnable_status() if ret == Task.ASK_LATER: return ret for x in self.generator.bld.raw_deps[self.uid()]: if x.startswith('header:'): self.outputs.append(self.inputs[0].parent.find_or_declare(x.replace('header:', ''))) return super(cython, self).runnable_status() def post_run(self): for x in self.outputs: if x.name.endswith('.h'): if not x.exists(): if Logs.verbose: Logs.warn('Expected %r', x.abspath()) x.write('') return Task.Task.post_run(self) def scan(self): """ Return the dependent files (.pxd) by looking in the include folders. Put the headers to generate in the custom list "bld.raw_deps". To inspect the scanne results use:: $ waf clean build --zones=deps """ node = self.inputs[0] txt = node.read() mods = set() for m in re_cyt.finditer(txt): if m.group(1): # matches "from foo import bar" mods.add(m.group(1)) else: mods.add(m.group(2)) Logs.debug('cython: mods %r', mods) incs = getattr(self.generator, 'cython_includes', []) incs = [self.generator.path.find_dir(x) for x in incs] incs.append(node.parent) found = [] missing = [] for x in sorted(mods): for y in incs: k = y.find_resource(x + '.pxd') if k: found.append(k) break else: missing.append(x) # the cython file implicitly depends on a pxd file that might be present implicit = node.parent.find_resource(node.name[:-3] + 'pxd') if implicit: found.append(implicit) Logs.debug('cython: found %r', found) # Now the .h created - store them in bld.raw_deps for later use has_api = False has_public = False for l in txt.splitlines(): if cy_api_pat.match(l): if ' api ' in l: has_api = True if ' public ' in l: has_public = True name = node.name.replace('.pyx', '') if has_api: missing.append('header:%s_api.h' % name) if has_public: missing.append('header:%s.h' % name) return (found, missing) def options(ctx): ctx.add_option('--cython-flags', action='store', default='', help='space separated list of flags to pass to cython') def configure(ctx): if not ctx.env.CC and not ctx.env.CXX: ctx.fatal('Load a C/C++ compiler first') if not ctx.env.PYTHON: ctx.fatal('Load the python tool first!') ctx.find_program('cython', var='CYTHON') if hasattr(ctx.options, 'cython_flags'): ctx.env.CYTHONFLAGS = ctx.options.cython_flags ldb-2.0.8/third_party/waf/waflib/extras/dcc.py0000660000000000000000000000357313573675414021230 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Jérôme Carretero, 2011 (zougloub) from waflib import Options from waflib.Tools import ccroot from waflib.Configure import conf @conf def find_dcc(conf): conf.find_program(['dcc'], var='CC', path_list=getattr(Options.options, 'diabbindir', "")) conf.env.CC_NAME = 'dcc' @conf def find_dld(conf): conf.find_program(['dld'], var='LINK_CC', path_list=getattr(Options.options, 'diabbindir', "")) conf.env.LINK_CC_NAME = 'dld' @conf def find_dar(conf): conf.find_program(['dar'], var='AR', path_list=getattr(Options.options, 'diabbindir', "")) conf.env.AR_NAME = 'dar' conf.env.ARFLAGS = 'rcs' @conf def find_ddump(conf): conf.find_program(['ddump'], var='DDUMP', path_list=getattr(Options.options, 'diabbindir', "")) @conf def dcc_common_flags(conf): v = conf.env v['CC_SRC_F'] = [] v['CC_TGT_F'] = ['-c', '-o'] # linker if not v['LINK_CC']: v['LINK_CC'] = v['CC'] v['CCLNK_SRC_F'] = [] v['CCLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' v['LIB_ST'] = '-l:%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l:%s' v['STLIBPATH_ST'] = '-L%s' v['RPATH_ST'] = '-Wl,-rpath,%s' #v['STLIB_MARKER'] = '-Wl,-Bstatic' # program v['cprogram_PATTERN'] = '%s.elf' # static lib v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic'] v['cstlib_PATTERN'] = 'lib%s.a' def configure(conf): conf.find_dcc() conf.find_dar() conf.find_dld() conf.find_ddump() conf.dcc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() def options(opt): """ Add the ``--with-diab-bindir`` command-line options. """ opt.add_option('--with-diab-bindir', type='string', dest='diabbindir', help = 'Specify alternate diab bin folder', default="") ldb-2.0.8/third_party/waf/waflib/extras/distnet.py0000660000000000000000000002650513573675414022151 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 """ waf-powered distributed network builds, with a network cache. Caching files from a server has advantages over a NFS/Samba shared folder: - builds are much faster because they use local files - builds just continue to work in case of a network glitch - permissions are much simpler to manage """ import os, urllib, tarfile, re, shutil, tempfile, sys from collections import OrderedDict from waflib import Context, Utils, Logs try: from urllib.parse import urlencode except ImportError: urlencode = urllib.urlencode def safe_urlencode(data): x = urlencode(data) try: x = x.encode('utf-8') except Exception: pass return x try: from urllib.error import URLError except ImportError: from urllib2 import URLError try: from urllib.request import Request, urlopen except ImportError: from urllib2 import Request, urlopen DISTNETCACHE = os.environ.get('DISTNETCACHE', '/tmp/distnetcache') DISTNETSERVER = os.environ.get('DISTNETSERVER', 'http://localhost:8000/cgi-bin/') TARFORMAT = 'w:bz2' TIMEOUT = 60 REQUIRES = 'requires.txt' re_com = re.compile(r'\s*#.*', re.M) def total_version_order(num): lst = num.split('.') template = '%10s' * len(lst) ret = template % tuple(lst) return ret def get_distnet_cache(): return getattr(Context.g_module, 'DISTNETCACHE', DISTNETCACHE) def get_server_url(): return getattr(Context.g_module, 'DISTNETSERVER', DISTNETSERVER) def get_download_url(): return '%s/download.py' % get_server_url() def get_upload_url(): return '%s/upload.py' % get_server_url() def get_resolve_url(): return '%s/resolve.py' % get_server_url() def send_package_name(): out = getattr(Context.g_module, 'out', 'build') pkgfile = '%s/package_to_upload.tarfile' % out return pkgfile class package(Context.Context): fun = 'package' cmd = 'package' def execute(self): try: files = self.files except AttributeError: files = self.files = [] Context.Context.execute(self) pkgfile = send_package_name() if not pkgfile in files: if not REQUIRES in files: files.append(REQUIRES) self.make_tarfile(pkgfile, files, add_to_package=False) def make_tarfile(self, filename, files, **kw): if kw.get('add_to_package', True): self.files.append(filename) with tarfile.open(filename, TARFORMAT) as tar: endname = os.path.split(filename)[-1] endname = endname.split('.')[0] + '/' for x in files: tarinfo = tar.gettarinfo(x, x) tarinfo.uid = tarinfo.gid = 0 tarinfo.uname = tarinfo.gname = 'root' tarinfo.size = os.stat(x).st_size # TODO - more archive creation options? if kw.get('bare', True): tarinfo.name = os.path.split(x)[1] else: tarinfo.name = endname + x # todo, if tuple, then.. Logs.debug('distnet: adding %r to %s', tarinfo.name, filename) with open(x, 'rb') as f: tar.addfile(tarinfo, f) Logs.info('Created %s', filename) class publish(Context.Context): fun = 'publish' cmd = 'publish' def execute(self): if hasattr(Context.g_module, 'publish'): Context.Context.execute(self) mod = Context.g_module rfile = getattr(self, 'rfile', send_package_name()) if not os.path.isfile(rfile): self.fatal('Create the release file with "waf release" first! %r' % rfile) fdata = Utils.readf(rfile, m='rb') data = safe_urlencode([('pkgdata', fdata), ('pkgname', mod.APPNAME), ('pkgver', mod.VERSION)]) req = Request(get_upload_url(), data) response = urlopen(req, timeout=TIMEOUT) data = response.read().strip() if sys.hexversion>0x300000f: data = data.decode('utf-8') if data != 'ok': self.fatal('Could not publish the package %r' % data) class constraint(object): def __init__(self, line=''): self.required_line = line self.info = [] line = line.strip() if not line: return lst = line.split(',') if lst: self.pkgname = lst[0] self.required_version = lst[1] for k in lst: a, b, c = k.partition('=') if a and c: self.info.append((a, c)) def __str__(self): buf = [] buf.append(self.pkgname) buf.append(self.required_version) for k in self.info: buf.append('%s=%s' % k) return ','.join(buf) def __repr__(self): return "requires %s-%s" % (self.pkgname, self.required_version) def human_display(self, pkgname, pkgver): return '%s-%s requires %s-%s' % (pkgname, pkgver, self.pkgname, self.required_version) def why(self): ret = [] for x in self.info: if x[0] == 'reason': ret.append(x[1]) return ret def add_reason(self, reason): self.info.append(('reason', reason)) def parse_constraints(text): assert(text is not None) constraints = [] text = re.sub(re_com, '', text) lines = text.splitlines() for line in lines: line = line.strip() if not line: continue constraints.append(constraint(line)) return constraints def list_package_versions(cachedir, pkgname): pkgdir = os.path.join(cachedir, pkgname) try: versions = os.listdir(pkgdir) except OSError: return [] versions.sort(key=total_version_order) versions.reverse() return versions class package_reader(Context.Context): cmd = 'solver' fun = 'solver' def __init__(self, **kw): Context.Context.__init__(self, **kw) self.myproject = getattr(Context.g_module, 'APPNAME', 'project') self.myversion = getattr(Context.g_module, 'VERSION', '1.0') self.cache_constraints = {} self.constraints = [] def compute_dependencies(self, filename=REQUIRES): text = Utils.readf(filename) data = safe_urlencode([('text', text)]) if '--offline' in sys.argv: self.constraints = self.local_resolve(text) else: req = Request(get_resolve_url(), data) try: response = urlopen(req, timeout=TIMEOUT) except URLError as e: Logs.warn('The package server is down! %r', e) self.constraints = self.local_resolve(text) else: ret = response.read() try: ret = ret.decode('utf-8') except Exception: pass self.trace(ret) self.constraints = parse_constraints(ret) self.check_errors() def check_errors(self): errors = False for c in self.constraints: if not c.required_version: errors = True reasons = c.why() if len(reasons) == 1: Logs.error('%s but no matching package could be found in this repository', reasons[0]) else: Logs.error('Conflicts on package %r:', c.pkgname) for r in reasons: Logs.error(' %s', r) if errors: self.fatal('The package requirements cannot be satisfied!') def load_constraints(self, pkgname, pkgver, requires=REQUIRES): try: return self.cache_constraints[(pkgname, pkgver)] except KeyError: text = Utils.readf(os.path.join(get_distnet_cache(), pkgname, pkgver, requires)) ret = parse_constraints(text) self.cache_constraints[(pkgname, pkgver)] = ret return ret def apply_constraint(self, domain, constraint): vname = constraint.required_version.replace('*', '.*') rev = re.compile(vname, re.M) ret = [x for x in domain if rev.match(x)] return ret def trace(self, *k): if getattr(self, 'debug', None): Logs.error(*k) def solve(self, packages_to_versions={}, packages_to_constraints={}, pkgname='', pkgver='', todo=[], done=[]): # breadth first search n_packages_to_versions = dict(packages_to_versions) n_packages_to_constraints = dict(packages_to_constraints) self.trace("calling solve with %r %r %r" % (packages_to_versions, todo, done)) done = done + [pkgname] constraints = self.load_constraints(pkgname, pkgver) self.trace("constraints %r" % constraints) for k in constraints: try: domain = n_packages_to_versions[k.pkgname] except KeyError: domain = list_package_versions(get_distnet_cache(), k.pkgname) self.trace("constraints?") if not k.pkgname in done: todo = todo + [k.pkgname] self.trace("domain before %s -> %s, %r" % (pkgname, k.pkgname, domain)) # apply the constraint domain = self.apply_constraint(domain, k) self.trace("domain after %s -> %s, %r" % (pkgname, k.pkgname, domain)) n_packages_to_versions[k.pkgname] = domain # then store the constraint applied constraints = list(packages_to_constraints.get(k.pkgname, [])) constraints.append((pkgname, pkgver, k)) n_packages_to_constraints[k.pkgname] = constraints if not domain: self.trace("no domain while processing constraint %r from %r %r" % (domain, pkgname, pkgver)) return (n_packages_to_versions, n_packages_to_constraints) # next package on the todo list if not todo: return (n_packages_to_versions, n_packages_to_constraints) n_pkgname = todo[0] n_pkgver = n_packages_to_versions[n_pkgname][0] tmp = dict(n_packages_to_versions) tmp[n_pkgname] = [n_pkgver] self.trace("fixed point %s" % n_pkgname) return self.solve(tmp, n_packages_to_constraints, n_pkgname, n_pkgver, todo[1:], done) def get_results(self): return '\n'.join([str(c) for c in self.constraints]) def solution_to_constraints(self, versions, constraints): solution = [] for p in versions: c = constraint() solution.append(c) c.pkgname = p if versions[p]: c.required_version = versions[p][0] else: c.required_version = '' for (from_pkgname, from_pkgver, c2) in constraints.get(p, ''): c.add_reason(c2.human_display(from_pkgname, from_pkgver)) return solution def local_resolve(self, text): self.cache_constraints[(self.myproject, self.myversion)] = parse_constraints(text) p2v = OrderedDict({self.myproject: [self.myversion]}) (versions, constraints) = self.solve(p2v, {}, self.myproject, self.myversion, []) return self.solution_to_constraints(versions, constraints) def download_to_file(self, pkgname, pkgver, subdir, tmp): data = safe_urlencode([('pkgname', pkgname), ('pkgver', pkgver), ('pkgfile', subdir)]) req = urlopen(get_download_url(), data, timeout=TIMEOUT) with open(tmp, 'wb') as f: while True: buf = req.read(8192) if not buf: break f.write(buf) def extract_tar(self, subdir, pkgdir, tmpfile): with tarfile.open(tmpfile) as f: temp = tempfile.mkdtemp(dir=pkgdir) try: f.extractall(temp) os.rename(temp, os.path.join(pkgdir, subdir)) finally: try: shutil.rmtree(temp) except Exception: pass def get_pkg_dir(self, pkgname, pkgver, subdir): pkgdir = os.path.join(get_distnet_cache(), pkgname, pkgver) if not os.path.isdir(pkgdir): os.makedirs(pkgdir) target = os.path.join(pkgdir, subdir) if os.path.exists(target): return target (fd, tmp) = tempfile.mkstemp(dir=pkgdir) try: os.close(fd) self.download_to_file(pkgname, pkgver, subdir, tmp) if subdir == REQUIRES: os.rename(tmp, target) else: self.extract_tar(subdir, pkgdir, tmp) finally: try: os.remove(tmp) except OSError: pass return target def __iter__(self): if not self.constraints: self.compute_dependencies() for x in self.constraints: if x.pkgname == self.myproject: continue yield x def execute(self): self.compute_dependencies() packages = package_reader() def load_tools(ctx, extra): global packages for c in packages: packages.get_pkg_dir(c.pkgname, c.required_version, extra) noarchdir = packages.get_pkg_dir(c.pkgname, c.required_version, 'noarch') for x in os.listdir(noarchdir): if x.startswith('waf_') and x.endswith('.py'): ctx.load([x.rstrip('.py')], tooldir=[noarchdir]) def options(opt): opt.add_option('--offline', action='store_true') packages.execute() load_tools(opt, REQUIRES) def configure(conf): load_tools(conf, conf.variant) def build(bld): load_tools(bld, bld.variant) ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py0000660000000000000000000001624613573675414022155 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: UTF-8 # Thomas Nagy 2008-2010 (ita) """ Doxygen support Variables passed to bld(): * doxyfile -- the Doxyfile to use * doxy_tar -- destination archive for generated documentation (if desired) * install_path -- where to install the documentation * pars -- dictionary overriding doxygen configuration settings When using this tool, the wscript will look like: def options(opt): opt.load('doxygen') def configure(conf): conf.load('doxygen') # check conf.env.DOXYGEN, if it is mandatory def build(bld): if bld.env.DOXYGEN: bld(features="doxygen", doxyfile='Doxyfile', ...) """ import os, os.path, re from collections import OrderedDict from waflib import Task, Utils, Node from waflib.TaskGen import feature DOXY_STR = '"${DOXYGEN}" - ' DOXY_FMTS = 'html latex man rft xml'.split() DOXY_FILE_PATTERNS = '*.' + ' *.'.join(''' c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx hpp h++ idl odl cs php php3 inc m mm py f90c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx '''.split()) re_rl = re.compile('\\\\\r*\n', re.MULTILINE) re_nl = re.compile('\r*\n', re.M) def parse_doxy(txt): ''' Parses a doxygen file. Returns an ordered dictionary. We cannot return a default dictionary, as the order in which the entries are reported does matter, especially for the '@INCLUDE' lines. ''' tbl = OrderedDict() txt = re_rl.sub('', txt) lines = re_nl.split(txt) for x in lines: x = x.strip() if not x or x.startswith('#') or x.find('=') < 0: continue if x.find('+=') >= 0: tmp = x.split('+=') key = tmp[0].strip() if key in tbl: tbl[key] += ' ' + '+='.join(tmp[1:]).strip() else: tbl[key] = '+='.join(tmp[1:]).strip() else: tmp = x.split('=') tbl[tmp[0].strip()] = '='.join(tmp[1:]).strip() return tbl class doxygen(Task.Task): vars = ['DOXYGEN', 'DOXYFLAGS'] color = 'BLUE' def runnable_status(self): ''' self.pars are populated in runnable_status - because this function is being run *before* both self.pars "consumers" - scan() and run() set output_dir (node) for the output ''' for x in self.run_after: if not x.hasrun: return Task.ASK_LATER if not getattr(self, 'pars', None): txt = self.inputs[0].read() self.pars = parse_doxy(txt) # Override with any parameters passed to the task generator if getattr(self.generator, 'pars', None): for k, v in self.generator.pars.items(): self.pars[k] = v if self.pars.get('OUTPUT_DIRECTORY'): # Use the path parsed from the Doxyfile as an absolute path output_node = self.inputs[0].parent.get_bld().make_node(self.pars['OUTPUT_DIRECTORY']) else: # If no OUTPUT_PATH was specified in the Doxyfile, build path from the Doxyfile name + '.doxy' output_node = self.inputs[0].parent.get_bld().make_node(self.inputs[0].name + '.doxy') output_node.mkdir() self.pars['OUTPUT_DIRECTORY'] = output_node.abspath() self.doxy_inputs = getattr(self, 'doxy_inputs', []) if not self.pars.get('INPUT'): self.doxy_inputs.append(self.inputs[0].parent) else: for i in self.pars.get('INPUT').split(): if os.path.isabs(i): node = self.generator.bld.root.find_node(i) else: node = self.inputs[0].parent.find_node(i) if not node: self.generator.bld.fatal('Could not find the doxygen input %r' % i) self.doxy_inputs.append(node) if not getattr(self, 'output_dir', None): bld = self.generator.bld # Output path is always an absolute path as it was transformed above. self.output_dir = bld.root.find_dir(self.pars['OUTPUT_DIRECTORY']) self.signature() ret = Task.Task.runnable_status(self) if ret == Task.SKIP_ME: # in case the files were removed self.add_install() return ret def scan(self): exclude_patterns = self.pars.get('EXCLUDE_PATTERNS','').split() exclude_patterns = [pattern.replace('*/', '**/') for pattern in exclude_patterns] file_patterns = self.pars.get('FILE_PATTERNS','').split() if not file_patterns: file_patterns = DOXY_FILE_PATTERNS.split() if self.pars.get('RECURSIVE') == 'YES': file_patterns = ["**/%s" % pattern for pattern in file_patterns] nodes = [] names = [] for node in self.doxy_inputs: if os.path.isdir(node.abspath()): for m in node.ant_glob(incl=file_patterns, excl=exclude_patterns): nodes.append(m) else: nodes.append(node) return (nodes, names) def run(self): dct = self.pars.copy() code = '\n'.join(['%s = %s' % (x, dct[x]) for x in self.pars]) code = code.encode() # for python 3 #fmt = DOXY_STR % (self.inputs[0].parent.abspath()) cmd = Utils.subst_vars(DOXY_STR, self.env) env = self.env.env or None proc = Utils.subprocess.Popen(cmd, shell=True, stdin=Utils.subprocess.PIPE, env=env, cwd=self.inputs[0].parent.abspath()) proc.communicate(code) return proc.returncode def post_run(self): nodes = self.output_dir.ant_glob('**/*', quiet=True) for x in nodes: self.generator.bld.node_sigs[x] = self.uid() self.add_install() return Task.Task.post_run(self) def add_install(self): nodes = self.output_dir.ant_glob('**/*', quiet=True) self.outputs += nodes if getattr(self.generator, 'install_path', None): if not getattr(self.generator, 'doxy_tar', None): self.generator.add_install_files(install_to=self.generator.install_path, install_from=self.outputs, postpone=False, cwd=self.output_dir, relative_trick=True) class tar(Task.Task): "quick tar creation" run_str = '${TAR} ${TAROPTS} ${TGT} ${SRC}' color = 'RED' after = ['doxygen'] def runnable_status(self): for x in getattr(self, 'input_tasks', []): if not x.hasrun: return Task.ASK_LATER if not getattr(self, 'tar_done_adding', None): # execute this only once self.tar_done_adding = True for x in getattr(self, 'input_tasks', []): self.set_inputs(x.outputs) if not self.inputs: return Task.SKIP_ME return Task.Task.runnable_status(self) def __str__(self): tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs]) return '%s: %s\n' % (self.__class__.__name__, tgt_str) @feature('doxygen') def process_doxy(self): if not getattr(self, 'doxyfile', None): self.bld.fatal('no doxyfile variable specified??') node = self.doxyfile if not isinstance(node, Node.Node): node = self.path.find_resource(node) if not node: self.bld.fatal('doxygen file %s not found' % self.doxyfile) # the task instance dsk = self.create_task('doxygen', node) if getattr(self, 'doxy_tar', None): tsk = self.create_task('tar') tsk.input_tasks = [dsk] tsk.set_outputs(self.path.find_or_declare(self.doxy_tar)) if self.doxy_tar.endswith('bz2'): tsk.env['TAROPTS'] = ['cjf'] elif self.doxy_tar.endswith('gz'): tsk.env['TAROPTS'] = ['czf'] else: tsk.env['TAROPTS'] = ['cf'] if getattr(self, 'install_path', None): self.add_install_files(install_to=self.install_path, install_from=tsk.outputs) def configure(conf): ''' Check if doxygen and tar commands are present in the system If the commands are present, then conf.env.DOXYGEN and conf.env.TAR variables will be set. Detection can be controlled by setting DOXYGEN and TAR environmental variables. ''' conf.find_program('doxygen', var='DOXYGEN', mandatory=False) conf.find_program('tar', var='TAR', mandatory=False) ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py0000660000000000000000000000556613573675414021600 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Matt Clarkson, 2012 ''' DPAPI access library (http://msdn.microsoft.com/en-us/library/ms995355.aspx) This file uses code originally created by Crusher Joe: http://article.gmane.org/gmane.comp.python.ctypes/420 And modified by Wayne Koorts: http://stackoverflow.com/questions/463832/using-dpapi-with-python ''' from ctypes import windll, byref, cdll, Structure, POINTER, c_char, c_buffer from ctypes.wintypes import DWORD from waflib.Configure import conf LocalFree = windll.kernel32.LocalFree memcpy = cdll.msvcrt.memcpy CryptProtectData = windll.crypt32.CryptProtectData CryptUnprotectData = windll.crypt32.CryptUnprotectData CRYPTPROTECT_UI_FORBIDDEN = 0x01 try: extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd'.encode('ascii') except AttributeError: extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd' class DATA_BLOB(Structure): _fields_ = [ ('cbData', DWORD), ('pbData', POINTER(c_char)) ] def get_data(blob_out): cbData = int(blob_out.cbData) pbData = blob_out.pbData buffer = c_buffer(cbData) memcpy(buffer, pbData, cbData) LocalFree(pbData) return buffer.raw @conf def dpapi_encrypt_data(self, input_bytes, entropy = extra_entropy): ''' Encrypts data and returns byte string :param input_bytes: The data to be encrypted :type input_bytes: String or Bytes :param entropy: Extra entropy to add to the encryption process (optional) :type entropy: String or Bytes ''' if not isinstance(input_bytes, bytes) or not isinstance(entropy, bytes): self.fatal('The inputs to dpapi must be bytes') buffer_in = c_buffer(input_bytes, len(input_bytes)) buffer_entropy = c_buffer(entropy, len(entropy)) blob_in = DATA_BLOB(len(input_bytes), buffer_in) blob_entropy = DATA_BLOB(len(entropy), buffer_entropy) blob_out = DATA_BLOB() if CryptProtectData(byref(blob_in), 'python_data', byref(blob_entropy), None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)): return get_data(blob_out) else: self.fatal('Failed to decrypt data') @conf def dpapi_decrypt_data(self, encrypted_bytes, entropy = extra_entropy): ''' Decrypts data and returns byte string :param encrypted_bytes: The encrypted data :type encrypted_bytes: Bytes :param entropy: Extra entropy to add to the encryption process (optional) :type entropy: String or Bytes ''' if not isinstance(encrypted_bytes, bytes) or not isinstance(entropy, bytes): self.fatal('The inputs to dpapi must be bytes') buffer_in = c_buffer(encrypted_bytes, len(encrypted_bytes)) buffer_entropy = c_buffer(entropy, len(entropy)) blob_in = DATA_BLOB(len(encrypted_bytes), buffer_in) blob_entropy = DATA_BLOB(len(entropy), buffer_entropy) blob_out = DATA_BLOB() if CryptUnprotectData(byref(blob_in), None, byref(blob_entropy), None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)): return get_data(blob_out) else: self.fatal('Failed to decrypt data') ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py0000660000000000000000000003777613573675414022137 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Eclipse CDT 5.0 generator for Waf # Richard Quirk 2009-1011 (New BSD License) # Thomas Nagy 2011 (ported to Waf 1.6) """ Usage: def options(opt): opt.load('eclipse') $ waf configure eclipse """ import sys, os from waflib import Utils, Logs, Context, Build, TaskGen, Scripting, Errors, Node from xml.dom.minidom import Document STANDARD_INCLUDES = [ '/usr/local/include', '/usr/include' ] oe_cdt = 'org.eclipse.cdt' cdt_mk = oe_cdt + '.make.core' cdt_core = oe_cdt + '.core' cdt_bld = oe_cdt + '.build.core' extbuilder_dir = '.externalToolBuilders' extbuilder_name = 'Waf_Builder.launch' class eclipse(Build.BuildContext): cmd = 'eclipse' fun = Scripting.default_cmd def execute(self): """ Entry point """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) self.create_cproject(appname, pythonpath=self.env['ECLIPSE_PYTHON_PATH']) # Helper to dump the XML document content to XML with UTF-8 encoding def write_conf_to_xml(self, filename, document): self.srcnode.make_node(filename).write(document.toprettyxml(encoding='UTF-8'), flags='wb') def create_cproject(self, appname, workspace_includes=[], pythonpath=[]): """ Create the Eclipse CDT .project and .cproject files @param appname The name that will appear in the Project Explorer @param build The BuildContext object to extract includes from @param workspace_includes Optional project includes to prevent "Unresolved Inclusion" errors in the Eclipse editor @param pythonpath Optional project specific python paths """ hasc = hasjava = haspython = False source_dirs = [] cpppath = self.env['CPPPATH'] javasrcpath = [] javalibpath = [] includes = STANDARD_INCLUDES if sys.platform != 'win32': cc = self.env.CC or self.env.CXX if cc: cmd = cc + ['-xc++', '-E', '-Wp,-v', '-'] try: gccout = self.cmd_and_log(cmd, output=Context.STDERR, quiet=Context.BOTH, input='\n'.encode()).splitlines() except Errors.WafError: pass else: includes = [] for ipath in gccout: if ipath.startswith(' /'): includes.append(ipath[1:]) cpppath += includes Logs.warn('Generating Eclipse CDT project files') for g in self.groups: for tg in g: if not isinstance(tg, TaskGen.task_gen): continue tg.post() # Add local Python modules paths to configuration so object resolving will work in IDE # This may also contain generated files (ie. pyqt5 or protoc) that get picked from build if 'py' in tg.features: pypath = tg.path.relpath() py_installfrom = getattr(tg, 'install_from', None) if isinstance(py_installfrom, Node.Node): pypath = py_installfrom.path_from(self.root.make_node(self.top_dir)) if pypath not in pythonpath: pythonpath.append(pypath) haspython = True # Add Java source directories so object resolving works in IDE # This may also contain generated files (ie. protoc) that get picked from build if 'javac' in tg.features: java_src = tg.path.relpath() java_srcdir = getattr(tg.javac_task, 'srcdir', None) if java_srcdir: if isinstance(java_srcdir, Node.Node): java_srcdir = [java_srcdir] for x in Utils.to_list(java_srcdir): x = x.path_from(self.root.make_node(self.top_dir)) if x not in javasrcpath: javasrcpath.append(x) else: if java_src not in javasrcpath: javasrcpath.append(java_src) hasjava = True # Check if there are external dependencies and add them as external jar so they will be resolved by Eclipse usedlibs=getattr(tg, 'use', []) for x in Utils.to_list(usedlibs): for cl in Utils.to_list(tg.env['CLASSPATH_'+x]): if cl not in javalibpath: javalibpath.append(cl) if not getattr(tg, 'link_task', None): continue features = Utils.to_list(getattr(tg, 'features', '')) is_cc = 'c' in features or 'cxx' in features incnodes = tg.to_incnodes(tg.to_list(getattr(tg, 'includes', [])) + tg.env['INCLUDES']) for p in incnodes: path = p.path_from(self.srcnode) if (path.startswith("/")): cpppath.append(path) else: workspace_includes.append(path) if is_cc and path not in source_dirs: source_dirs.append(path) hasc = True waf_executable = os.path.abspath(sys.argv[0]) project = self.impl_create_project(sys.executable, appname, hasc, hasjava, haspython, waf_executable) self.write_conf_to_xml('.project', project) if hasc: project = self.impl_create_cproject(sys.executable, waf_executable, appname, workspace_includes, cpppath, source_dirs) self.write_conf_to_xml('.cproject', project) if haspython: project = self.impl_create_pydevproject(sys.path, pythonpath) self.write_conf_to_xml('.pydevproject', project) if hasjava: project = self.impl_create_javaproject(javasrcpath, javalibpath) self.write_conf_to_xml('.classpath', project) def impl_create_project(self, executable, appname, hasc, hasjava, haspython, waf_executable): doc = Document() projectDescription = doc.createElement('projectDescription') self.add(doc, projectDescription, 'name', appname) self.add(doc, projectDescription, 'comment') self.add(doc, projectDescription, 'projects') buildSpec = self.add(doc, projectDescription, 'buildSpec') buildCommand = self.add(doc, buildSpec, 'buildCommand') self.add(doc, buildCommand, 'triggers', 'clean,full,incremental,') arguments = self.add(doc, buildCommand, 'arguments') dictionaries = {} # If CDT is present, instruct this one to call waf as it is more flexible (separate build/clean ...) if hasc: self.add(doc, buildCommand, 'name', oe_cdt + '.managedbuilder.core.genmakebuilder') # the default make-style targets are overwritten by the .cproject values dictionaries = { cdt_mk + '.contents': cdt_mk + '.activeConfigSettings', cdt_mk + '.enableAutoBuild': 'false', cdt_mk + '.enableCleanBuild': 'true', cdt_mk + '.enableFullBuild': 'true', } else: # Otherwise for Java/Python an external builder tool is created that will call waf build self.add(doc, buildCommand, 'name', 'org.eclipse.ui.externaltools.ExternalToolBuilder') dictionaries = { 'LaunchConfigHandle': '/%s/%s'%(extbuilder_dir, extbuilder_name), } # The definition is in a separate directory XML file try: os.mkdir(extbuilder_dir) except OSError: pass # Ignore error if already exists # Populate here the external builder XML calling waf builder = Document() launchConfiguration = doc.createElement('launchConfiguration') launchConfiguration.setAttribute('type', 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType') self.add(doc, launchConfiguration, 'booleanAttribute', {'key': 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'false'}) self.add(doc, launchConfiguration, 'booleanAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED', 'value': 'true'}) self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': waf_executable}) self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'full,incremental,'}) self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': 'build'}) self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': '${project_loc}'}) builder.appendChild(launchConfiguration) # And write the XML to the file references before self.write_conf_to_xml('%s%s%s'%(extbuilder_dir, os.path.sep, extbuilder_name), builder) for k, v in dictionaries.items(): self.addDictionary(doc, arguments, k, v) natures = self.add(doc, projectDescription, 'natures') if hasc: nature_list = """ core.ccnature managedbuilder.core.ScannerConfigNature managedbuilder.core.managedBuildNature core.cnature """.split() for n in nature_list: self.add(doc, natures, 'nature', oe_cdt + '.' + n) if haspython: self.add(doc, natures, 'nature', 'org.python.pydev.pythonNature') if hasjava: self.add(doc, natures, 'nature', 'org.eclipse.jdt.core.javanature') doc.appendChild(projectDescription) return doc def impl_create_cproject(self, executable, waf_executable, appname, workspace_includes, cpppath, source_dirs=[]): doc = Document() doc.appendChild(doc.createProcessingInstruction('fileVersion', '4.0.0')) cconf_id = cdt_core + '.default.config.1' cproject = doc.createElement('cproject') storageModule = self.add(doc, cproject, 'storageModule', {'moduleId': cdt_core + '.settings'}) cconf = self.add(doc, storageModule, 'cconfiguration', {'id':cconf_id}) storageModule = self.add(doc, cconf, 'storageModule', {'buildSystemId': oe_cdt + '.managedbuilder.core.configurationDataProvider', 'id': cconf_id, 'moduleId': cdt_core + '.settings', 'name': 'Default'}) self.add(doc, storageModule, 'externalSettings') extensions = self.add(doc, storageModule, 'extensions') extension_list = """ VCErrorParser MakeErrorParser GCCErrorParser GASErrorParser GLDErrorParser """.split() self.add(doc, extensions, 'extension', {'id': cdt_core + '.ELF', 'point':cdt_core + '.BinaryParser'}) for e in extension_list: self.add(doc, extensions, 'extension', {'id': cdt_core + '.' + e, 'point':cdt_core + '.ErrorParser'}) storageModule = self.add(doc, cconf, 'storageModule', {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'}) config = self.add(doc, storageModule, 'configuration', {'artifactName': appname, 'id': cconf_id, 'name': 'Default', 'parent': cdt_bld + '.prefbase.cfg'}) folderInfo = self.add(doc, config, 'folderInfo', {'id': cconf_id+'.', 'name': '/', 'resourcePath': ''}) toolChain = self.add(doc, folderInfo, 'toolChain', {'id': cdt_bld + '.prefbase.toolchain.1', 'name': 'No ToolChain', 'resourceTypeBasedDiscovery': 'false', 'superClass': cdt_bld + '.prefbase.toolchain'}) self.add(doc, toolChain, 'targetPlatform', {'binaryParser': 'org.eclipse.cdt.core.ELF', 'id': cdt_bld + '.prefbase.toolchain.1', 'name': ''}) waf_build = '"%s" %s'%(waf_executable, eclipse.fun) waf_clean = '"%s" clean'%(waf_executable) self.add(doc, toolChain, 'builder', {'autoBuildTarget': waf_build, 'command': executable, 'enableAutoBuild': 'false', 'cleanBuildTarget': waf_clean, 'enableIncrementalBuild': 'true', 'id': cdt_bld + '.settings.default.builder.1', 'incrementalBuildTarget': waf_build, 'managedBuildOn': 'false', 'name': 'Gnu Make Builder', 'superClass': cdt_bld + '.settings.default.builder'}) tool_index = 1; for tool_name in ("Assembly", "GNU C++", "GNU C"): tool = self.add(doc, toolChain, 'tool', {'id': cdt_bld + '.settings.holder.' + str(tool_index), 'name': tool_name, 'superClass': cdt_bld + '.settings.holder'}) if cpppath or workspace_includes: incpaths = cdt_bld + '.settings.holder.incpaths' option = self.add(doc, tool, 'option', {'id': incpaths + '.' + str(tool_index), 'name': 'Include Paths', 'superClass': incpaths, 'valueType': 'includePath'}) for i in workspace_includes: self.add(doc, option, 'listOptionValue', {'builtIn': 'false', 'value': '"${workspace_loc:/%s/%s}"'%(appname, i)}) for i in cpppath: self.add(doc, option, 'listOptionValue', {'builtIn': 'false', 'value': '"%s"'%(i)}) if tool_name == "GNU C++" or tool_name == "GNU C": self.add(doc,tool,'inputType',{ 'id':'org.eclipse.cdt.build.core.settings.holder.inType.' + str(tool_index), \ 'languageId':'org.eclipse.cdt.core.gcc' if tool_name == "GNU C" else 'org.eclipse.cdt.core.g++','languageName':tool_name, \ 'sourceContentType':'org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader', \ 'superClass':'org.eclipse.cdt.build.core.settings.holder.inType' }) tool_index += 1 if source_dirs: sourceEntries = self.add(doc, config, 'sourceEntries') for i in source_dirs: self.add(doc, sourceEntries, 'entry', {'excluding': i, 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', 'kind': 'sourcePath', 'name': ''}) self.add(doc, sourceEntries, 'entry', { 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', 'kind': 'sourcePath', 'name': i}) storageModule = self.add(doc, cconf, 'storageModule', {'moduleId': cdt_mk + '.buildtargets'}) buildTargets = self.add(doc, storageModule, 'buildTargets') def addTargetWrap(name, runAll): return self.addTarget(doc, buildTargets, executable, name, '"%s" %s'%(waf_executable, name), runAll) addTargetWrap('configure', True) addTargetWrap('dist', False) addTargetWrap('install', False) addTargetWrap('check', False) storageModule = self.add(doc, cproject, 'storageModule', {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'}) self.add(doc, storageModule, 'project', {'id': '%s.null.1'%appname, 'name': appname}) doc.appendChild(cproject) return doc def impl_create_pydevproject(self, system_path, user_path): # create a pydevproject file doc = Document() doc.appendChild(doc.createProcessingInstruction('eclipse-pydev', 'version="1.0"')) pydevproject = doc.createElement('pydev_project') prop = self.add(doc, pydevproject, 'pydev_property', 'python %d.%d'%(sys.version_info[0], sys.version_info[1])) prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_VERSION') prop = self.add(doc, pydevproject, 'pydev_property', 'Default') prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_INTERPRETER') # add waf's paths wafadmin = [p for p in system_path if p.find('wafadmin') != -1] if wafadmin: prop = self.add(doc, pydevproject, 'pydev_pathproperty', {'name':'org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH'}) for i in wafadmin: self.add(doc, prop, 'path', i) if user_path: prop = self.add(doc, pydevproject, 'pydev_pathproperty', {'name':'org.python.pydev.PROJECT_SOURCE_PATH'}) for i in user_path: self.add(doc, prop, 'path', '/${PROJECT_DIR_NAME}/'+i) doc.appendChild(pydevproject) return doc def impl_create_javaproject(self, javasrcpath, javalibpath): # create a .classpath file for java usage doc = Document() javaproject = doc.createElement('classpath') if javasrcpath: for i in javasrcpath: self.add(doc, javaproject, 'classpathentry', {'kind': 'src', 'path': i}) if javalibpath: for i in javalibpath: self.add(doc, javaproject, 'classpathentry', {'kind': 'lib', 'path': i}) self.add(doc, javaproject, 'classpathentry', {'kind': 'con', 'path': 'org.eclipse.jdt.launching.JRE_CONTAINER'}) self.add(doc, javaproject, 'classpathentry', {'kind': 'output', 'path': self.bldnode.name }) doc.appendChild(javaproject) return doc def addDictionary(self, doc, parent, k, v): dictionary = self.add(doc, parent, 'dictionary') self.add(doc, dictionary, 'key', k) self.add(doc, dictionary, 'value', v) return dictionary def addTarget(self, doc, buildTargets, executable, name, buildTarget, runAllBuilders=True): target = self.add(doc, buildTargets, 'target', {'name': name, 'path': '', 'targetID': oe_cdt + '.build.MakeTargetBuilder'}) self.add(doc, target, 'buildCommand', executable) self.add(doc, target, 'buildArguments', None) self.add(doc, target, 'buildTarget', buildTarget) self.add(doc, target, 'stopOnError', 'true') self.add(doc, target, 'useDefaultCommand', 'false') self.add(doc, target, 'runAllBuilders', str(runAllBuilders).lower()) def add(self, doc, parent, tag, value = None): el = doc.createElement(tag) if (value): if type(value) == type(str()): el.appendChild(doc.createTextNode(value)) elif type(value) == type(dict()): self.setAttributes(el, value) parent.appendChild(el) return el def setAttributes(self, node, attrs): for k, v in attrs.items(): node.setAttribute(k, v) ldb-2.0.8/third_party/waf/waflib/extras/erlang.py0000660000000000000000000000667313573675414021753 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010 (ita) # Przemyslaw Rzepecki, 2016 """ Erlang support """ import re from waflib import Task, TaskGen from waflib.TaskGen import feature, after_method, before_method # to load the method "to_incnodes" below from waflib.Tools import ccroot # Those flags are required by the Erlang VM to execute/evaluate code in # non-interactive mode. It is used in this tool to create Erlang modules # documentation and run unit tests. The user can pass additional arguments to the # 'erl' command with ERL_FLAGS environment variable. EXEC_NON_INTERACTIVE = ['-noshell', '-noinput', '-eval'] def configure(conf): conf.find_program('erlc', var='ERLC') conf.find_program('erl', var='ERL') conf.add_os_flags('ERLC_FLAGS') conf.add_os_flags('ERL_FLAGS') conf.env.ERLC_DEF_PATTERN = '-D%s' conf.env.ERLC_INC_PATTERN = '-I%s' @TaskGen.extension('.erl') def process_erl_node(self, node): tsk = self.create_task('erl', node, node.change_ext('.beam')) tsk.erlc_incnodes = [tsk.outputs[0].parent] + self.to_incnodes(self.includes) tsk.env.append_value('ERLC_INCPATHS', [x.abspath() for x in tsk.erlc_incnodes]) tsk.env.append_value('ERLC_DEFINES', self.to_list(getattr(self, 'defines', []))) tsk.env.append_value('ERLC_FLAGS', self.to_list(getattr(self, 'flags', []))) tsk.cwd = tsk.outputs[0].parent class erl(Task.Task): color = 'GREEN' run_str = '${ERLC} ${ERL_FLAGS} ${ERLC_INC_PATTERN:ERLC_INCPATHS} ${ERLC_DEF_PATTERN:ERLC_DEFINES} ${SRC}' def scan(task): node = task.inputs[0] deps = [] scanned = set([]) nodes_to_scan = [node] for n in nodes_to_scan: if n.abspath() in scanned: continue for i in re.findall(r'-include\("(.*)"\)\.', n.read()): for d in task.erlc_incnodes: r = d.find_node(i) if r: deps.append(r) nodes_to_scan.append(r) break scanned.add(n.abspath()) return (deps, []) @TaskGen.extension('.beam') def process(self, node): pass class erl_test(Task.Task): color = 'BLUE' run_str = '${ERL} ${ERL_FLAGS} ${ERL_TEST_FLAGS}' @feature('eunit') @after_method('process_source') def add_erl_test_run(self): test_modules = [t.outputs[0] for t in self.tasks] test_task = self.create_task('erl_test') test_task.set_inputs(self.source + test_modules) test_task.cwd = test_modules[0].parent test_task.env.append_value('ERL_FLAGS', self.to_list(getattr(self, 'flags', []))) test_list = ", ".join([m.change_ext("").path_from(test_task.cwd)+":test()" for m in test_modules]) test_flag = 'halt(case lists:all(fun(Elem) -> Elem == ok end, [%s]) of true -> 0; false -> 1 end).' % test_list test_task.env.append_value('ERL_TEST_FLAGS', EXEC_NON_INTERACTIVE) test_task.env.append_value('ERL_TEST_FLAGS', test_flag) class edoc(Task.Task): color = 'BLUE' run_str = "${ERL} ${ERL_FLAGS} ${ERL_DOC_FLAGS}" def keyword(self): return 'Generating edoc' @feature('edoc') @before_method('process_source') def add_edoc_task(self): # do not process source, it would create double erl->beam task self.meths.remove('process_source') e = self.path.find_resource(self.source) t = e.change_ext('.html') png = t.parent.make_node('erlang.png') css = t.parent.make_node('stylesheet.css') tsk = self.create_task('edoc', e, [t, png, css]) tsk.cwd = tsk.outputs[0].parent tsk.env.append_value('ERL_DOC_FLAGS', EXEC_NON_INTERACTIVE) tsk.env.append_value('ERL_DOC_FLAGS', 'edoc:files(["%s"]), halt(0).' % tsk.inputs[0].abspath()) # TODO the above can break if a file path contains '"' ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py0000660000000000000000000003622713573675414023152 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2017-2018 (ita) """ A system for fast partial rebuilds Creating a large amount of task objects up front can take some time. By making a few assumptions, it is possible to avoid posting creating task objects for targets that are already up-to-date. On a silly benchmark the gain observed for 1M tasks can be 5m->10s for a single file change. Usage:: def options(opt): opt.load('fast_partial') Assumptions: * Start with a clean build (run "waf distclean" after enabling) * Mostly for C/C++/Fortran targets with link tasks (object-only targets are not handled) try it in the folder generated by utils/genbench.py * For full project builds: no --targets and no pruning from subfolders * The installation phase is ignored * `use=` dependencies are specified up front even across build groups * Task generator source files are not obtained from globs Implementation details: * The first layer obtains file timestamps to recalculate file hashes only when necessary (similar to md5_tstamp); the timestamps are then stored in a dedicated pickle file * A second layer associates each task generator to a file set to help detecting changes. Task generators are to create their tasks only when the related files have been modified. A specific db file is created to store such data (5m -> 1m10) * A third layer binds build context proxies onto task generators, replacing the default context. While loading data for the full build uses more memory (4GB -> 9GB), partial builds are then much faster (1m10 -> 13s) * A fourth layer enables a 2-level cache on file signatures to reduce the size of the main pickle file (13s -> 10s) """ import os from waflib import Build, Context, Errors, Logs, Task, TaskGen, Utils from waflib.TaskGen import feature, after_method, taskgen_method import waflib.Node DONE = 0 DIRTY = 1 NEEDED = 2 SKIPPABLE = ['cshlib', 'cxxshlib', 'cstlib', 'cxxstlib', 'cprogram', 'cxxprogram'] TSTAMP_DB = '.wafpickle_tstamp_db_file' SAVED_ATTRS = 'root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() class bld_proxy(object): def __init__(self, bld): object.__setattr__(self, 'bld', bld) object.__setattr__(self, 'node_class', type('Nod3', (waflib.Node.Node,), {})) self.node_class.__module__ = 'waflib.Node' self.node_class.ctx = self object.__setattr__(self, 'root', self.node_class('', None)) for x in SAVED_ATTRS: if x != 'root': object.__setattr__(self, x, {}) self.fix_nodes() def __setattr__(self, name, value): bld = object.__getattribute__(self, 'bld') setattr(bld, name, value) def __delattr__(self, name): bld = object.__getattribute__(self, 'bld') delattr(bld, name) def __getattribute__(self, name): try: return object.__getattribute__(self, name) except AttributeError: bld = object.__getattribute__(self, 'bld') return getattr(bld, name) def __call__(self, *k, **kw): return self.bld(*k, **kw) def fix_nodes(self): for x in ('srcnode', 'path', 'bldnode'): node = self.root.find_dir(getattr(self.bld, x).abspath()) object.__setattr__(self, x, node) def set_key(self, store_key): object.__setattr__(self, 'store_key', store_key) def fix_tg_path(self, *tgs): # changing Node objects on task generators is possible # yet, all Node objects must belong to the same parent for tg in tgs: tg.path = self.root.make_node(tg.path.abspath()) def restore(self): dbfn = os.path.join(self.variant_dir, Context.DBFILE + self.store_key) Logs.debug('rev_use: reading %s', dbfn) try: data = Utils.readf(dbfn, 'rb') except (EnvironmentError, EOFError): # handle missing file/empty file Logs.debug('rev_use: Could not load the build cache %s (missing)', dbfn) else: try: waflib.Node.pickle_lock.acquire() waflib.Node.Nod3 = self.node_class try: data = Build.cPickle.loads(data) except Exception as e: Logs.debug('rev_use: Could not pickle the build cache %s: %r', dbfn, e) else: for x in SAVED_ATTRS: object.__setattr__(self, x, data.get(x, {})) finally: waflib.Node.pickle_lock.release() self.fix_nodes() def store(self): data = {} for x in Build.SAVED_ATTRS: data[x] = getattr(self, x) db = os.path.join(self.variant_dir, Context.DBFILE + self.store_key) with waflib.Node.pickle_lock: waflib.Node.Nod3 = self.node_class try: x = Build.cPickle.dumps(data, Build.PROTOCOL) except Build.cPickle.PicklingError: root = data['root'] for node_deps in data['node_deps'].values(): for idx, node in enumerate(node_deps): # there may be more cross-context Node objects to fix, # but this should be the main source node_deps[idx] = root.find_node(node.abspath()) x = Build.cPickle.dumps(data, Build.PROTOCOL) Logs.debug('rev_use: storing %s', db) Utils.writef(db + '.tmp', x, m='wb') try: st = os.stat(db) os.remove(db) if not Utils.is_win32: os.chown(db + '.tmp', st.st_uid, st.st_gid) except (AttributeError, OSError): pass os.rename(db + '.tmp', db) class bld(Build.BuildContext): def __init__(self, **kw): super(bld, self).__init__(**kw) self.hashes_md5_tstamp = {} def __call__(self, *k, **kw): # this is one way of doing it, one could use a task generator method too bld = kw['bld'] = bld_proxy(self) ret = TaskGen.task_gen(*k, **kw) self.task_gen_cache_names = {} self.add_to_group(ret, group=kw.get('group')) ret.bld = bld bld.set_key(ret.path.abspath().replace(os.sep, '') + str(ret.idx)) return ret def is_dirty(self): return True def store_tstamps(self): # Called after a build is finished # For each task generator, record all files involved in task objects # optimization: done only if there was something built do_store = False try: f_deps = self.f_deps except AttributeError: f_deps = self.f_deps = {} self.f_tstamps = {} allfiles = set() for g in self.groups: for tg in g: try: staleness = tg.staleness except AttributeError: staleness = DIRTY if staleness != DIRTY: # DONE case: there was nothing built # NEEDED case: the tg was brought in because of 'use' propagation # but nothing really changed for them, there may be incomplete # tasks (object files) and in this case it is best to let the next build # figure out if an input/output file changed continue do_cache = False for tsk in tg.tasks: if tsk.hasrun == Task.SUCCESS: do_cache = True pass elif tsk.hasrun == Task.SKIPPED: pass else: # one failed task, clear the cache for this tg try: del f_deps[(tg.path.abspath(), tg.idx)] except KeyError: pass else: # just store the new state because there is a change do_store = True # skip the rest because there is no valid cache possible break else: if not do_cache: # all skipped, but is there anything in cache? try: f_deps[(tg.path.abspath(), tg.idx)] except KeyError: # probably cleared because a wscript file changed # store it do_cache = True if do_cache: # there was a rebuild, store the data structure too tg.bld.store() # all tasks skipped but no cache # or a successful task build do_store = True st = set() for tsk in tg.tasks: st.update(tsk.inputs) st.update(self.node_deps.get(tsk.uid(), [])) # TODO do last/when loading the tgs? lst = [] for k in ('wscript', 'wscript_build'): n = tg.path.find_node(k) if n: n.get_bld_sig() lst.append(n.abspath()) lst.extend(sorted(x.abspath() for x in st)) allfiles.update(lst) f_deps[(tg.path.abspath(), tg.idx)] = lst for x in allfiles: # f_tstamps has everything, while md5_tstamp can be relatively empty on partial builds self.f_tstamps[x] = self.hashes_md5_tstamp[x][0] if do_store: dbfn = os.path.join(self.variant_dir, TSTAMP_DB) Logs.debug('rev_use: storing %s', dbfn) dbfn_tmp = dbfn + '.tmp' x = Build.cPickle.dumps([self.f_tstamps, f_deps], Build.PROTOCOL) Utils.writef(dbfn_tmp, x, m='wb') os.rename(dbfn_tmp, dbfn) Logs.debug('rev_use: stored %s', dbfn) def store(self): self.store_tstamps() if self.producer.dirty: Build.BuildContext.store(self) def compute_needed_tgs(self): # assume the 'use' keys are not modified during the build phase dbfn = os.path.join(self.variant_dir, TSTAMP_DB) Logs.debug('rev_use: Loading %s', dbfn) try: data = Utils.readf(dbfn, 'rb') except (EnvironmentError, EOFError): Logs.debug('rev_use: Could not load the build cache %s (missing)', dbfn) self.f_deps = {} self.f_tstamps = {} else: try: self.f_tstamps, self.f_deps = Build.cPickle.loads(data) except Exception as e: Logs.debug('rev_use: Could not pickle the build cache %s: %r', dbfn, e) self.f_deps = {} self.f_tstamps = {} else: Logs.debug('rev_use: Loaded %s', dbfn) # 1. obtain task generators that contain rebuilds # 2. obtain the 'use' graph and its dual stales = set() reverse_use_map = Utils.defaultdict(list) use_map = Utils.defaultdict(list) for g in self.groups: for tg in g: if tg.is_stale(): stales.add(tg) try: lst = tg.use = Utils.to_list(tg.use) except AttributeError: pass else: for x in lst: try: xtg = self.get_tgen_by_name(x) except Errors.WafError: pass else: use_map[tg].append(xtg) reverse_use_map[xtg].append(tg) Logs.debug('rev_use: found %r stale tgs', len(stales)) # 3. dfs to post downstream tg as stale visited = set() def mark_down(tg): if tg in visited: return visited.add(tg) Logs.debug('rev_use: marking down %r as stale', tg.name) tg.staleness = DIRTY for x in reverse_use_map[tg]: mark_down(x) for tg in stales: mark_down(tg) # 4. dfs to find ancestors tg to mark as needed self.needed_tgs = needed_tgs = set() def mark_needed(tg): if tg in needed_tgs: return needed_tgs.add(tg) if tg.staleness == DONE: Logs.debug('rev_use: marking up %r as needed', tg.name) tg.staleness = NEEDED for x in use_map[tg]: mark_needed(x) for xx in visited: mark_needed(xx) # so we have the whole tg trees to post in the set "needed" # load their build trees for tg in needed_tgs: tg.bld.restore() tg.bld.fix_tg_path(tg) # the stale ones should be fully build, while the needed ones # may skip a few tasks, see create_compiled_task and apply_link_after below Logs.debug('rev_use: amount of needed task gens: %r', len(needed_tgs)) def post_group(self): # assumption: we can ignore the folder/subfolders cuts def tgpost(tg): try: f = tg.post except AttributeError: pass else: f() if not self.targets or self.targets == '*': for tg in self.groups[self.current_group]: # this can cut quite a lot of tg objects if tg in self.needed_tgs: tgpost(tg) else: # default implementation return Build.BuildContext.post_group() def get_build_iterator(self): if not self.targets or self.targets == '*': self.compute_needed_tgs() return Build.BuildContext.get_build_iterator(self) @taskgen_method def is_stale(self): # assume no globs self.staleness = DIRTY # 1. the case of always stale targets if getattr(self, 'always_stale', False): return True # 2. check if the db file exists db = os.path.join(self.bld.variant_dir, Context.DBFILE) try: dbstat = os.stat(db).st_mtime except OSError: Logs.debug('rev_use: must post %r because this is a clean build') return True # 3.a check if the configuration exists cache_node = self.bld.bldnode.find_node('c4che/build.config.py') if not cache_node: return True # 3.b check if the configuration changed if os.stat(cache_node.abspath()).st_mtime > dbstat: Logs.debug('rev_use: must post %r because the configuration has changed', self.name) return True # 3.c any tstamp data? try: f_deps = self.bld.f_deps except AttributeError: Logs.debug('rev_use: must post %r because there is no f_deps', self.name) return True # 4. check if this is the first build (no cache) try: lst = f_deps[(self.path.abspath(), self.idx)] except KeyError: Logs.debug('rev_use: must post %r because there it has no cached data', self.name) return True try: cache = self.bld.cache_tstamp_rev_use except AttributeError: cache = self.bld.cache_tstamp_rev_use = {} # 5. check the timestamp of each dependency files listed is unchanged f_tstamps = self.bld.f_tstamps for x in lst: try: old_ts = f_tstamps[x] except KeyError: Logs.debug('rev_use: must post %r because %r is not in cache', self.name, x) return True try: try: ts = cache[x] except KeyError: ts = cache[x] = os.stat(x).st_mtime except OSError: del f_deps[(self.path.abspath(), self.idx)] Logs.debug('rev_use: must post %r because %r does not exist anymore', self.name, x) return True else: if ts != old_ts: Logs.debug('rev_use: must post %r because the timestamp on %r changed %r %r', self.name, x, old_ts, ts) return True self.staleness = DONE return False @taskgen_method def create_compiled_task(self, name, node): # skip the creation of object files # assumption: object-only targets are not skippable if self.staleness == NEEDED: # only libraries/programs can skip object files for x in SKIPPABLE: if x in self.features: return None out = '%s.%d.o' % (node.name, self.idx) task = self.create_task(name, node, node.parent.find_or_declare(out)) try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] return task @feature(*SKIPPABLE) @after_method('apply_link') def apply_link_after(self): # cprogram/cxxprogram might be unnecessary if self.staleness != NEEDED: return for tsk in self.tasks: tsk.hasrun = Task.SKIPPED def path_from(self, node): # handle nodes of distinct types if node.ctx is not self.ctx: node = self.ctx.root.make_node(node.abspath()) return self.default_path_from(node) waflib.Node.Node.default_path_from = waflib.Node.Node.path_from waflib.Node.Node.path_from = path_from def h_file(self): # similar to md5_tstamp.py, but with 2-layer cache # global_cache for the build context common for all task generators # local_cache for the build context proxy (one by task generator) # # the global cache is not persistent # the local cache is persistent and meant for partial builds # # assume all calls are made from a single thread # filename = self.abspath() st = os.stat(filename) global_cache = self.ctx.bld.hashes_md5_tstamp local_cache = self.ctx.hashes_md5_tstamp if filename in global_cache: # value already calculated in this build cval = global_cache[filename] # the value in global cache is assumed to be calculated once # reverifying it could cause task generators # to get distinct tstamp values, thus missing rebuilds local_cache[filename] = cval return cval[1] if filename in local_cache: cval = local_cache[filename] if cval[0] == st.st_mtime: # correct value from a previous build # put it in the global cache global_cache[filename] = cval return cval[1] ret = Utils.h_file(filename) local_cache[filename] = global_cache[filename] = (st.st_mtime, ret) return ret waflib.Node.Node.h_file = h_file ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py0000660000000000000000000000132613573675414022243 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de from waflib.Tools import fc, fc_config, fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].insert(0, 'fc_bgxlf') @conf def find_bgxlf(conf): fc = conf.find_program(['bgxlf2003_r','bgxlf2003'], var='FC') conf.get_xlf_version(fc) conf.env.FC_NAME = 'BGXLF' @conf def bg_flags(self): self.env.SONAME_ST = '' self.env.FCSHLIB_MARKER = '' self.env.FCSTLIB_MARKER = '' self.env.FCFLAGS_fcshlib = ['-fPIC'] self.env.LINKFLAGS_fcshlib = ['-G', '-Wl,-bexpfull'] def configure(conf): conf.find_bgxlf() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.xlf_flags() conf.bg_flags() ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py0000660000000000000000000000264613573675414022105 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de import re from waflib.Tools import fc, fc_config, fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].append('fc_cray') @conf def find_crayftn(conf): """Find the Cray fortran compiler (will look in the environment variable 'FC')""" fc = conf.find_program(['crayftn'], var='FC') conf.get_crayftn_version(fc) conf.env.FC_NAME = 'CRAY' conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod' @conf def crayftn_flags(conf): v = conf.env v['_FCMODOUTFLAGS'] = ['-em', '-J.'] # enable module files and put them in the current directory v['FCFLAGS_DEBUG'] = ['-m1'] # more verbose compiler warnings v['FCFLAGS_fcshlib'] = ['-h pic'] v['LINKFLAGS_fcshlib'] = ['-h shared'] v['FCSTLIB_MARKER'] = '-h static' v['FCSHLIB_MARKER'] = '-h dynamic' @conf def get_crayftn_version(conf, fc): version_re = re.compile(r"Cray Fortran\s*:\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search cmd = fc + ['-V'] out,err = fc_config.getoutput(conf, cmd, stdin=False) if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not determine the Cray Fortran compiler version.') k = match.groupdict() conf.env['FC_VERSION'] = (k['major'], k['minor']) def configure(conf): conf.find_crayftn() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.crayftn_flags() ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py0000660000000000000000000000276013573675414021711 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de import re from waflib import Utils from waflib.Tools import fc,fc_config,fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].insert(0, 'fc_nag') @conf def find_nag(conf): """Find the NAG Fortran Compiler (will look in the environment variable 'FC')""" fc = conf.find_program(['nagfor'], var='FC') conf.get_nag_version(fc) conf.env.FC_NAME = 'NAG' conf.env.FC_MOD_CAPITALIZATION = 'lower' @conf def nag_flags(conf): v = conf.env v.FCFLAGS_DEBUG = ['-C=all'] v.FCLNK_TGT_F = ['-o', ''] v.FC_TGT_F = ['-c', '-o', ''] @conf def nag_modifier_platform(conf): dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() nag_modifier_func = getattr(conf, 'nag_modifier_' + dest_os, None) if nag_modifier_func: nag_modifier_func() @conf def get_nag_version(conf, fc): """Get the NAG compiler version""" version_re = re.compile(r"^NAG Fortran Compiler *Release *(?P\d*)\.(?P\d*)", re.M).search cmd = fc + ['-V'] out, err = fc_config.getoutput(conf,cmd,stdin=False) if out: match = version_re(out) if not match: match = version_re(err) else: match = version_re(err) if not match: conf.fatal('Could not determine the NAG version.') k = match.groupdict() conf.env['FC_VERSION'] = (k['major'], k['minor']) def configure(conf): conf.find_nag() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.nag_flags() conf.nag_modifier_platform() ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py0000660000000000000000000000317313573675414021710 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de import re from waflib.Tools import fc, fc_config, fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].append('fc_nec') @conf def find_sxfc(conf): """Find the NEC fortran compiler (will look in the environment variable 'FC')""" fc = conf.find_program(['sxf90','sxf03'], var='FC') conf.get_sxfc_version(fc) conf.env.FC_NAME = 'NEC' conf.env.FC_MOD_CAPITALIZATION = 'lower' @conf def sxfc_flags(conf): v = conf.env v['_FCMODOUTFLAGS'] = [] # enable module files and put them in the current directory v['FCFLAGS_DEBUG'] = [] # more verbose compiler warnings v['FCFLAGS_fcshlib'] = [] v['LINKFLAGS_fcshlib'] = [] v['FCSTLIB_MARKER'] = '' v['FCSHLIB_MARKER'] = '' @conf def get_sxfc_version(conf, fc): version_re = re.compile(r"FORTRAN90/SX\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search cmd = fc + ['-V'] out,err = fc_config.getoutput(conf, cmd, stdin=False) if out: match = version_re(out) else: match = version_re(err) if not match: version_re=re.compile(r"NEC Fortran 2003 Compiler for\s*(?P\S*)\s*\(c\)\s*(?P\d*)",re.I).search if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not determine the NEC Fortran compiler version.') k = match.groupdict() conf.env['FC_VERSION'] = (k['major'], k['minor']) def configure(conf): conf.find_sxfc() conf.find_program('sxar',var='AR') conf.add_os_flags('ARFLAGS') if not conf.env.ARFLAGS: conf.env.ARFLAGS=['rcs'] conf.fc_flags() conf.fc_add_flags() conf.sxfc_flags() ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py0000660000000000000000000000243013573675414022266 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Detection of the NEC Fortran compiler for Aurora Tsubasa import re from waflib.Tools import fc,fc_config,fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].append('fc_nfort') @conf def find_nfort(conf): fc=conf.find_program(['nfort'],var='FC') conf.get_nfort_version(fc) conf.env.FC_NAME='NFORT' conf.env.FC_MOD_CAPITALIZATION='lower' @conf def nfort_flags(conf): v=conf.env v['_FCMODOUTFLAGS']=[] v['FCFLAGS_DEBUG']=[] v['FCFLAGS_fcshlib']=[] v['LINKFLAGS_fcshlib']=[] v['FCSTLIB_MARKER']='' v['FCSHLIB_MARKER']='' @conf def get_nfort_version(conf,fc): version_re=re.compile(r"nfort\s*\(NFORT\)\s*(?P\d+)\.(?P\d+)\.",re.I).search cmd=fc+['--version'] out,err=fc_config.getoutput(conf,cmd,stdin=False) if out: match=version_re(out) else: match=version_re(err) if not match: return(False) conf.fatal('Could not determine the NEC NFORT Fortran compiler version.') else: k=match.groupdict() conf.env['FC_VERSION']=(k['major'],k['minor']) def configure(conf): conf.find_nfort() conf.find_program('nar',var='AR') conf.add_os_flags('ARFLAGS') if not conf.env.ARFLAGS: conf.env.ARFLAGS=['rcs'] conf.fc_flags() conf.fc_add_flags() conf.nfort_flags() ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py0000660000000000000000000000274613573675414022263 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de import re from waflib import Utils from waflib.Tools import fc,fc_config,fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].insert(0, 'fc_open64') @conf def find_openf95(conf): """Find the Open64 Fortran Compiler (will look in the environment variable 'FC')""" fc = conf.find_program(['openf95', 'openf90'], var='FC') conf.get_open64_version(fc) conf.env.FC_NAME = 'OPEN64' conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod' @conf def openf95_flags(conf): v = conf.env v['FCFLAGS_DEBUG'] = ['-fullwarn'] @conf def openf95_modifier_platform(conf): dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() openf95_modifier_func = getattr(conf, 'openf95_modifier_' + dest_os, None) if openf95_modifier_func: openf95_modifier_func() @conf def get_open64_version(conf, fc): """Get the Open64 compiler version""" version_re = re.compile(r"Open64 Compiler Suite: *Version *(?P\d*)\.(?P\d*)", re.I).search cmd = fc + ['-version'] out, err = fc_config.getoutput(conf,cmd,stdin=False) if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not determine the Open64 version.') k = match.groupdict() conf.env['FC_VERSION'] = (k['major'], k['minor']) def configure(conf): conf.find_openf95() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.openf95_flags() conf.openf95_modifier_platform() ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py0000660000000000000000000000336413573675414023147 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de import re from waflib.Tools import fc, fc_config, fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].append('fc_pgfortran') @conf def find_pgfortran(conf): """Find the PGI fortran compiler (will look in the environment variable 'FC')""" fc = conf.find_program(['pgfortran', 'pgf95', 'pgf90'], var='FC') conf.get_pgfortran_version(fc) conf.env.FC_NAME = 'PGFC' @conf def pgfortran_flags(conf): v = conf.env v['FCFLAGS_fcshlib'] = ['-shared'] v['FCFLAGS_DEBUG'] = ['-Minform=inform', '-Mstandard'] # why not v['FCSTLIB_MARKER'] = '-Bstatic' v['FCSHLIB_MARKER'] = '-Bdynamic' v['SONAME_ST'] = '-soname %s' @conf def get_pgfortran_version(conf,fc): version_re = re.compile(r"The Portland Group", re.I).search cmd = fc + ['-V'] out,err = fc_config.getoutput(conf, cmd, stdin=False) if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not verify PGI signature') cmd = fc + ['-help=variable'] out,err = fc_config.getoutput(conf, cmd, stdin=False) if out.find('COMPVER')<0: conf.fatal('Could not determine the compiler type') k = {} prevk = '' out = out.splitlines() for line in out: lst = line.partition('=') if lst[1] == '=': key = lst[0].rstrip() if key == '': key = prevk val = lst[2].rstrip() k[key] = val else: prevk = line.partition(' ')[0] def isD(var): return var in k def isT(var): return var in k and k[var]!='0' conf.env['FC_VERSION'] = (k['COMPVER'].split('.')) def configure(conf): conf.find_pgfortran() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.pgfortran_flags() ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py0000660000000000000000000000315213573675414023165 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de import re from waflib import Utils from waflib.Tools import fc,fc_config,fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['linux'].append('fc_solstudio') @conf def find_solstudio(conf): """Find the Solaris Studio compiler (will look in the environment variable 'FC')""" fc = conf.find_program(['sunf95', 'f95', 'sunf90', 'f90'], var='FC') conf.get_solstudio_version(fc) conf.env.FC_NAME = 'SOL' @conf def solstudio_flags(conf): v = conf.env v['FCFLAGS_fcshlib'] = ['-Kpic'] v['FCFLAGS_DEBUG'] = ['-w3'] v['LINKFLAGS_fcshlib'] = ['-G'] v['FCSTLIB_MARKER'] = '-Bstatic' v['FCSHLIB_MARKER'] = '-Bdynamic' v['SONAME_ST'] = '-h %s' @conf def solstudio_modifier_platform(conf): dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() solstudio_modifier_func = getattr(conf, 'solstudio_modifier_' + dest_os, None) if solstudio_modifier_func: solstudio_modifier_func() @conf def get_solstudio_version(conf, fc): """Get the compiler version""" version_re = re.compile(r"Sun Fortran 95 *(?P\d*)\.(?P\d*)", re.I).search cmd = fc + ['-V'] out, err = fc_config.getoutput(conf,cmd,stdin=False) if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not determine the Sun Studio Fortran version.') k = match.groupdict() conf.env['FC_VERSION'] = (k['major'], k['minor']) def configure(conf): conf.find_solstudio() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.solstudio_flags() conf.solstudio_modifier_platform() ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py0000660000000000000000000000311713573675414021732 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de import re from waflib import Utils,Errors from waflib.Tools import fc,fc_config,fc_scan from waflib.Configure import conf from waflib.Tools.compiler_fc import fc_compiler fc_compiler['aix'].insert(0, 'fc_xlf') @conf def find_xlf(conf): """Find the xlf program (will look in the environment variable 'FC')""" fc = conf.find_program(['xlf2003_r', 'xlf2003', 'xlf95_r', 'xlf95', 'xlf90_r', 'xlf90', 'xlf_r', 'xlf'], var='FC') conf.get_xlf_version(fc) conf.env.FC_NAME='XLF' @conf def xlf_flags(conf): v = conf.env v['FCDEFINES_ST'] = '-WF,-D%s' v['FCFLAGS_fcshlib'] = ['-qpic=small'] v['FCFLAGS_DEBUG'] = ['-qhalt=w'] v['LINKFLAGS_fcshlib'] = ['-Wl,-shared'] @conf def xlf_modifier_platform(conf): dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() xlf_modifier_func = getattr(conf, 'xlf_modifier_' + dest_os, None) if xlf_modifier_func: xlf_modifier_func() @conf def get_xlf_version(conf, fc): """Get the compiler version""" cmd = fc + ['-qversion'] try: out, err = conf.cmd_and_log(cmd, output=0) except Errors.WafError: conf.fatal('Could not find xlf %r' % cmd) for v in (r"IBM XL Fortran.* V(?P\d*)\.(?P\d*)",): version_re = re.compile(v, re.I).search match = version_re(out or err) if match: k = match.groupdict() conf.env['FC_VERSION'] = (k['major'], k['minor']) break else: conf.fatal('Could not determine the XLF version.') def configure(conf): conf.find_xlf() conf.find_ar() conf.fc_flags() conf.fc_add_flags() conf.xlf_flags() conf.xlf_modifier_platform() ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py0000660000000000000000000000646513573675414023451 0ustar rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Tool to embed file into objects __author__ = __maintainer__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2014" """ This tool allows to embed file contents in object files (.o). It is not exactly portable, and the file contents are reachable using various non-portable fashions. The goal here is to provide a functional interface to the embedding of file data in objects. See the ``playground/embedded_resources`` example for an example. Usage:: bld( name='pipeline', # ^ Reference this in use="..." for things using the generated code features='file_to_object', source='some.file', # ^ Name of the file to embed in binary section. ) Known issues: - Destination is named like source, with extension renamed to .o eg. some.file -> some.o """ import os from waflib import Task, TaskGen, Errors def filename_c_escape(x): return x.replace("\\", "\\\\") class file_to_object_s(Task.Task): color = 'CYAN' vars = ['DEST_CPU', 'DEST_BINFMT'] def run(self): name = [] for i, x in enumerate(self.inputs[0].name): if x.isalnum(): name.append(x) else: name.append('_') file = self.inputs[0].abspath() size = os.path.getsize(file) if self.env.DEST_CPU in ('x86_64', 'ia', 'aarch64'): unit = 'quad' align = 8 elif self.env.DEST_CPU in ('x86','arm', 'thumb', 'm68k'): unit = 'long' align = 4 else: raise Errors.WafError("Unsupported DEST_CPU, please report bug!") file = filename_c_escape(file) name = "_binary_" + "".join(name) rodata = ".section .rodata" if self.env.DEST_BINFMT == "mac-o": name = "_" + name rodata = ".section __TEXT,__const" with open(self.outputs[0].abspath(), 'w') as f: f.write(\ """ .global %(name)s_start .global %(name)s_end .global %(name)s_size %(rodata)s %(name)s_start: .incbin "%(file)s" %(name)s_end: .align %(align)d %(name)s_size: .%(unit)s 0x%(size)x """ % locals()) class file_to_object_c(Task.Task): color = 'CYAN' def run(self): name = [] for i, x in enumerate(self.inputs[0].name): if x.isalnum(): name.append(x) else: name.append('_') file = self.inputs[0].abspath() size = os.path.getsize(file) name = "_binary_" + "".join(name) data = self.inputs[0].read('rb') lines, line = [], [] for idx_byte, byte in enumerate(data): line.append(byte) if len(line) > 15 or idx_byte == size-1: lines.append(", ".join(("0x%02x" % ord(x)) for x in line)) line = [] data = ",\n ".join(lines) self.outputs[0].write(\ """ unsigned long %(name)s_size = %(size)dL; char const %(name)s_start[] = { %(data)s }; char const %(name)s_end[] = {}; """ % locals()) @TaskGen.feature('file_to_object') @TaskGen.before_method('process_source') def tg_file_to_object(self): bld = self.bld sources = self.to_nodes(self.source) targets = [] for src in sources: if bld.env.F2O_METHOD == ["asm"]: tgt = src.parent.find_or_declare(src.name + '.f2o.s') tsk = self.create_task('file_to_object_s', src, tgt) tsk.cwd = src.parent.abspath() # verify else: tgt = src.parent.find_or_declare(src.name + '.f2o.c') tsk = self.create_task('file_to_object_c', src, tgt) tsk.cwd = src.parent.abspath() # verify targets.append(tgt) self.source = targets def configure(conf): conf.load('gas') conf.env.F2O_METHOD = ["c"] ldb-2.0.8/third_party/waf/waflib/extras/fluid.py0000660000000000000000000000153613573675414021577 0ustar rootroot00000000000000#!/usr/bin/python # encoding: utf-8 # Grygoriy Fuchedzhy 2009 """ Compile fluid files (fltk graphic library). Use the 'fluid' feature in conjunction with the 'cxx' feature. """ from waflib import Task from waflib.TaskGen import extension class fluid(Task.Task): color = 'BLUE' ext_out = ['.h'] run_str = '${FLUID} -c -o ${TGT[0].abspath()} -h ${TGT[1].abspath()} ${SRC}' @extension('.fl') def process_fluid(self, node): """add the .fl to the source list; the cxx file generated will be compiled when possible""" cpp = node.change_ext('.cpp') hpp = node.change_ext('.hpp') self.create_task('fluid', node, [cpp, hpp]) if 'cxx' in self.features: self.source.append(cpp) def configure(conf): conf.find_program('fluid', var='FLUID') conf.check_cfg(path='fltk-config', package='', args='--cxxflags --ldflags', uselib_store='FLTK', mandatory=True) ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py0000660000000000000000000000410513573675414022413 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # # written by Sylvain Rouquette, 2011 ''' To add the freeimage tool to the waf file: $ ./waf-light --tools=compat15,freeimage or, if you have waf >= 1.6.2 $ ./waf update --files=freeimage The wscript will look like: def options(opt): opt.load('compiler_cxx freeimage') def configure(conf): conf.load('compiler_cxx freeimage') # you can call check_freeimage with some parameters. # It's optional on Linux, it's 'mandatory' on Windows if # you didn't use --fi-path on the command-line # conf.check_freeimage(path='FreeImage/Dist', fip=True) def build(bld): bld(source='main.cpp', target='app', use='FREEIMAGE') ''' from waflib import Utils from waflib.Configure import conf def options(opt): opt.add_option('--fi-path', type='string', default='', dest='fi_path', help='''path to the FreeImage directory \ where the files are e.g. /FreeImage/Dist''') opt.add_option('--fip', action='store_true', default=False, dest='fip', help='link with FreeImagePlus') opt.add_option('--fi-static', action='store_true', default=False, dest='fi_static', help="link as shared libraries") @conf def check_freeimage(self, path=None, fip=False): self.start_msg('Checking FreeImage') if not self.env['CXX']: self.fatal('you must load compiler_cxx before loading freeimage') prefix = self.options.fi_static and 'ST' or '' platform = Utils.unversioned_sys_platform() if platform == 'win32': if not path: self.fatal('you must specify the path to FreeImage. \ use --fi-path=/FreeImage/Dist') else: self.env['INCLUDES_FREEIMAGE'] = path self.env['%sLIBPATH_FREEIMAGE' % prefix] = path libs = ['FreeImage'] if self.options.fip: libs.append('FreeImagePlus') if platform == 'win32': self.env['%sLIB_FREEIMAGE' % prefix] = libs else: self.env['%sLIB_FREEIMAGE' % prefix] = [i.lower() for i in libs] self.end_msg('ok') def configure(conf): platform = Utils.unversioned_sys_platform() if platform == 'win32' and not conf.options.fi_path: return conf.check_freeimage(conf.options.fi_path, conf.options.fip) ldb-2.0.8/third_party/waf/waflib/extras/fsb.py0000660000000000000000000000107413573675414021243 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 (ita) """ Fully sequential builds The previous tasks from task generators are re-processed, and this may lead to speed issues Yet, if you are using this, speed is probably a minor concern """ from waflib import Build def options(opt): pass def configure(conf): pass class FSBContext(Build.BuildContext): def __call__(self, *k, **kw): ret = Build.BuildContext.__call__(self, *k, **kw) # evaluate the results immediately Build.BuildContext.compile(self) return ret def compile(self): pass ldb-2.0.8/third_party/waf/waflib/extras/fsc.py0000660000000000000000000000356513573675414021253 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 (ita) """ Experimental F# stuff FSC="mono /path/to/fsc.exe" waf configure build """ from waflib import Utils, Task from waflib.TaskGen import before_method, after_method, feature from waflib.Tools import ccroot, cs ccroot.USELIB_VARS['fsc'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES']) @feature('fs') @before_method('process_source') def apply_fsc(self): cs_nodes = [] no_nodes = [] for x in self.to_nodes(self.source): if x.name.endswith('.fs'): cs_nodes.append(x) else: no_nodes.append(x) self.source = no_nodes bintype = getattr(self, 'type', self.gen.endswith('.dll') and 'library' or 'exe') self.cs_task = tsk = self.create_task('fsc', cs_nodes, self.path.find_or_declare(self.gen)) tsk.env.CSTYPE = '/target:%s' % bintype tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath() inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}') if inst_to: # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644) self.install_task = self.add_install_files(install_to=inst_to, install_from=self.cs_task.outputs[:], chmod=mod) feature('fs')(cs.use_cs) after_method('apply_fsc')(cs.use_cs) feature('fs')(cs.debug_cs) after_method('apply_fsc', 'use_cs')(cs.debug_cs) class fsc(Task.Task): """ Compile F# files """ color = 'YELLOW' run_str = '${FSC} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' def configure(conf): """ Find a F# compiler, set the variable FSC for the compiler and FS_NAME (mono or fsc) """ conf.find_program(['fsc.exe', 'fsharpc'], var='FSC') conf.env.ASS_ST = '/r:%s' conf.env.RES_ST = '/resource:%s' conf.env.FS_NAME = 'fsc' if str(conf.env.FSC).lower().find('fsharpc') > -1: conf.env.FS_NAME = 'mono' ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py0000660000000000000000000001410013573675414022073 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2008-2010 (ita) """ Execute the tasks with gcc -MD, read the dependencies from the .d file and prepare the dependency calculation for the next run. This affects the cxx class, so make sure to load Qt5 after this tool. Usage:: def options(opt): opt.load('compiler_cxx') def configure(conf): conf.load('compiler_cxx gccdeps') """ import os, re, threading from waflib import Task, Logs, Utils, Errors from waflib.Tools import c_preproc from waflib.TaskGen import before_method, feature lock = threading.Lock() gccdeps_flags = ['-MD'] if not c_preproc.go_absolute: gccdeps_flags = ['-MMD'] # Third-party tools are allowed to add extra names in here with append() supported_compilers = ['gcc', 'icc', 'clang'] def scan(self): if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: return super(self.derived_gccdeps, self).scan() nodes = self.generator.bld.node_deps.get(self.uid(), []) names = [] return (nodes, names) re_o = re.compile(r"\.o$") re_splitter = re.compile(r'(?= 0: return line[sep_idx + 2:] else: return line def path_to_node(base_node, path, cached_nodes): # Take the base node and the path and return a node # Results are cached because searching the node tree is expensive # The following code is executed by threads, it is not safe, so a lock is needed... if getattr(path, '__hash__'): node_lookup_key = (base_node, path) else: # Not hashable, assume it is a list and join into a string node_lookup_key = (base_node, os.path.sep.join(path)) try: lock.acquire() node = cached_nodes[node_lookup_key] except KeyError: node = base_node.find_resource(path) cached_nodes[node_lookup_key] = node finally: lock.release() return node def post_run(self): if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: return super(self.derived_gccdeps, self).post_run() name = self.outputs[0].abspath() name = re_o.sub('.d', name) try: txt = Utils.readf(name) except EnvironmentError: Logs.error('Could not find a .d dependency file, are cflags/cxxflags overwritten?') raise #os.remove(name) # Compilers have the choice to either output the file's dependencies # as one large Makefile rule: # # /path/to/file.o: /path/to/dep1.h \ # /path/to/dep2.h \ # /path/to/dep3.h \ # ... # # or as many individual rules: # # /path/to/file.o: /path/to/dep1.h # /path/to/file.o: /path/to/dep2.h # /path/to/file.o: /path/to/dep3.h # ... # # So the first step is to sanitize the input by stripping out the left- # hand side of all these lines. After that, whatever remains are the # implicit dependencies of task.outputs[0] txt = '\n'.join([remove_makefile_rule_lhs(line) for line in txt.splitlines()]) # Now join all the lines together txt = txt.replace('\\\n', '') val = txt.strip() val = [x.replace('\\ ', ' ') for x in re_splitter.split(val) if x] nodes = [] bld = self.generator.bld # Dynamically bind to the cache try: cached_nodes = bld.cached_nodes except AttributeError: cached_nodes = bld.cached_nodes = {} for x in val: node = None if os.path.isabs(x): node = path_to_node(bld.root, x, cached_nodes) else: # TODO waf 1.9 - single cwd value path = getattr(bld, 'cwdx', bld.bldnode) # when calling find_resource, make sure the path does not contain '..' x = [k for k in Utils.split_path(x) if k and k != '.'] while '..' in x: idx = x.index('..') if idx == 0: x = x[1:] path = path.parent else: del x[idx] del x[idx-1] node = path_to_node(path, x, cached_nodes) if not node: raise ValueError('could not find %r for %r' % (x, self)) if id(node) == id(self.inputs[0]): # ignore the source file, it is already in the dependencies # this way, successful config tests may be retrieved from the cache continue nodes.append(node) Logs.debug('deps: gccdeps for %s returned %s', self, nodes) bld.node_deps[self.uid()] = nodes bld.raw_deps[self.uid()] = [] try: del self.cache_sig except AttributeError: pass Task.Task.post_run(self) def sig_implicit_deps(self): if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: return super(self.derived_gccdeps, self).sig_implicit_deps() try: return Task.Task.sig_implicit_deps(self) except Errors.WafError: return Utils.SIG_NIL def wrap_compiled_task(classname): derived_class = type(classname, (Task.classes[classname],), {}) derived_class.derived_gccdeps = derived_class derived_class.post_run = post_run derived_class.scan = scan derived_class.sig_implicit_deps = sig_implicit_deps for k in ('c', 'cxx'): if k in Task.classes: wrap_compiled_task(k) @before_method('process_source') @feature('force_gccdeps') def force_gccdeps(self): self.env.ENABLE_GCCDEPS = ['c', 'cxx'] def configure(conf): # in case someone provides a --enable-gccdeps command-line option if not getattr(conf.options, 'enable_gccdeps', True): return global gccdeps_flags flags = conf.env.GCCDEPS_FLAGS or gccdeps_flags if conf.env.CC_NAME in supported_compilers: try: conf.check(fragment='int main() { return 0; }', features='c force_gccdeps', cflags=flags, msg='Checking for c flags %r' % ''.join(flags)) except Errors.ConfigurationError: pass else: conf.env.append_value('CFLAGS', flags) conf.env.append_unique('ENABLE_GCCDEPS', 'c') if conf.env.CXX_NAME in supported_compilers: try: conf.check(fragment='int main() { return 0; }', features='cxx force_gccdeps', cxxflags=flags, msg='Checking for cxx flags %r' % ''.join(flags)) except Errors.ConfigurationError: pass else: conf.env.append_value('CXXFLAGS', flags) conf.env.append_unique('ENABLE_GCCDEPS', 'cxx') def options(opt): raise ValueError('Do not load gccdeps options') ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py0000660000000000000000000000553213573675414021600 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Copyright Garmin International or its subsidiaries, 2018 # # Heavily based on dbus.py """ Compiles dbus files with **gdbus-codegen** Typical usage:: def options(opt): opt.load('compiler_c gdbus') def configure(conf): conf.load('compiler_c gdbus') def build(bld): tg = bld.program( includes = '.', source = bld.path.ant_glob('*.c'), target = 'gnome-hello') tg.add_gdbus_file('test.xml', 'com.example.example.', 'Example') """ from waflib import Task, Errors, Utils from waflib.TaskGen import taskgen_method, before_method @taskgen_method def add_gdbus_file(self, filename, prefix, namespace, export=False): """ Adds a dbus file to the list of dbus files to process. Store them in the attribute *dbus_lst*. :param filename: xml file to compile :type filename: string :param prefix: interface prefix (--interface-prefix=prefix) :type prefix: string :param mode: C namespace (--c-namespace=namespace) :type mode: string :param export: Export Headers? :type export: boolean """ if not hasattr(self, 'gdbus_lst'): self.gdbus_lst = [] if not 'process_gdbus' in self.meths: self.meths.append('process_gdbus') self.gdbus_lst.append([filename, prefix, namespace, export]) @before_method('process_source') def process_gdbus(self): """ Processes the dbus files stored in the attribute *gdbus_lst* to create :py:class:`gdbus_binding_tool` instances. """ output_node = self.path.get_bld().make_node(['gdbus', self.get_name()]) sources = [] for filename, prefix, namespace, export in getattr(self, 'gdbus_lst', []): node = self.path.find_resource(filename) if not node: raise Errors.WafError('file not found ' + filename) c_file = output_node.find_or_declare(node.change_ext('.c').name) h_file = output_node.find_or_declare(node.change_ext('.h').name) tsk = self.create_task('gdbus_binding_tool', node, [c_file, h_file]) tsk.cwd = output_node.abspath() tsk.env.GDBUS_CODEGEN_INTERFACE_PREFIX = prefix tsk.env.GDBUS_CODEGEN_NAMESPACE = namespace tsk.env.GDBUS_CODEGEN_OUTPUT = node.change_ext('').name sources.append(c_file) if sources: output_node.mkdir() self.source = Utils.to_list(self.source) + sources self.includes = [output_node] + self.to_incnodes(getattr(self, 'includes', [])) if export: self.export_includes = [output_node] + self.to_incnodes(getattr(self, 'export_includes', [])) class gdbus_binding_tool(Task.Task): """ Compiles a dbus file """ color = 'BLUE' ext_out = ['.h', '.c'] run_str = '${GDBUS_CODEGEN} --interface-prefix ${GDBUS_CODEGEN_INTERFACE_PREFIX} --generate-c-code ${GDBUS_CODEGEN_OUTPUT} --c-namespace ${GDBUS_CODEGEN_NAMESPACE} --c-generate-object-manager ${SRC[0].abspath()}' shell = True def configure(conf): """ Detects the program gdbus-codegen and sets ``conf.env.GDBUS_CODEGEN`` """ conf.find_program('gdbus-codegen', var='GDBUS_CODEGEN') ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py0000660000000000000000000001553013573675414022452 0ustar rootroot00000000000000import os import pipes import subprocess import sys from waflib import Logs, Task, Context from waflib.Tools.c_preproc import scan as scan_impl # ^-- Note: waflib.extras.gccdeps.scan does not work for us, # due to its current implementation: # The -MD flag is injected into the {C,CXX}FLAGS environment variable and # dependencies are read out in a separate step after compiling by reading # the .d file saved alongside the object file. # As the genpybind task refers to a header file that is never compiled itself, # gccdeps will not be able to extract the list of dependencies. from waflib.TaskGen import feature, before_method def join_args(args): return " ".join(pipes.quote(arg) for arg in args) def configure(cfg): cfg.load("compiler_cxx") cfg.load("python") cfg.check_python_version(minver=(2, 7)) if not cfg.env.LLVM_CONFIG: cfg.find_program("llvm-config", var="LLVM_CONFIG") if not cfg.env.GENPYBIND: cfg.find_program("genpybind", var="GENPYBIND") # find clang reasource dir for builtin headers cfg.env.GENPYBIND_RESOURCE_DIR = os.path.join( cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--libdir"]).strip(), "clang", cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--version"]).strip()) if os.path.exists(cfg.env.GENPYBIND_RESOURCE_DIR): cfg.msg("Checking clang resource dir", cfg.env.GENPYBIND_RESOURCE_DIR) else: cfg.fatal("Clang resource dir not found") @feature("genpybind") @before_method("process_source") def generate_genpybind_source(self): """ Run genpybind on the headers provided in `source` and compile/link the generated code instead. This works by generating the code on the fly and swapping the source node before `process_source` is run. """ # name of module defaults to name of target module = getattr(self, "module", self.target) # create temporary source file in build directory to hold generated code out = "genpybind-%s.%d.cpp" % (module, self.idx) out = self.path.get_bld().find_or_declare(out) task = self.create_task("genpybind", self.to_nodes(self.source), out) # used to detect whether CFLAGS or CXXFLAGS should be passed to genpybind task.features = self.features task.module = module # can be used to select definitions to include in the current module # (when header files are shared by more than one module) task.genpybind_tags = self.to_list(getattr(self, "genpybind_tags", [])) # additional include directories task.includes = self.to_list(getattr(self, "includes", [])) task.genpybind = self.env.GENPYBIND # Tell waf to compile/link the generated code instead of the headers # originally passed-in via the `source` parameter. (see `process_source`) self.source = [out] class genpybind(Task.Task): # pylint: disable=invalid-name """ Runs genpybind on headers provided as input to this task. Generated code will be written to the first (and only) output node. """ quiet = True color = "PINK" scan = scan_impl @staticmethod def keyword(): return "Analyzing" def run(self): if not self.inputs: return args = self.find_genpybind() + self._arguments( resource_dir=self.env.GENPYBIND_RESOURCE_DIR) output = self.run_genpybind(args) # For debugging / log output pasteable_command = join_args(args) # write generated code to file in build directory # (will be compiled during process_source stage) (output_node,) = self.outputs output_node.write("// {}\n{}\n".format( pasteable_command.replace("\n", "\n// "), output)) def find_genpybind(self): return self.genpybind def run_genpybind(self, args): bld = self.generator.bld kwargs = dict(cwd=bld.variant_dir) if hasattr(bld, "log_command"): bld.log_command(args, kwargs) else: Logs.debug("runner: {!r}".format(args)) proc = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) stdout, stderr = proc.communicate() if not isinstance(stdout, str): stdout = stdout.decode(sys.stdout.encoding, errors="replace") if not isinstance(stderr, str): stderr = stderr.decode(sys.stderr.encoding, errors="replace") if proc.returncode != 0: bld.fatal( "genpybind returned {code} during the following call:" "\n{command}\n\n{stdout}\n\n{stderr}".format( code=proc.returncode, command=join_args(args), stdout=stdout, stderr=stderr, )) if stderr.strip(): Logs.debug("non-fatal warnings during genpybind run:\n{}".format(stderr)) return stdout def _include_paths(self): return self.generator.to_incnodes(self.includes + self.env.INCLUDES) def _inputs_as_relative_includes(self): include_paths = self._include_paths() relative_includes = [] for node in self.inputs: for inc in include_paths: if node.is_child_of(inc): relative_includes.append(node.path_from(inc)) break else: self.generator.bld.fatal("could not resolve {}".format(node)) return relative_includes def _arguments(self, genpybind_parse=None, resource_dir=None): args = [] relative_includes = self._inputs_as_relative_includes() is_cxx = "cxx" in self.features # options for genpybind args.extend(["--genpybind-module", self.module]) if self.genpybind_tags: args.extend(["--genpybind-tag"] + self.genpybind_tags) if relative_includes: args.extend(["--genpybind-include"] + relative_includes) if genpybind_parse: args.extend(["--genpybind-parse", genpybind_parse]) args.append("--") # headers to be processed by genpybind args.extend(node.abspath() for node in self.inputs) args.append("--") # options for clang/genpybind-parse args.append("-D__GENPYBIND__") args.append("-xc++" if is_cxx else "-xc") has_std_argument = False for flag in self.env["CXXFLAGS" if is_cxx else "CFLAGS"]: flag = flag.replace("-std=gnu", "-std=c") if flag.startswith("-std=c"): has_std_argument = True args.append(flag) if not has_std_argument: args.append("-std=c++14") args.extend("-I{}".format(n.abspath()) for n in self._include_paths()) args.extend("-D{}".format(p) for p in self.env.DEFINES) # point to clang resource dir, if specified if resource_dir: args.append("-resource-dir={}".format(resource_dir)) return args ldb-2.0.8/third_party/waf/waflib/extras/gob2.py0000660000000000000000000000047213573675414021323 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Ali Sabil, 2007 from waflib import TaskGen TaskGen.declare_chain( name = 'gob2', rule = '${GOB2} -o ${TGT[0].bld_dir()} ${GOB2FLAGS} ${SRC}', ext_in = '.gob', ext_out = '.c' ) def configure(conf): conf.find_program('gob2', var='GOB2') conf.env['GOB2FLAGS'] = '' ldb-2.0.8/third_party/waf/waflib/extras/halide.py0000660000000000000000000000762313573675414021725 0ustar rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Halide code generation tool __author__ = __maintainer__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2014" """ Tool to run `Halide `_ code generators. Usage:: bld( name='pipeline', # ^ Reference this in use="..." for things using the generated code #target=['pipeline.o', 'pipeline.h'] # ^ by default, name.{o,h} is added, but you can set the outputs here features='halide', halide_env="HL_TRACE=1 HL_TARGET=host-opencl-gpu_debug", # ^ Environment passed to the generator, # can be a dict, k/v list, or string. args=[], # ^ Command-line arguments to the generator (optional), # eg. to give parameters to the scheduling source='pipeline_gen', # ^ Name of the source executable ) Known issues: - Currently only supports Linux (no ".exe") - Doesn't rerun on input modification when input is part of a build chain, and has been modified externally. """ import os from waflib import Task, Utils, Options, TaskGen, Errors class run_halide_gen(Task.Task): color = 'CYAN' vars = ['HALIDE_ENV', 'HALIDE_ARGS'] run_str = "${SRC[0].abspath()} ${HALIDE_ARGS}" def __str__(self): stuff = "halide" stuff += ("[%s]" % (",".join( ('%s=%s' % (k,v)) for k, v in sorted(self.env.env.items())))) return Task.Task.__str__(self).replace(self.__class__.__name__, stuff) @TaskGen.feature('halide') @TaskGen.before_method('process_source') def halide(self): Utils.def_attrs(self, args=[], halide_env={}, ) bld = self.bld env = self.halide_env try: if isinstance(env, str): env = dict(x.split('=') for x in env.split()) elif isinstance(env, list): env = dict(x.split('=') for x in env) assert isinstance(env, dict) except Exception as e: if not isinstance(e, ValueError) \ and not isinstance(e, AssertionError): raise raise Errors.WafError( "halide_env must be under the form" \ " {'HL_x':'a', 'HL_y':'b'}" \ " or ['HL_x=y', 'HL_y=b']" \ " or 'HL_x=y HL_y=b'") src = self.to_nodes(self.source) assert len(src) == 1, "Only one source expected" src = src[0] args = Utils.to_list(self.args) def change_ext(src, ext): # Return a node with a new extension, in an appropriate folder name = src.name xpos = src.name.rfind('.') if xpos == -1: xpos = len(src.name) newname = name[:xpos] + ext if src.is_child_of(bld.bldnode): node = src.get_src().parent.find_or_declare(newname) else: node = bld.bldnode.find_or_declare(newname) return node def to_nodes(self, lst, path=None): tmp = [] path = path or self.path find = path.find_or_declare if isinstance(lst, self.path.__class__): lst = [lst] for x in Utils.to_list(lst): if isinstance(x, str): node = find(x) else: node = x tmp.append(node) return tmp tgt = to_nodes(self, self.target) if not tgt: tgt = [change_ext(src, '.o'), change_ext(src, '.h')] cwd = tgt[0].parent.abspath() task = self.create_task('run_halide_gen', src, tgt, cwd=cwd) task.env.append_unique('HALIDE_ARGS', args) if task.env.env == []: task.env.env = {} task.env.env.update(env) task.env.HALIDE_ENV = " ".join(("%s=%s" % (k,v)) for (k,v) in sorted(env.items())) task.env.HALIDE_ARGS = args try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] self.source = [] def configure(conf): if Options.options.halide_root is None: conf.check_cfg(package='Halide', args='--cflags --libs') else: halide_root = Options.options.halide_root conf.env.INCLUDES_HALIDE = [ os.path.join(halide_root, "include") ] conf.env.LIBPATH_HALIDE = [ os.path.join(halide_root, "lib") ] conf.env.LIB_HALIDE = ["Halide"] # You might want to add this, while upstream doesn't fix it #conf.env.LIB_HALIDE += ['ncurses', 'dl', 'pthread'] def options(opt): opt.add_option('--halide-root', help="path to Halide include and lib files", ) ldb-2.0.8/third_party/waf/waflib/extras/javatest.py0000770000000000000000000001004513573675414022312 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Federico Pellegrin, 2017 (fedepell) """ Provides Java Unit test support using :py:class:`waflib.Tools.waf_unit_test.utest` task via the **javatest** feature. This gives the possibility to run unit test and have them integrated into the standard waf unit test environment. It has been tested with TestNG and JUnit but should be easily expandable to other frameworks given the flexibility of ut_str provided by the standard waf unit test environment. Example usage: def options(opt): opt.load('java waf_unit_test javatest') def configure(conf): conf.load('java javatest') def build(bld): [ ... mainprog is built here ... ] bld(features = 'javac javatest', srcdir = 'test/', outdir = 'test', sourcepath = ['test'], classpath = [ 'src' ], basedir = 'test', use = ['JAVATEST', 'mainprog'], # mainprog is the program being tested in src/ ut_str = 'java -cp ${CLASSPATH} ${JTRUNNER} ${SRC}', jtest_source = bld.path.ant_glob('test/*.xml'), ) At command line the CLASSPATH where to find the testing environment and the test runner (default TestNG) that will then be seen in the environment as CLASSPATH_JAVATEST (then used for use) and JTRUNNER and can be used for dependencies and ut_str generation. Example configure for TestNG: waf configure --jtpath=/tmp/testng-6.12.jar:/tmp/jcommander-1.71.jar --jtrunner=org.testng.TestNG or as default runner is TestNG: waf configure --jtpath=/tmp/testng-6.12.jar:/tmp/jcommander-1.71.jar Example configure for JUnit: waf configure --jtpath=/tmp/junit.jar --jtrunner=org.junit.runner.JUnitCore The runner class presence on the system is checked for at configuration stage. """ import os from waflib import Task, TaskGen, Options @TaskGen.feature('javatest') @TaskGen.after_method('apply_java', 'use_javac_files', 'set_classpath') def make_javatest(self): """ Creates a ``utest`` task with a populated environment for Java Unit test execution """ tsk = self.create_task('utest') tsk.set_run_after(self.javac_task) # Put test input files as waf_unit_test relies on that for some prints and log generation # If jtest_source is there, this is specially useful for passing XML for TestNG # that contain test specification, use that as inputs, otherwise test sources if getattr(self, 'jtest_source', None): tsk.inputs = self.to_nodes(self.jtest_source) else: if self.javac_task.srcdir[0].exists(): tsk.inputs = self.javac_task.srcdir[0].ant_glob('**/*.java', remove=False) if getattr(self, 'ut_str', None): self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) tsk.vars = lst + tsk.vars if getattr(self, 'ut_cwd', None): if isinstance(self.ut_cwd, str): # we want a Node instance if os.path.isabs(self.ut_cwd): self.ut_cwd = self.bld.root.make_node(self.ut_cwd) else: self.ut_cwd = self.path.make_node(self.ut_cwd) else: self.ut_cwd = self.bld.bldnode # Get parent CLASSPATH and add output dir of test, we run from wscript dir # We have to change it from list to the standard java -cp format (: separated) tsk.env.CLASSPATH = ':'.join(self.env.CLASSPATH) + ':' + self.outdir.abspath() if not self.ut_cwd.exists(): self.ut_cwd.mkdir() if not hasattr(self, 'ut_env'): self.ut_env = dict(os.environ) def configure(ctx): cp = ctx.env.CLASSPATH or '.' if getattr(Options.options, 'jtpath', None): ctx.env.CLASSPATH_JAVATEST = getattr(Options.options, 'jtpath').split(':') cp += ':' + getattr(Options.options, 'jtpath') if getattr(Options.options, 'jtrunner', None): ctx.env.JTRUNNER = getattr(Options.options, 'jtrunner') if ctx.check_java_class(ctx.env.JTRUNNER, with_classpath=cp): ctx.fatal('Could not run test class %r' % ctx.env.JTRUNNER) def options(opt): opt.add_option('--jtpath', action='store', default='', dest='jtpath', help='Path to jar(s) needed for javatest execution, colon separated, if not in the system CLASSPATH') opt.add_option('--jtrunner', action='store', default='org.testng.TestNG', dest='jtrunner', help='Class to run javatest test [default: org.testng.TestNG]') ldb-2.0.8/third_party/waf/waflib/extras/kde4.py0000660000000000000000000000524313573675414021322 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) """ Support for the KDE4 libraries and msgfmt """ import os, re from waflib import Task, Utils from waflib.TaskGen import feature @feature('msgfmt') def apply_msgfmt(self): """ Process all languages to create .mo files and to install them:: def build(bld): bld(features='msgfmt', langs='es de fr', appname='myapp', install_path='${KDE4_LOCALE_INSTALL_DIR}') """ for lang in self.to_list(self.langs): node = self.path.find_resource(lang+'.po') task = self.create_task('msgfmt', node, node.change_ext('.mo')) langname = lang.split('/') langname = langname[-1] inst = getattr(self, 'install_path', '${KDE4_LOCALE_INSTALL_DIR}') self.add_install_as( inst_to = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + getattr(self, 'appname', 'set_your_appname') + '.mo', inst_from = task.outputs[0], chmod = getattr(self, 'chmod', Utils.O644)) class msgfmt(Task.Task): """ Transform .po files into .mo files """ color = 'BLUE' run_str = '${MSGFMT} ${SRC} -o ${TGT}' def configure(self): """ Detect kde4-config and set various variables for the *use* system:: def options(opt): opt.load('compiler_cxx kde4') def configure(conf): conf.load('compiler_cxx kde4') def build(bld): bld.program(source='main.c', target='app', use='KDECORE KIO KHTML') """ kdeconfig = self.find_program('kde4-config') prefix = self.cmd_and_log(kdeconfig + ['--prefix']).strip() fname = '%s/share/apps/cmake/modules/KDELibsDependencies.cmake' % prefix try: os.stat(fname) except OSError: fname = '%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake' % prefix try: os.stat(fname) except OSError: self.fatal('could not open %s' % fname) try: txt = Utils.readf(fname) except EnvironmentError: self.fatal('could not read %s' % fname) txt = txt.replace('\\\n', '\n') fu = re.compile('#(.*)\n') txt = fu.sub('', txt) setregexp = re.compile(r'([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)') found = setregexp.findall(txt) for (_, key, val) in found: #print key, val self.env[key] = val # well well, i could just write an interpreter for cmake files self.env['LIB_KDECORE']= ['kdecore'] self.env['LIB_KDEUI'] = ['kdeui'] self.env['LIB_KIO'] = ['kio'] self.env['LIB_KHTML'] = ['khtml'] self.env['LIB_KPARTS'] = ['kparts'] self.env['LIBPATH_KDECORE'] = [os.path.join(self.env.KDE4_LIB_INSTALL_DIR, 'kde4', 'devel'), self.env.KDE4_LIB_INSTALL_DIR] self.env['INCLUDES_KDECORE'] = [self.env['KDE4_INCLUDE_INSTALL_DIR']] self.env.append_value('INCLUDES_KDECORE', [self.env['KDE4_INCLUDE_INSTALL_DIR']+ os.sep + 'KDE']) self.find_program('msgfmt', var='MSGFMT') ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py0000660000000000000000000000112213573675414022753 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 (ita) import copy from waflib.TaskGen import after_method, feature @after_method('propagate_uselib_vars') @feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib', 'fcprogram', 'fcshlib') def add_rpath_stuff(self): all = copy.copy(self.to_list(getattr(self, 'use', []))) while all: name = all.pop() try: tg = self.bld.get_tgen_by_name(name) except: continue if hasattr(tg, 'link_task'): self.env.append_value('RPATH', tg.link_task.outputs[0].parent.abspath()) all.extend(self.to_list(getattr(tg, 'use', []))) ldb-2.0.8/third_party/waf/waflib/extras/make.py0000660000000000000000000000620213573675414021404 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 (ita) """ A make-like way of executing the build, following the relationships between inputs/outputs This algorithm will lead to slower builds, will not be as flexible as "waf build", but it might be useful for building data files (?) It is likely to break in the following cases: - files are created dynamically (no inputs or outputs) - headers - building two files from different groups """ import re from waflib import Options, Task from waflib.Build import BuildContext class MakeContext(BuildContext): '''executes tasks in a step-by-step manner, following dependencies between inputs/outputs''' cmd = 'make' fun = 'build' def __init__(self, **kw): super(MakeContext, self).__init__(**kw) self.files = Options.options.files def get_build_iterator(self): if not self.files: while 1: yield super(MakeContext, self).get_build_iterator() for g in self.groups: for tg in g: try: f = tg.post except AttributeError: pass else: f() provides = {} uses = {} all_tasks = [] tasks = [] for pat in self.files.split(','): matcher = self.get_matcher(pat) for tg in g: if isinstance(tg, Task.Task): lst = [tg] else: lst = tg.tasks for tsk in lst: all_tasks.append(tsk) do_exec = False for node in tsk.inputs: try: uses[node].append(tsk) except: uses[node] = [tsk] if matcher(node, output=False): do_exec = True break for node in tsk.outputs: try: provides[node].append(tsk) except: provides[node] = [tsk] if matcher(node, output=True): do_exec = True break if do_exec: tasks.append(tsk) # so we have the tasks that we need to process, the list of all tasks, # the map of the tasks providing nodes, and the map of tasks using nodes if not tasks: # if there are no tasks matching, return everything in the current group result = all_tasks else: # this is like a big filter... result = set() seen = set() cur = set(tasks) while cur: result |= cur tosee = set() for tsk in cur: for node in tsk.inputs: if node in seen: continue seen.add(node) tosee |= set(provides.get(node, [])) cur = tosee result = list(result) Task.set_file_constraints(result) Task.set_precedence_constraints(result) yield result while 1: yield [] def get_matcher(self, pat): # this returns a function inn = True out = True if pat.startswith('in:'): out = False pat = pat.replace('in:', '') elif pat.startswith('out:'): inn = False pat = pat.replace('out:', '') anode = self.root.find_node(pat) pattern = None if not anode: if not pat.startswith('^'): pat = '^.+?%s' % pat if not pat.endswith('$'): pat = '%s$' % pat pattern = re.compile(pat) def match(node, output): if output and not out: return False if not output and not inn: return False if anode: return anode == node else: return pattern.match(node.abspath()) return match ldb-2.0.8/third_party/waf/waflib/extras/midl.py0000660000000000000000000000324313573675414021416 0ustar rootroot00000000000000#!/usr/bin/env python # Issue 1185 ultrix gmail com """ Microsoft Interface Definition Language support. Given ComObject.idl, this tool will generate ComObject.tlb ComObject_i.h ComObject_i.c ComObject_p.c and dlldata.c To declare targets using midl:: def configure(conf): conf.load('msvc') conf.load('midl') def build(bld): bld( features='c cshlib', # Note: ComObject_i.c is generated from ComObject.idl source = 'main.c ComObject.idl ComObject_i.c', target = 'ComObject.dll') """ from waflib import Task, Utils from waflib.TaskGen import feature, before_method import os def configure(conf): conf.find_program(['midl'], var='MIDL') conf.env.MIDLFLAGS = [ '/nologo', '/D', '_DEBUG', '/W1', '/char', 'signed', '/Oicf', ] @feature('c', 'cxx') @before_method('process_source') def idl_file(self): # Do this before process_source so that the generated header can be resolved # when scanning source dependencies. idl_nodes = [] src_nodes = [] for node in Utils.to_list(self.source): if str(node).endswith('.idl'): idl_nodes.append(node) else: src_nodes.append(node) for node in self.to_nodes(idl_nodes): t = node.change_ext('.tlb') h = node.change_ext('_i.h') c = node.change_ext('_i.c') p = node.change_ext('_p.c') d = node.parent.find_or_declare('dlldata.c') self.create_task('midl', node, [t, h, c, p, d]) self.source = src_nodes class midl(Task.Task): """ Compile idl files """ color = 'YELLOW' run_str = '${MIDL} ${MIDLFLAGS} ${CPPPATH_ST:INCLUDES} /tlb ${TGT[0].bldpath()} /header ${TGT[1].bldpath()} /iid ${TGT[2].bldpath()} /proxy ${TGT[3].bldpath()} /dlldata ${TGT[4].bldpath()} ${SRC}' before = ['winrc'] ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py0000660000000000000000000001652313573675414022322 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Copyright Garmin International or its subsidiaries, 2012-2013 ''' Off-load dependency scanning from Python code to MSVC compiler This tool is safe to load in any environment; it will only activate the MSVC exploits when it finds that a particular taskgen uses MSVC to compile. Empirical testing shows about a 10% execution time savings from using this tool as compared to c_preproc. The technique of gutting scan() and pushing the dependency calculation down to post_run() is cribbed from gccdeps.py. This affects the cxx class, so make sure to load Qt5 after this tool. Usage:: def options(opt): opt.load('compiler_cxx') def configure(conf): conf.load('compiler_cxx msvcdeps') ''' import os, sys, tempfile, threading from waflib import Context, Errors, Logs, Task, Utils from waflib.Tools import c_preproc, c, cxx, msvc from waflib.TaskGen import feature, before_method lock = threading.Lock() nodes = {} # Cache the path -> Node lookup PREPROCESSOR_FLAG = '/showIncludes' INCLUDE_PATTERN = 'Note: including file:' # Extensible by outside tools supported_compilers = ['msvc'] @feature('c', 'cxx') @before_method('process_source') def apply_msvcdeps_flags(taskgen): if taskgen.env.CC_NAME not in supported_compilers: return for flag in ('CFLAGS', 'CXXFLAGS'): if taskgen.env.get_flat(flag).find(PREPROCESSOR_FLAG) < 0: taskgen.env.append_value(flag, PREPROCESSOR_FLAG) def path_to_node(base_node, path, cached_nodes): ''' Take the base node and the path and return a node Results are cached because searching the node tree is expensive The following code is executed by threads, it is not safe, so a lock is needed... ''' # normalize the path because ant_glob() does not understand # parent path components (..) path = os.path.normpath(path) # normalize the path case to increase likelihood of a cache hit path = os.path.normcase(path) # ant_glob interprets [] and () characters, so those must be replaced path = path.replace('[', '?').replace(']', '?').replace('(', '[(]').replace(')', '[)]') node_lookup_key = (base_node, path) try: node = cached_nodes[node_lookup_key] except KeyError: # retry with lock on cache miss with lock: try: node = cached_nodes[node_lookup_key] except KeyError: node_list = base_node.ant_glob([path], ignorecase=True, remove=False, quiet=True, regex=False) node = cached_nodes[node_lookup_key] = node_list[0] if node_list else None return node def post_run(self): if self.env.CC_NAME not in supported_compilers: return super(self.derived_msvcdeps, self).post_run() # TODO this is unlikely to work with netcache if getattr(self, 'cached', None): return Task.Task.post_run(self) bld = self.generator.bld unresolved_names = [] resolved_nodes = [] # Dynamically bind to the cache try: cached_nodes = bld.cached_nodes except AttributeError: cached_nodes = bld.cached_nodes = {} for path in self.msvcdeps_paths: node = None if os.path.isabs(path): node = path_to_node(bld.root, path, cached_nodes) else: # when calling find_resource, make sure the path does not begin with '..' base_node = bld.bldnode path = [k for k in Utils.split_path(path) if k and k != '.'] while path[0] == '..': path.pop(0) base_node = base_node.parent path = os.sep.join(path) node = path_to_node(base_node, path, cached_nodes) if not node: raise ValueError('could not find %r for %r' % (path, self)) else: if not c_preproc.go_absolute: if not (node.is_child_of(bld.srcnode) or node.is_child_of(bld.bldnode)): # System library Logs.debug('msvcdeps: Ignoring system include %r', node) continue if id(node) == id(self.inputs[0]): # Self-dependency continue resolved_nodes.append(node) bld.node_deps[self.uid()] = resolved_nodes bld.raw_deps[self.uid()] = unresolved_names try: del self.cache_sig except AttributeError: pass Task.Task.post_run(self) def scan(self): if self.env.CC_NAME not in supported_compilers: return super(self.derived_msvcdeps, self).scan() resolved_nodes = self.generator.bld.node_deps.get(self.uid(), []) unresolved_names = [] return (resolved_nodes, unresolved_names) def sig_implicit_deps(self): if self.env.CC_NAME not in supported_compilers: return super(self.derived_msvcdeps, self).sig_implicit_deps() try: return Task.Task.sig_implicit_deps(self) except Errors.WafError: return Utils.SIG_NIL def exec_command(self, cmd, **kw): if self.env.CC_NAME not in supported_compilers: return super(self.derived_msvcdeps, self).exec_command(cmd, **kw) if not 'cwd' in kw: kw['cwd'] = self.get_cwd() if self.env.PATH: env = kw['env'] = dict(kw.get('env') or self.env.env or os.environ) env['PATH'] = self.env.PATH if isinstance(self.env.PATH, str) else os.pathsep.join(self.env.PATH) # The Visual Studio IDE adds an environment variable that causes # the MS compiler to send its textual output directly to the # debugging window rather than normal stdout/stderr. # # This is unrecoverably bad for this tool because it will cause # all the dependency scanning to see an empty stdout stream and # assume that the file being compiled uses no headers. # # See http://blogs.msdn.com/b/freik/archive/2006/04/05/569025.aspx # # Attempting to repair the situation by deleting the offending # envvar at this point in tool execution will not be good enough-- # its presence poisons the 'waf configure' step earlier. We just # want to put a sanity check here in order to help developers # quickly diagnose the issue if an otherwise-good Waf tree # is then executed inside the MSVS IDE. assert 'VS_UNICODE_OUTPUT' not in kw['env'] cmd, args = self.split_argfile(cmd) try: (fd, tmp) = tempfile.mkstemp() os.write(fd, '\r\n'.join(args).encode()) os.close(fd) self.msvcdeps_paths = [] kw['env'] = kw.get('env', os.environ.copy()) kw['cwd'] = kw.get('cwd', os.getcwd()) kw['quiet'] = Context.STDOUT kw['output'] = Context.STDOUT out = [] if Logs.verbose: Logs.debug('argfile: @%r -> %r', tmp, args) try: raw_out = self.generator.bld.cmd_and_log(cmd + ['@' + tmp], **kw) ret = 0 except Errors.WafError as e: # Use e.msg if e.stdout is not set raw_out = getattr(e, 'stdout', e.msg) # Return non-zero error code even if we didn't # get one from the exception object ret = getattr(e, 'returncode', 1) for line in raw_out.splitlines(): if line.startswith(INCLUDE_PATTERN): inc_path = line[len(INCLUDE_PATTERN):].strip() Logs.debug('msvcdeps: Regex matched %s', inc_path) self.msvcdeps_paths.append(inc_path) else: out.append(line) # Pipe through the remaining stdout content (not related to /showIncludes) if self.generator.bld.logger: self.generator.bld.logger.debug('out: %s' % os.linesep.join(out)) else: sys.stdout.write(os.linesep.join(out) + os.linesep) return ret finally: try: os.remove(tmp) except OSError: # anti-virus and indexers can keep files open -_- pass def wrap_compiled_task(classname): derived_class = type(classname, (Task.classes[classname],), {}) derived_class.derived_msvcdeps = derived_class derived_class.post_run = post_run derived_class.scan = scan derived_class.sig_implicit_deps = sig_implicit_deps derived_class.exec_command = exec_command for k in ('c', 'cxx'): if k in Task.classes: wrap_compiled_task(k) def options(opt): raise ValueError('Do not load msvcdeps options') ldb-2.0.8/third_party/waf/waflib/extras/msvs.py0000660000000000000000000007452213573675414021471 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Avalanche Studios 2009-2011 # Thomas Nagy 2011 """ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ """ To add this tool to your project: def options(conf): opt.load('msvs') It can be a good idea to add the sync_exec tool too. To generate solution files: $ waf configure msvs To customize the outputs, provide subclasses in your wscript files:: from waflib.extras import msvs class vsnode_target(msvs.vsnode_target): def get_build_command(self, props): # likely to be required return "waf.bat build" def collect_source(self): # likely to be required ... class msvs_bar(msvs.msvs_generator): def init(self): msvs.msvs_generator.init(self) self.vsnode_target = vsnode_target The msvs class re-uses the same build() function for reading the targets (task generators), you may therefore specify msvs settings on the context object:: def build(bld): bld.solution_name = 'foo.sln' bld.waf_command = 'waf.bat' bld.projects_dir = bld.srcnode.make_node('.depproj') bld.projects_dir.mkdir() For visual studio 2008, the command is called 'msvs2008', and the classes such as vsnode_target are wrapped by a decorator class 'wrap_2008' to provide special functionality. To customize platform toolsets, pass additional parameters, for example:: class msvs_2013(msvs.msvs_generator): cmd = 'msvs2013' numver = '13.00' vsver = '2013' platform_toolset_ver = 'v120' ASSUMPTIONS: * a project can be either a directory or a target, vcxproj files are written only for targets that have source files * each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path """ import os, re, sys import uuid # requires python 2.5 from waflib.Build import BuildContext from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' PROJECT_TEMPLATE = r''' ${for b in project.build_properties} ${b.configuration} ${b.platform} ${endfor} {${project.uuid}} MakeFileProj ${project.name} ${for b in project.build_properties} Makefile ${b.outdir} ${project.platform_toolset_ver} ${endfor} ${for b in project.build_properties} ${endfor} ${for b in project.build_properties} ${xml:project.get_build_command(b)} ${xml:project.get_rebuild_command(b)} ${xml:project.get_clean_command(b)} ${xml:b.includes_search_path} ${xml:b.preprocessor_definitions};$(NMakePreprocessorDefinitions) ${xml:b.includes_search_path} $(ExecutablePath) ${if getattr(b, 'output_file', None)} ${xml:b.output_file} ${endif} ${if getattr(b, 'deploy_dir', None)} ${xml:b.deploy_dir} ${endif} ${endfor} ${for b in project.build_properties} ${if getattr(b, 'deploy_dir', None)} CopyToHardDrive ${endif} ${endfor} ${for x in project.source} <${project.get_key(x)} Include='${x.win32path()}' /> ${endfor} ''' FILTER_TEMPLATE = ''' ${for x in project.source} <${project.get_key(x)} Include="${x.win32path()}"> ${project.get_filter_name(x.parent)} ${endfor} ${for x in project.dirs()} {${project.make_uuid(x.win32path())}} ${endfor} ''' PROJECT_2008_TEMPLATE = r''' ${if project.build_properties} ${for b in project.build_properties} ${endfor} ${else} ${endif} ${if project.build_properties} ${for b in project.build_properties} ${endfor} ${else} ${endif} ${project.display_filter()} ''' SOLUTION_TEMPLATE = '''Microsoft Visual Studio Solution File, Format Version ${project.numver} # Visual Studio ${project.vsver} ${for p in project.all_projects} Project("{${p.ptype()}}") = "${p.name}", "${p.title}", "{${p.uuid}}" EndProject${endfor} Global GlobalSection(SolutionConfigurationPlatforms) = preSolution ${if project.all_projects} ${for (configuration, platform) in project.all_projects[0].ctx.project_configurations()} ${configuration}|${platform} = ${configuration}|${platform} ${endfor} ${endif} EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution ${for p in project.all_projects} ${if hasattr(p, 'source')} ${for b in p.build_properties} {${p.uuid}}.${b.configuration}|${b.platform}.ActiveCfg = ${b.configuration}|${b.platform} ${if getattr(p, 'is_active', None)} {${p.uuid}}.${b.configuration}|${b.platform}.Build.0 = ${b.configuration}|${b.platform} ${endif} ${if getattr(p, 'is_deploy', None)} {${p.uuid}}.${b.configuration}|${b.platform}.Deploy.0 = ${b.configuration}|${b.platform} ${endif} ${endfor} ${endif} ${endfor} EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution ${for p in project.all_projects} ${if p.parent} {${p.uuid}} = {${p.parent.uuid}} ${endif} ${endfor} EndGlobalSection EndGlobal ''' COMPILE_TEMPLATE = '''def f(project): lst = [] def xml_escape(value): return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") %s #f = open('cmd.txt', 'w') #f.write(str(lst)) #f.close() return ''.join(lst) ''' reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) def compile_template(line): """ Compile a template expression into a python function (like jsps, but way shorter) """ extr = [] def repl(match): g = match.group if g('dollar'): return "$" elif g('backslash'): return "\\" elif g('subst'): extr.append(g('code')) return "<<|@|>>" return None line2 = reg_act.sub(repl, line) params = line2.split('<<|@|>>') assert(extr) indent = 0 buf = [] app = buf.append def app(txt): buf.append(indent * '\t' + txt) for x in range(len(extr)): if params[x]: app("lst.append(%r)" % params[x]) f = extr[x] if f.startswith(('if', 'for')): app(f + ':') indent += 1 elif f.startswith('py:'): app(f[3:]) elif f.startswith(('endif', 'endfor')): indent -= 1 elif f.startswith(('else', 'elif')): indent -= 1 app(f + ':') indent += 1 elif f.startswith('xml:'): app('lst.append(xml_escape(%s))' % f[4:]) else: #app('lst.append((%s) or "cannot find %s")' % (f, f)) app('lst.append(%s)' % f) if extr: if params[-1]: app("lst.append(%r)" % params[-1]) fun = COMPILE_TEMPLATE % "\n\t".join(buf) #print(fun) return Task.funex(fun) re_blank = re.compile('(\n|\r|\\s)*\n', re.M) def rm_blank_lines(txt): txt = re_blank.sub('\r\n', txt) return txt BOM = '\xef\xbb\xbf' try: BOM = bytes(BOM, 'latin-1') # python 3 except TypeError: pass def stealth_write(self, data, flags='wb'): try: unicode except NameError: data = data.encode('utf-8') # python 3 else: data = data.decode(sys.getfilesystemencoding(), 'replace') data = data.encode('utf-8') if self.name.endswith(('.vcproj', '.vcxproj')): data = BOM + data try: txt = self.read(flags='rb') if txt != data: raise ValueError('must write') except (IOError, ValueError): self.write(data, flags=flags) else: Logs.debug('msvs: skipping %s', self.win32path()) Node.Node.stealth_write = stealth_write re_win32 = re.compile(r'^([/\\]cygdrive)?[/\\]([a-z])([^a-z0-9_-].*)', re.I) def win32path(self): p = self.abspath() m = re_win32.match(p) if m: return "%s:%s" % (m.group(2).upper(), m.group(3)) return p Node.Node.win32path = win32path re_quote = re.compile("[^a-zA-Z0-9-]") def quote(s): return re_quote.sub("_", s) def xml_escape(value): return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") def make_uuid(v, prefix = None): """ simple utility function """ if isinstance(v, dict): keys = list(v.keys()) keys.sort() tmp = str([(k, v[k]) for k in keys]) else: tmp = str(v) d = Utils.md5(tmp.encode()).hexdigest().upper() if prefix: d = '%s%s' % (prefix, d[8:]) gid = uuid.UUID(d, version = 4) return str(gid).upper() def diff(node, fromnode): # difference between two nodes, but with "(..)" instead of ".." c1 = node c2 = fromnode c1h = c1.height() c2h = c2.height() lst = [] up = 0 while c1h > c2h: lst.append(c1.name) c1 = c1.parent c1h -= 1 while c2h > c1h: up += 1 c2 = c2.parent c2h -= 1 while id(c1) != id(c2): lst.append(c1.name) up += 1 c1 = c1.parent c2 = c2.parent for i in range(up): lst.append('(..)') lst.reverse() return tuple(lst) class build_property(object): pass class vsnode(object): """ Abstract class representing visual studio elements We assume that all visual studio nodes have a uuid and a parent """ def __init__(self, ctx): self.ctx = ctx # msvs context self.name = '' # string, mandatory self.vspath = '' # path in visual studio (name for dirs, absolute path for projects) self.uuid = '' # string, mandatory self.parent = None # parent node for visual studio nesting def get_waf(self): """ Override in subclasses... """ return 'cd /d "%s" & %s' % (self.ctx.srcnode.win32path(), getattr(self.ctx, 'waf_command', 'waf.bat')) def ptype(self): """ Return a special uuid for projects written in the solution file """ pass def write(self): """ Write the project file, by default, do nothing """ pass def make_uuid(self, val): """ Alias for creating uuid values easily (the templates cannot access global variables) """ return make_uuid(val) class vsnode_vsdir(vsnode): """ Nodes representing visual studio folders (which do not match the filesystem tree!) """ VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8" def __init__(self, ctx, uuid, name, vspath=''): vsnode.__init__(self, ctx) self.title = self.name = name self.uuid = uuid self.vspath = vspath or name def ptype(self): return self.VS_GUID_SOLUTIONFOLDER class vsnode_project(vsnode): """ Abstract class representing visual studio project elements A project is assumed to be writable, and has a node representing the file to write to """ VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" def ptype(self): return self.VS_GUID_VCPROJ def __init__(self, ctx, node): vsnode.__init__(self, ctx) self.path = node self.uuid = make_uuid(node.win32path()) self.name = node.name self.platform_toolset_ver = getattr(ctx, 'platform_toolset_ver', None) self.title = self.path.win32path() self.source = [] # list of node objects self.build_properties = [] # list of properties (nmake commands, output dir, etc) def dirs(self): """ Get the list of parent folders of the source files (header files included) for writing the filters """ lst = [] def add(x): if x.height() > self.tg.path.height() and x not in lst: lst.append(x) add(x.parent) for x in self.source: add(x.parent) return lst def write(self): Logs.debug('msvs: creating %r', self.path) # first write the project file template1 = compile_template(PROJECT_TEMPLATE) proj_str = template1(self) proj_str = rm_blank_lines(proj_str) self.path.stealth_write(proj_str) # then write the filter template2 = compile_template(FILTER_TEMPLATE) filter_str = template2(self) filter_str = rm_blank_lines(filter_str) tmp = self.path.parent.make_node(self.path.name + '.filters') tmp.stealth_write(filter_str) def get_key(self, node): """ required for writing the source files """ name = node.name if name.endswith(('.cpp', '.c')): return 'ClCompile' return 'ClInclude' def collect_properties(self): """ Returns a list of triplet (configuration, platform, output_directory) """ ret = [] for c in self.ctx.configurations: for p in self.ctx.platforms: x = build_property() x.outdir = '' x.configuration = c x.platform = p x.preprocessor_definitions = '' x.includes_search_path = '' # can specify "deploy_dir" too ret.append(x) self.build_properties = ret def get_build_params(self, props): opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() return (self.get_waf(), opt) def get_build_command(self, props): return "%s build %s" % self.get_build_params(props) def get_clean_command(self, props): return "%s clean %s" % self.get_build_params(props) def get_rebuild_command(self, props): return "%s clean build %s" % self.get_build_params(props) def get_filter_name(self, node): lst = diff(node, self.tg.path) return '\\'.join(lst) or '.' class vsnode_alias(vsnode_project): def __init__(self, ctx, node, name): vsnode_project.__init__(self, ctx, node) self.name = name self.output_file = '' class vsnode_build_all(vsnode_alias): """ Fake target used to emulate the behaviour of "make all" (starting one process by target is slow) This is the only alias enabled by default """ def __init__(self, ctx, node, name='build_all_projects'): vsnode_alias.__init__(self, ctx, node, name) self.is_active = True class vsnode_install_all(vsnode_alias): """ Fake target used to emulate the behaviour of "make install" """ def __init__(self, ctx, node, name='install_all_projects'): vsnode_alias.__init__(self, ctx, node, name) def get_build_command(self, props): return "%s build install %s" % self.get_build_params(props) def get_clean_command(self, props): return "%s clean %s" % self.get_build_params(props) def get_rebuild_command(self, props): return "%s clean build install %s" % self.get_build_params(props) class vsnode_project_view(vsnode_alias): """ Fake target used to emulate a file system view """ def __init__(self, ctx, node, name='project_view'): vsnode_alias.__init__(self, ctx, node, name) self.tg = self.ctx() # fake one, cannot remove self.exclude_files = Node.exclude_regs + ''' waf-2* waf3-2*/** .waf-2* .waf3-2*/** **/*.sdf **/*.suo **/*.ncb **/%s ''' % Options.lockfile def collect_source(self): # this is likely to be slow self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files) def get_build_command(self, props): params = self.get_build_params(props) + (self.ctx.cmd,) return "%s %s %s" % params def get_clean_command(self, props): return "" def get_rebuild_command(self, props): return self.get_build_command(props) class vsnode_target(vsnode_project): """ Visual studio project representing a targets (programs, libraries, etc) and bound to a task generator """ def __init__(self, ctx, tg): """ A project is more or less equivalent to a file/folder """ base = getattr(ctx, 'projects_dir', None) or tg.path node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node vsnode_project.__init__(self, ctx, node) self.name = quote(tg.name) self.tg = tg # task generator def get_build_params(self, props): """ Override the default to add the target name """ opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() if getattr(self, 'tg', None): opt += " --targets=%s" % self.tg.name return (self.get_waf(), opt) def collect_source(self): tg = self.tg source_files = tg.to_nodes(getattr(tg, 'source', [])) include_dirs = Utils.to_list(getattr(tg, 'msvs_includes', [])) include_files = [] for x in include_dirs: if isinstance(x, str): x = tg.path.find_node(x) if x: lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)] include_files.extend(lst) # remove duplicates self.source.extend(list(set(source_files + include_files))) self.source.sort(key=lambda x: x.win32path()) def collect_properties(self): """ Visual studio projects are associated with platforms and configurations (for building especially) """ super(vsnode_target, self).collect_properties() for x in self.build_properties: x.outdir = self.path.parent.win32path() x.preprocessor_definitions = '' x.includes_search_path = '' try: tsk = self.tg.link_task except AttributeError: pass else: x.output_file = tsk.outputs[0].win32path() x.preprocessor_definitions = ';'.join(tsk.env.DEFINES) x.includes_search_path = ';'.join(self.tg.env.INCPATHS) class msvs_generator(BuildContext): '''generates a visual studio 2010 solution''' cmd = 'msvs' fun = 'build' numver = '11.00' # Visual Studio Version Number vsver = '2010' # Visual Studio Version Year platform_toolset_ver = 'v110' # Platform Toolset Version Number def init(self): """ Some data that needs to be present """ if not getattr(self, 'configurations', None): self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc if not getattr(self, 'platforms', None): self.platforms = ['Win32'] if not getattr(self, 'all_projects', None): self.all_projects = [] if not getattr(self, 'project_extension', None): self.project_extension = '.vcxproj' if not getattr(self, 'projects_dir', None): self.projects_dir = self.srcnode.make_node('.depproj') self.projects_dir.mkdir() # bind the classes to the object, so that subclass can provide custom generators if not getattr(self, 'vsnode_vsdir', None): self.vsnode_vsdir = vsnode_vsdir if not getattr(self, 'vsnode_target', None): self.vsnode_target = vsnode_target if not getattr(self, 'vsnode_build_all', None): self.vsnode_build_all = vsnode_build_all if not getattr(self, 'vsnode_install_all', None): self.vsnode_install_all = vsnode_install_all if not getattr(self, 'vsnode_project_view', None): self.vsnode_project_view = vsnode_project_view self.numver = self.__class__.numver self.vsver = self.__class__.vsver self.platform_toolset_ver = self.__class__.platform_toolset_ver def execute(self): """ Entry point """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) # user initialization self.init() # two phases for creating the solution self.collect_projects() # add project objects into "self.all_projects" self.write_files() # write the corresponding project and solution files def collect_projects(self): """ Fill the list self.all_projects with project objects Fill the list of build targets """ self.collect_targets() self.add_aliases() self.collect_dirs() default_project = getattr(self, 'default_project', None) def sortfun(x): if x.name == default_project: return '' return getattr(x, 'path', None) and x.path.win32path() or x.name self.all_projects.sort(key=sortfun) def write_files(self): """ Write the project and solution files from the data collected so far. It is unlikely that you will want to change this """ for p in self.all_projects: p.write() # and finally write the solution file node = self.get_solution_node() node.parent.mkdir() Logs.warn('Creating %r', node) template1 = compile_template(SOLUTION_TEMPLATE) sln_str = template1(self) sln_str = rm_blank_lines(sln_str) node.stealth_write(sln_str) def get_solution_node(self): """ The solution filename is required when writing the .vcproj files return self.solution_node and if it does not exist, make one """ try: return self.solution_node except AttributeError: pass solution_name = getattr(self, 'solution_name', None) if not solution_name: solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.sln' if os.path.isabs(solution_name): self.solution_node = self.root.make_node(solution_name) else: self.solution_node = self.srcnode.make_node(solution_name) return self.solution_node def project_configurations(self): """ Helper that returns all the pairs (config,platform) """ ret = [] for c in self.configurations: for p in self.platforms: ret.append((c, p)) return ret def collect_targets(self): """ Process the list of task generators """ for g in self.groups: for tg in g: if not isinstance(tg, TaskGen.task_gen): continue if not hasattr(tg, 'msvs_includes'): tg.msvs_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', [])) tg.post() if not getattr(tg, 'link_task', None): continue p = self.vsnode_target(self, tg) p.collect_source() # delegate this processing p.collect_properties() self.all_projects.append(p) def add_aliases(self): """ Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7 We also add an alias for "make install" (disabled by default) """ base = getattr(self, 'projects_dir', None) or self.tg.path node_project = base.make_node('build_all_projects' + self.project_extension) # Node p_build = self.vsnode_build_all(self, node_project) p_build.collect_properties() self.all_projects.append(p_build) node_project = base.make_node('install_all_projects' + self.project_extension) # Node p_install = self.vsnode_install_all(self, node_project) p_install.collect_properties() self.all_projects.append(p_install) node_project = base.make_node('project_view' + self.project_extension) # Node p_view = self.vsnode_project_view(self, node_project) p_view.collect_source() p_view.collect_properties() self.all_projects.append(p_view) n = self.vsnode_vsdir(self, make_uuid(self.srcnode.win32path() + 'build_aliases'), "build_aliases") p_build.parent = p_install.parent = p_view.parent = n self.all_projects.append(n) def collect_dirs(self): """ Create the folder structure in the Visual studio project view """ seen = {} def make_parents(proj): # look at a project, try to make a parent if getattr(proj, 'parent', None): # aliases already have parents return x = proj.iter_path if x in seen: proj.parent = seen[x] return # There is not vsnode_vsdir for x. # So create a project representing the folder "x" n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.win32path()), x.name) n.iter_path = x.parent self.all_projects.append(n) # recurse up to the project directory if x.height() > self.srcnode.height() + 1: make_parents(n) for p in self.all_projects[:]: # iterate over a copy of all projects if not getattr(p, 'tg', None): # but only projects that have a task generator continue # make a folder for each task generator p.iter_path = p.tg.path make_parents(p) def wrap_2008(cls): class dec(cls): def __init__(self, *k, **kw): cls.__init__(self, *k, **kw) self.project_template = PROJECT_2008_TEMPLATE def display_filter(self): root = build_property() root.subfilters = [] root.sourcefiles = [] root.source = [] root.name = '' @Utils.run_once def add_path(lst): if not lst: return root child = build_property() child.subfilters = [] child.sourcefiles = [] child.source = [] child.name = lst[-1] par = add_path(lst[:-1]) par.subfilters.append(child) return child for x in self.source: # this crap is for enabling subclasses to override get_filter_name tmp = self.get_filter_name(x.parent) tmp = tmp != '.' and tuple(tmp.split('\\')) or () par = add_path(tmp) par.source.append(x) def display(n): buf = [] for x in n.source: buf.append('\n' % (xml_escape(x.win32path()), self.get_key(x))) for x in n.subfilters: buf.append('' % xml_escape(x.name)) buf.append(display(x)) buf.append('') return '\n'.join(buf) return display(root) def get_key(self, node): """ If you do not want to let visual studio use the default file extensions, override this method to return a value: 0: C/C++ Code, 1: C++ Class, 2: C++ Header File, 3: C++ Form, 4: C++ Control, 5: Text File, 6: DEF File, 7: IDL File, 8: Makefile, 9: RGS File, 10: RC File, 11: RES File, 12: XSD File, 13: XML File, 14: HTML File, 15: CSS File, 16: Bitmap, 17: Icon, 18: Resx File, 19: BSC File, 20: XSX File, 21: C++ Web Service, 22: ASAX File, 23: Asp Page, 24: Document, 25: Discovery File, 26: C# File, 27: eFileTypeClassDiagram, 28: MHTML Document, 29: Property Sheet, 30: Cursor, 31: Manifest, 32: eFileTypeRDLC """ return '' def write(self): Logs.debug('msvs: creating %r', self.path) template1 = compile_template(self.project_template) proj_str = template1(self) proj_str = rm_blank_lines(proj_str) self.path.stealth_write(proj_str) return dec class msvs_2008_generator(msvs_generator): '''generates a visual studio 2008 solution''' cmd = 'msvs2008' fun = msvs_generator.fun numver = '10.00' vsver = '2008' def init(self): if not getattr(self, 'project_extension', None): self.project_extension = '_2008.vcproj' if not getattr(self, 'solution_name', None): self.solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '_2008.sln' if not getattr(self, 'vsnode_target', None): self.vsnode_target = wrap_2008(vsnode_target) if not getattr(self, 'vsnode_build_all', None): self.vsnode_build_all = wrap_2008(vsnode_build_all) if not getattr(self, 'vsnode_install_all', None): self.vsnode_install_all = wrap_2008(vsnode_install_all) if not getattr(self, 'vsnode_project_view', None): self.vsnode_project_view = wrap_2008(vsnode_project_view) msvs_generator.init(self) def options(ctx): """ If the msvs option is used, try to detect if the build is made from visual studio """ ctx.add_option('--execsolution', action='store', help='when building with visual studio, use a build state file') old = BuildContext.execute def override_build_state(ctx): def lock(rm, add): uns = ctx.options.execsolution.replace('.sln', rm) uns = ctx.root.make_node(uns) try: uns.delete() except OSError: pass uns = ctx.options.execsolution.replace('.sln', add) uns = ctx.root.make_node(uns) try: uns.write('') except EnvironmentError: pass if ctx.options.execsolution: ctx.launch_dir = Context.top_dir # force a build for the whole project (invalid cwd when called by visual studio) lock('.lastbuildstate', '.unsuccessfulbuild') old(ctx) lock('.unsuccessfulbuild', '.lastbuildstate') else: old(ctx) BuildContext.execute = override_build_state ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py0000660000000000000000000002160713573675414023605 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011-2015 (ita) """ A client for the network cache (playground/netcache/). Launch the server with: ./netcache_server, then use it for the builds by adding the following: def build(bld): bld.load('netcache_client') The parameters should be present in the environment in the form: NETCACHE=host:port waf configure build Or in a more detailed way: NETCACHE_PUSH=host:port NETCACHE_PULL=host:port waf configure build where: host: host where the server resides, by default localhost port: by default push on 11001 and pull on 12001 Use the server provided in playground/netcache/Netcache.java """ import os, socket, time, atexit, sys from waflib import Task, Logs, Utils, Build, Runner from waflib.Configure import conf BUF = 8192 * 16 HEADER_SIZE = 128 MODES = ['PUSH', 'PULL', 'PUSH_PULL'] STALE_TIME = 30 # seconds GET = 'GET' PUT = 'PUT' LST = 'LST' BYE = 'BYE' all_sigs_in_cache = (0.0, []) def put_data(conn, data): if sys.hexversion > 0x3000000: data = data.encode('latin-1') cnt = 0 while cnt < len(data): sent = conn.send(data[cnt:]) if sent == 0: raise RuntimeError('connection ended') cnt += sent push_connections = Runner.Queue(0) pull_connections = Runner.Queue(0) def get_connection(push=False): # return a new connection... do not forget to release it! try: if push: ret = push_connections.get(block=False) else: ret = pull_connections.get(block=False) except Exception: ret = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if push: ret.connect(Task.push_addr) else: ret.connect(Task.pull_addr) return ret def release_connection(conn, msg='', push=False): if conn: if push: push_connections.put(conn) else: pull_connections.put(conn) def close_connection(conn, msg=''): if conn: data = '%s,%s' % (BYE, msg) try: put_data(conn, data.ljust(HEADER_SIZE)) except: pass try: conn.close() except: pass def close_all(): for q in (push_connections, pull_connections): while q.qsize(): conn = q.get() try: close_connection(conn) except: # ignore errors when cleaning up pass atexit.register(close_all) def read_header(conn): cnt = 0 buf = [] while cnt < HEADER_SIZE: data = conn.recv(HEADER_SIZE - cnt) if not data: #import traceback #traceback.print_stack() raise ValueError('connection ended when reading a header %r' % buf) buf.append(data) cnt += len(data) if sys.hexversion > 0x3000000: ret = ''.encode('latin-1').join(buf) ret = ret.decode('latin-1') else: ret = ''.join(buf) return ret def check_cache(conn, ssig): """ List the files on the server, this is an optimization because it assumes that concurrent builds are rare """ global all_sigs_in_cache if not STALE_TIME: return if time.time() - all_sigs_in_cache[0] > STALE_TIME: params = (LST,'') put_data(conn, ','.join(params).ljust(HEADER_SIZE)) # read what is coming back ret = read_header(conn) size = int(ret.split(',')[0]) buf = [] cnt = 0 while cnt < size: data = conn.recv(min(BUF, size-cnt)) if not data: raise ValueError('connection ended %r %r' % (cnt, size)) buf.append(data) cnt += len(data) if sys.hexversion > 0x3000000: ret = ''.encode('latin-1').join(buf) ret = ret.decode('latin-1') else: ret = ''.join(buf) all_sigs_in_cache = (time.time(), ret.splitlines()) Logs.debug('netcache: server cache has %r entries', len(all_sigs_in_cache[1])) if not ssig in all_sigs_in_cache[1]: raise ValueError('no file %s in cache' % ssig) class MissingFile(Exception): pass def recv_file(conn, ssig, count, p): check_cache(conn, ssig) params = (GET, ssig, str(count)) put_data(conn, ','.join(params).ljust(HEADER_SIZE)) data = read_header(conn) size = int(data.split(',')[0]) if size == -1: raise MissingFile('no file %s - %s in cache' % (ssig, count)) # get the file, writing immediately # TODO a tmp file would be better f = open(p, 'wb') cnt = 0 while cnt < size: data = conn.recv(min(BUF, size-cnt)) if not data: raise ValueError('connection ended %r %r' % (cnt, size)) f.write(data) cnt += len(data) f.close() def sock_send(conn, ssig, cnt, p): #print "pushing %r %r %r" % (ssig, cnt, p) size = os.stat(p).st_size params = (PUT, ssig, str(cnt), str(size)) put_data(conn, ','.join(params).ljust(HEADER_SIZE)) f = open(p, 'rb') cnt = 0 while cnt < size: r = f.read(min(BUF, size-cnt)) while r: k = conn.send(r) if not k: raise ValueError('connection ended') cnt += k r = r[k:] def can_retrieve_cache(self): if not Task.pull_addr: return False if not self.outputs: return False self.cached = False cnt = 0 sig = self.signature() ssig = Utils.to_hex(self.uid() + sig) conn = None err = False try: try: conn = get_connection() for node in self.outputs: p = node.abspath() recv_file(conn, ssig, cnt, p) cnt += 1 except MissingFile as e: Logs.debug('netcache: file is not in the cache %r', e) err = True except Exception as e: Logs.debug('netcache: could not get the files %r', self.outputs) if Logs.verbose > 1: Logs.debug('netcache: exception %r', e) err = True # broken connection? remove this one close_connection(conn) conn = None else: Logs.debug('netcache: obtained %r from cache', self.outputs) finally: release_connection(conn) if err: return False self.cached = True return True @Utils.run_once def put_files_cache(self): if not Task.push_addr: return if not self.outputs: return if getattr(self, 'cached', None): return #print "called put_files_cache", id(self) bld = self.generator.bld sig = self.signature() ssig = Utils.to_hex(self.uid() + sig) conn = None cnt = 0 try: for node in self.outputs: # We could re-create the signature of the task with the signature of the outputs # in practice, this means hashing the output files # this is unnecessary try: if not conn: conn = get_connection(push=True) sock_send(conn, ssig, cnt, node.abspath()) Logs.debug('netcache: sent %r', node) except Exception as e: Logs.debug('netcache: could not push the files %r', e) # broken connection? remove this one close_connection(conn) conn = None cnt += 1 finally: release_connection(conn, push=True) bld.task_sigs[self.uid()] = self.cache_sig def hash_env_vars(self, env, vars_lst): # reimplement so that the resulting hash does not depend on local paths if not env.table: env = env.parent if not env: return Utils.SIG_NIL idx = str(id(env)) + str(vars_lst) try: cache = self.cache_env except AttributeError: cache = self.cache_env = {} else: try: return self.cache_env[idx] except KeyError: pass v = str([env[a] for a in vars_lst]) v = v.replace(self.srcnode.abspath().__repr__()[:-1], '') m = Utils.md5() m.update(v.encode()) ret = m.digest() Logs.debug('envhash: %r %r', ret, v) cache[idx] = ret return ret def uid(self): # reimplement so that the signature does not depend on local paths try: return self.uid_ except AttributeError: m = Utils.md5() src = self.generator.bld.srcnode up = m.update up(self.__class__.__name__.encode()) for x in self.inputs + self.outputs: up(x.path_from(src).encode()) self.uid_ = m.digest() return self.uid_ def make_cached(cls): if getattr(cls, 'nocache', None): return m1 = cls.run def run(self): if getattr(self, 'nocache', False): return m1(self) if self.can_retrieve_cache(): return 0 return m1(self) cls.run = run m2 = cls.post_run def post_run(self): if getattr(self, 'nocache', False): return m2(self) bld = self.generator.bld ret = m2(self) if bld.cache_global: self.put_files_cache() if hasattr(self, 'chmod'): for node in self.outputs: os.chmod(node.abspath(), self.chmod) return ret cls.post_run = post_run @conf def setup_netcache(ctx, push_addr, pull_addr): Task.Task.can_retrieve_cache = can_retrieve_cache Task.Task.put_files_cache = put_files_cache Task.Task.uid = uid Task.push_addr = push_addr Task.pull_addr = pull_addr Build.BuildContext.hash_env_vars = hash_env_vars ctx.cache_global = True for x in Task.classes.values(): make_cached(x) def build(bld): if not 'NETCACHE' in os.environ and not 'NETCACHE_PULL' in os.environ and not 'NETCACHE_PUSH' in os.environ: Logs.warn('Setting NETCACHE_PULL=127.0.0.1:11001 and NETCACHE_PUSH=127.0.0.1:12001') os.environ['NETCACHE_PULL'] = '127.0.0.1:12001' os.environ['NETCACHE_PUSH'] = '127.0.0.1:11001' if 'NETCACHE' in os.environ: if not 'NETCACHE_PUSH' in os.environ: os.environ['NETCACHE_PUSH'] = os.environ['NETCACHE'] if not 'NETCACHE_PULL' in os.environ: os.environ['NETCACHE_PULL'] = os.environ['NETCACHE'] v = os.environ['NETCACHE_PULL'] if v: h, p = v.split(':') pull_addr = (h, int(p)) else: pull_addr = None v = os.environ['NETCACHE_PUSH'] if v: h, p = v.split(':') push_addr = (h, int(p)) else: push_addr = None setup_netcache(bld, push_addr, pull_addr) ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py0000660000000000000000000000352013573675414022134 0ustar rootroot00000000000000#!/usr/bin/python # Grygoriy Fuchedzhy 2010 """ Support for converting linked targets to ihex, srec or binary files using objcopy. Use the 'objcopy' feature in conjunction with the 'cc' or 'cxx' feature. The 'objcopy' feature uses the following attributes: objcopy_bfdname Target object format name (eg. ihex, srec, binary). Defaults to ihex. objcopy_target File name used for objcopy output. This defaults to the target name with objcopy_bfdname as extension. objcopy_install_path Install path for objcopy_target file. Defaults to ${PREFIX}/fw. objcopy_flags Additional flags passed to objcopy. """ from waflib.Utils import def_attrs from waflib import Task, Options from waflib.TaskGen import feature, after_method class objcopy(Task.Task): run_str = '${OBJCOPY} -O ${TARGET_BFDNAME} ${OBJCOPYFLAGS} ${SRC} ${TGT}' color = 'CYAN' @feature('objcopy') @after_method('apply_link') def map_objcopy(self): def_attrs(self, objcopy_bfdname = 'ihex', objcopy_target = None, objcopy_install_path = "${PREFIX}/firmware", objcopy_flags = '') link_output = self.link_task.outputs[0] if not self.objcopy_target: self.objcopy_target = link_output.change_ext('.' + self.objcopy_bfdname).name task = self.create_task('objcopy', src=link_output, tgt=self.path.find_or_declare(self.objcopy_target)) task.env.append_unique('TARGET_BFDNAME', self.objcopy_bfdname) try: task.env.append_unique('OBJCOPYFLAGS', getattr(self, 'objcopy_flags')) except AttributeError: pass if self.objcopy_install_path: self.add_install_files(install_to=self.objcopy_install_path, install_from=task.outputs[0]) def configure(ctx): program_name = 'objcopy' prefix = getattr(Options.options, 'cross_prefix', None) if prefix: program_name = '{}-{}'.format(prefix, program_name) ctx.find_program(program_name, var='OBJCOPY', mandatory=True) ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py0000660000000000000000000002247013573675414021567 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) "ocaml support" import os, re from waflib import Utils, Task from waflib.Logs import error from waflib.TaskGen import feature, before_method, after_method, extension EXT_MLL = ['.mll'] EXT_MLY = ['.mly'] EXT_MLI = ['.mli'] EXT_MLC = ['.c'] EXT_ML = ['.ml'] open_re = re.compile(r'^\s*open\s+([a-zA-Z]+)(;;){0,1}$', re.M) foo = re.compile(r"""(\(\*)|(\*\))|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^()*"'\\]*)""", re.M) def filter_comments(txt): meh = [0] def repl(m): if m.group(1): meh[0] += 1 elif m.group(2): meh[0] -= 1 elif not meh[0]: return m.group() return '' return foo.sub(repl, txt) def scan(self): node = self.inputs[0] code = filter_comments(node.read()) global open_re names = [] import_iterator = open_re.finditer(code) if import_iterator: for import_match in import_iterator: names.append(import_match.group(1)) found_lst = [] raw_lst = [] for name in names: nd = None for x in self.incpaths: nd = x.find_resource(name.lower()+'.ml') if not nd: nd = x.find_resource(name+'.ml') if nd: found_lst.append(nd) break else: raw_lst.append(name) return (found_lst, raw_lst) native_lst=['native', 'all', 'c_object'] bytecode_lst=['bytecode', 'all'] @feature('ocaml') def init_ml(self): Utils.def_attrs(self, type = 'all', incpaths_lst = [], bld_incpaths_lst = [], mlltasks = [], mlytasks = [], mlitasks = [], native_tasks = [], bytecode_tasks = [], linktasks = [], bytecode_env = None, native_env = None, compiled_tasks = [], includes = '', uselib = '', are_deps_set = 0) @feature('ocaml') @after_method('init_ml') def init_envs_ml(self): self.islibrary = getattr(self, 'islibrary', False) global native_lst, bytecode_lst self.native_env = None if self.type in native_lst: self.native_env = self.env.derive() if self.islibrary: self.native_env['OCALINKFLAGS'] = '-a' self.bytecode_env = None if self.type in bytecode_lst: self.bytecode_env = self.env.derive() if self.islibrary: self.bytecode_env['OCALINKFLAGS'] = '-a' if self.type == 'c_object': self.native_env.append_unique('OCALINKFLAGS_OPT', '-output-obj') @feature('ocaml') @before_method('apply_vars_ml') @after_method('init_envs_ml') def apply_incpaths_ml(self): inc_lst = self.includes.split() lst = self.incpaths_lst for dir in inc_lst: node = self.path.find_dir(dir) if not node: error("node not found: " + str(dir)) continue if not node in lst: lst.append(node) self.bld_incpaths_lst.append(node) # now the nodes are added to self.incpaths_lst @feature('ocaml') @before_method('process_source') def apply_vars_ml(self): for i in self.incpaths_lst: if self.bytecode_env: app = self.bytecode_env.append_value app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()]) if self.native_env: app = self.native_env.append_value app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()]) varnames = ['INCLUDES', 'OCAMLFLAGS', 'OCALINKFLAGS', 'OCALINKFLAGS_OPT'] for name in self.uselib.split(): for vname in varnames: cnt = self.env[vname+'_'+name] if cnt: if self.bytecode_env: self.bytecode_env.append_value(vname, cnt) if self.native_env: self.native_env.append_value(vname, cnt) @feature('ocaml') @after_method('process_source') def apply_link_ml(self): if self.bytecode_env: ext = self.islibrary and '.cma' or '.run' linktask = self.create_task('ocalink') linktask.bytecode = 1 linktask.set_outputs(self.path.find_or_declare(self.target + ext)) linktask.env = self.bytecode_env self.linktasks.append(linktask) if self.native_env: if self.type == 'c_object': ext = '.o' elif self.islibrary: ext = '.cmxa' else: ext = '' linktask = self.create_task('ocalinkx') linktask.set_outputs(self.path.find_or_declare(self.target + ext)) linktask.env = self.native_env self.linktasks.append(linktask) # we produce a .o file to be used by gcc self.compiled_tasks.append(linktask) @extension(*EXT_MLL) def mll_hook(self, node): mll_task = self.create_task('ocamllex', node, node.change_ext('.ml')) mll_task.env = self.native_env.derive() self.mlltasks.append(mll_task) self.source.append(mll_task.outputs[0]) @extension(*EXT_MLY) def mly_hook(self, node): mly_task = self.create_task('ocamlyacc', node, [node.change_ext('.ml'), node.change_ext('.mli')]) mly_task.env = self.native_env.derive() self.mlytasks.append(mly_task) self.source.append(mly_task.outputs[0]) task = self.create_task('ocamlcmi', mly_task.outputs[1], mly_task.outputs[1].change_ext('.cmi')) task.env = self.native_env.derive() @extension(*EXT_MLI) def mli_hook(self, node): task = self.create_task('ocamlcmi', node, node.change_ext('.cmi')) task.env = self.native_env.derive() self.mlitasks.append(task) @extension(*EXT_MLC) def mlc_hook(self, node): task = self.create_task('ocamlcc', node, node.change_ext('.o')) task.env = self.native_env.derive() self.compiled_tasks.append(task) @extension(*EXT_ML) def ml_hook(self, node): if self.native_env: task = self.create_task('ocamlx', node, node.change_ext('.cmx')) task.env = self.native_env.derive() task.incpaths = self.bld_incpaths_lst self.native_tasks.append(task) if self.bytecode_env: task = self.create_task('ocaml', node, node.change_ext('.cmo')) task.env = self.bytecode_env.derive() task.bytecode = 1 task.incpaths = self.bld_incpaths_lst self.bytecode_tasks.append(task) def compile_may_start(self): if not getattr(self, 'flag_deps', ''): self.flag_deps = 1 # the evil part is that we can only compute the dependencies after the # source files can be read (this means actually producing the source files) if getattr(self, 'bytecode', ''): alltasks = self.generator.bytecode_tasks else: alltasks = self.generator.native_tasks self.signature() # ensure that files are scanned - unfortunately tree = self.generator.bld for node in self.inputs: lst = tree.node_deps[self.uid()] for depnode in lst: for t in alltasks: if t == self: continue if depnode in t.inputs: self.set_run_after(t) # TODO necessary to get the signature right - for now delattr(self, 'cache_sig') self.signature() return Task.Task.runnable_status(self) class ocamlx(Task.Task): """native caml compilation""" color = 'GREEN' run_str = '${OCAMLOPT} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}' scan = scan runnable_status = compile_may_start class ocaml(Task.Task): """bytecode caml compilation""" color = 'GREEN' run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}' scan = scan runnable_status = compile_may_start class ocamlcmi(Task.Task): """interface generator (the .i files?)""" color = 'BLUE' run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLINCLUDES} -o ${TGT} -c ${SRC}' before = ['ocamlcc', 'ocaml', 'ocamlcc'] class ocamlcc(Task.Task): """ocaml to c interfaces""" color = 'GREEN' run_str = 'cd ${TGT[0].bld_dir()} && ${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLPATH} ${OCAMLINCLUDES} -c ${SRC[0].abspath()}' class ocamllex(Task.Task): """lexical generator""" color = 'BLUE' run_str = '${OCAMLLEX} ${SRC} -o ${TGT}' before = ['ocamlcmi', 'ocaml', 'ocamlcc'] class ocamlyacc(Task.Task): """parser generator""" color = 'BLUE' run_str = '${OCAMLYACC} -b ${tsk.base()} ${SRC}' before = ['ocamlcmi', 'ocaml', 'ocamlcc'] def base(self): node = self.outputs[0] s = os.path.splitext(node.name)[0] return node.bld_dir() + os.sep + s def link_may_start(self): if getattr(self, 'bytecode', 0): alltasks = self.generator.bytecode_tasks else: alltasks = self.generator.native_tasks for x in alltasks: if not x.hasrun: return Task.ASK_LATER if not getattr(self, 'order', ''): # now reorder the inputs given the task dependencies # this part is difficult, we do not have a total order on the tasks # if the dependencies are wrong, this may not stop seen = [] pendant = []+alltasks while pendant: task = pendant.pop(0) if task in seen: continue for x in task.run_after: if not x in seen: pendant.append(task) break else: seen.append(task) self.inputs = [x.outputs[0] for x in seen] self.order = 1 return Task.Task.runnable_status(self) class ocalink(Task.Task): """bytecode caml link""" color = 'YELLOW' run_str = '${OCAMLC} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS} ${SRC}' runnable_status = link_may_start after = ['ocaml', 'ocamlcc'] class ocalinkx(Task.Task): """native caml link""" color = 'YELLOW' run_str = '${OCAMLOPT} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS_OPT} ${SRC}' runnable_status = link_may_start after = ['ocamlx', 'ocamlcc'] def configure(conf): opt = conf.find_program('ocamlopt', var='OCAMLOPT', mandatory=False) occ = conf.find_program('ocamlc', var='OCAMLC', mandatory=False) if (not opt) or (not occ): conf.fatal('The objective caml compiler was not found:\ninstall it or make it available in your PATH') v = conf.env v['OCAMLC'] = occ v['OCAMLOPT'] = opt v['OCAMLLEX'] = conf.find_program('ocamllex', var='OCAMLLEX', mandatory=False) v['OCAMLYACC'] = conf.find_program('ocamlyacc', var='OCAMLYACC', mandatory=False) v['OCAMLFLAGS'] = '' where = conf.cmd_and_log(conf.env.OCAMLC + ['-where']).strip()+os.sep v['OCAMLLIB'] = where v['LIBPATH_OCAML'] = where v['INCLUDES_OCAML'] = where v['LIB_OCAML'] = 'camlrun' ldb-2.0.8/third_party/waf/waflib/extras/package.py0000660000000000000000000000306613573675414022067 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 """ Obtain packages, unpack them in a location, and add associated uselib variables (CFLAGS_pkgname, LIBPATH_pkgname, etc). The default is use a Dependencies.txt file in the source directory. This is a work in progress. Usage: def options(opt): opt.load('package') def configure(conf): conf.load_packages() """ from waflib import Logs from waflib.Configure import conf try: from urllib import request except ImportError: from urllib import urlopen else: urlopen = request.urlopen CACHEVAR = 'WAFCACHE_PACKAGE' @conf def get_package_cache_dir(self): cache = None if CACHEVAR in conf.environ: cache = conf.environ[CACHEVAR] cache = self.root.make_node(cache) elif self.env[CACHEVAR]: cache = self.env[CACHEVAR] cache = self.root.make_node(cache) else: cache = self.srcnode.make_node('.wafcache_package') cache.mkdir() return cache @conf def download_archive(self, src, dst): for x in self.env.PACKAGE_REPO: url = '/'.join((x, src)) try: web = urlopen(url) try: if web.getcode() != 200: continue except AttributeError: pass except Exception: # on python3 urlopen throws an exception # python 2.3 does not have getcode and throws an exception to fail continue else: tmp = self.root.make_node(dst) tmp.write(web.read()) Logs.warn('Downloaded %s from %s', tmp.abspath(), url) break else: self.fatal('Could not get the package %s' % src) @conf def load_packages(self): self.get_package_cache_dir() # read the dependencies, get the archives, .. ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py0000660000000000000000000002744313573675414023443 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2007-2010 (ita) """ Debugging helper for parallel compilation. Copy it to your project and load it with:: def options(opt): opt.load('parallel_debug', tooldir='.') def build(bld): ... The build will then output a file named pdebug.svg in the source directory. """ import re, sys, threading, time, traceback try: from Queue import Queue except: from queue import Queue from waflib import Runner, Options, Task, Logs, Errors SVG_TEMPLATE = """ ${if project.title} ${project.title} ${endif} ${for cls in project.groups} ${for rect in cls.rects} ${endfor} ${endfor} ${for info in project.infos} ${info.text} ${endfor} ${if project.tooltip} ${endif} """ COMPILE_TEMPLATE = '''def f(project): lst = [] def xml_escape(value): return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") %s return ''.join(lst) ''' reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) def compile_template(line): extr = [] def repl(match): g = match.group if g('dollar'): return "$" elif g('backslash'): return "\\" elif g('subst'): extr.append(g('code')) return "<<|@|>>" return None line2 = reg_act.sub(repl, line) params = line2.split('<<|@|>>') assert(extr) indent = 0 buf = [] app = buf.append def app(txt): buf.append(indent * '\t' + txt) for x in range(len(extr)): if params[x]: app("lst.append(%r)" % params[x]) f = extr[x] if f.startswith(('if', 'for')): app(f + ':') indent += 1 elif f.startswith('py:'): app(f[3:]) elif f.startswith(('endif', 'endfor')): indent -= 1 elif f.startswith(('else', 'elif')): indent -= 1 app(f + ':') indent += 1 elif f.startswith('xml:'): app('lst.append(xml_escape(%s))' % f[4:]) else: #app('lst.append((%s) or "cannot find %s")' % (f, f)) app('lst.append(str(%s))' % f) if extr: if params[-1]: app("lst.append(%r)" % params[-1]) fun = COMPILE_TEMPLATE % "\n\t".join(buf) # uncomment the following to debug the template #for i, x in enumerate(fun.splitlines()): # print i, x return Task.funex(fun) # red #ff4d4d # green #4da74d # lila #a751ff color2code = { 'GREEN' : '#4da74d', 'YELLOW' : '#fefe44', 'PINK' : '#a751ff', 'RED' : '#cc1d1d', 'BLUE' : '#6687bb', 'CYAN' : '#34e2e2', } mp = {} info = [] # list of (text,color) def map_to_color(name): if name in mp: return mp[name] try: cls = Task.classes[name] except KeyError: return color2code['RED'] if cls.color in mp: return mp[cls.color] if cls.color in color2code: return color2code[cls.color] return color2code['RED'] def process(self): m = self.generator.bld.producer try: # TODO another place for this? del self.generator.bld.task_sigs[self.uid()] except KeyError: pass self.generator.bld.producer.set_running(1, self) try: ret = self.run() except Exception: self.err_msg = traceback.format_exc() self.hasrun = Task.EXCEPTION # TODO cleanup m.error_handler(self) return if ret: self.err_code = ret self.hasrun = Task.CRASHED else: try: self.post_run() except Errors.WafError: pass except Exception: self.err_msg = traceback.format_exc() self.hasrun = Task.EXCEPTION else: self.hasrun = Task.SUCCESS if self.hasrun != Task.SUCCESS: m.error_handler(self) self.generator.bld.producer.set_running(-1, self) Task.Task.process_back = Task.Task.process Task.Task.process = process old_start = Runner.Parallel.start def do_start(self): try: Options.options.dband except AttributeError: self.bld.fatal('use def options(opt): opt.load("parallel_debug")!') self.taskinfo = Queue() old_start(self) if self.dirty: make_picture(self) Runner.Parallel.start = do_start lock_running = threading.Lock() def set_running(self, by, tsk): with lock_running: try: cache = self.lock_cache except AttributeError: cache = self.lock_cache = {} i = 0 if by > 0: vals = cache.values() for i in range(self.numjobs): if i not in vals: cache[tsk] = i break else: i = cache[tsk] del cache[tsk] self.taskinfo.put( (i, id(tsk), time.time(), tsk.__class__.__name__, self.processed, self.count, by, ",".join(map(str, tsk.outputs))) ) Runner.Parallel.set_running = set_running def name2class(name): return name.replace(' ', '_').replace('.', '_') def make_picture(producer): # first, cast the parameters if not hasattr(producer.bld, 'path'): return tmp = [] try: while True: tup = producer.taskinfo.get(False) tmp.append(list(tup)) except: pass try: ini = float(tmp[0][2]) except: return if not info: seen = [] for x in tmp: name = x[3] if not name in seen: seen.append(name) else: continue info.append((name, map_to_color(name))) info.sort(key=lambda x: x[0]) thread_count = 0 acc = [] for x in tmp: thread_count += x[6] acc.append("%d %d %f %r %d %d %d %s" % (x[0], x[1], x[2] - ini, x[3], x[4], x[5], thread_count, x[7])) data_node = producer.bld.path.make_node('pdebug.dat') data_node.write('\n'.join(acc)) tmp = [lst[:2] + [float(lst[2]) - ini] + lst[3:] for lst in tmp] st = {} for l in tmp: if not l[0] in st: st[l[0]] = len(st.keys()) tmp = [ [st[lst[0]]] + lst[1:] for lst in tmp ] THREAD_AMOUNT = len(st.keys()) st = {} for l in tmp: if not l[1] in st: st[l[1]] = len(st.keys()) tmp = [ [lst[0]] + [st[lst[1]]] + lst[2:] for lst in tmp ] BAND = Options.options.dband seen = {} acc = [] for x in range(len(tmp)): line = tmp[x] id = line[1] if id in seen: continue seen[id] = True begin = line[2] thread_id = line[0] for y in range(x + 1, len(tmp)): line = tmp[y] if line[1] == id: end = line[2] #print id, thread_id, begin, end #acc.append( ( 10*thread_id, 10*(thread_id+1), 10*begin, 10*end ) ) acc.append( (BAND * begin, BAND*thread_id, BAND*end - BAND*begin, BAND, line[3], line[7]) ) break if Options.options.dmaxtime < 0.1: gwidth = 1 for x in tmp: m = BAND * x[2] if m > gwidth: gwidth = m else: gwidth = BAND * Options.options.dmaxtime ratio = float(Options.options.dwidth) / gwidth gwidth = Options.options.dwidth gheight = BAND * (THREAD_AMOUNT + len(info) + 1.5) # simple data model for our template class tobject(object): pass model = tobject() model.x = 0 model.y = 0 model.width = gwidth + 4 model.height = gheight + 4 model.tooltip = not Options.options.dnotooltip model.title = Options.options.dtitle model.title_x = gwidth / 2 model.title_y = gheight + - 5 groups = {} for (x, y, w, h, clsname, name) in acc: try: groups[clsname].append((x, y, w, h, name)) except: groups[clsname] = [(x, y, w, h, name)] # groups of rectangles (else js highlighting is slow) model.groups = [] for cls in groups: g = tobject() model.groups.append(g) g.classname = name2class(cls) g.rects = [] for (x, y, w, h, name) in groups[cls]: r = tobject() g.rects.append(r) r.x = 2 + x * ratio r.y = 2 + y r.width = w * ratio r.height = h r.name = name r.color = map_to_color(cls) cnt = THREAD_AMOUNT # caption model.infos = [] for (text, color) in info: inf = tobject() model.infos.append(inf) inf.classname = name2class(text) inf.x = 2 + BAND inf.y = 5 + (cnt + 0.5) * BAND inf.width = BAND/2 inf.height = BAND/2 inf.color = color inf.text = text inf.text_x = 2 + 2 * BAND inf.text_y = 5 + (cnt + 0.5) * BAND + 10 cnt += 1 # write the file... template1 = compile_template(SVG_TEMPLATE) txt = template1(model) node = producer.bld.path.make_node('pdebug.svg') node.write(txt) Logs.warn('Created the diagram %r', node) def options(opt): opt.add_option('--dtitle', action='store', default='Parallel build representation for %r' % ' '.join(sys.argv), help='title for the svg diagram', dest='dtitle') opt.add_option('--dwidth', action='store', type='int', help='diagram width', default=800, dest='dwidth') opt.add_option('--dtime', action='store', type='float', help='recording interval in seconds', default=0.009, dest='dtime') opt.add_option('--dband', action='store', type='int', help='band width', default=22, dest='dband') opt.add_option('--dmaxtime', action='store', type='float', help='maximum time, for drawing fair comparisons', default=0, dest='dmaxtime') opt.add_option('--dnotooltip', action='store_true', help='disable tooltips', default=False, dest='dnotooltip') ldb-2.0.8/third_party/waf/waflib/extras/pch.py0000660000000000000000000001051413573675414021242 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Alexander Afanasyev (UCLA), 2014 """ Enable precompiled C++ header support (currently only clang++ and g++ are supported) To use this tool, wscript should look like: def options(opt): opt.load('pch') # This will add `--with-pch` configure option. # Unless --with-pch during configure stage specified, the precompiled header support is disabled def configure(conf): conf.load('pch') # this will set conf.env.WITH_PCH if --with-pch is specified and the supported compiler is used # Unless conf.env.WITH_PCH is set, the precompiled header support is disabled def build(bld): bld(features='cxx pch', target='precompiled-headers', name='precompiled-headers', headers='a.h b.h c.h', # headers to pre-compile into `precompiled-headers` # Other parameters to compile precompiled headers # includes=..., # export_includes=..., # use=..., # ... # Exported parameters will be propagated even if precompiled headers are disabled ) bld( target='test', features='cxx cxxprogram', source='a.cpp b.cpp d.cpp main.cpp', use='precompiled-headers', ) # or bld( target='test', features='pch cxx cxxprogram', source='a.cpp b.cpp d.cpp main.cpp', headers='a.h b.h c.h', ) Note that precompiled header must have multiple inclusion guards. If the guards are missing, any benefit of precompiled header will be voided and compilation may fail in some cases. """ import os from waflib import Task, TaskGen, Utils from waflib.Tools import c_preproc, cxx PCH_COMPILER_OPTIONS = { 'clang++': [['-include'], '.pch', ['-x', 'c++-header']], 'g++': [['-include'], '.gch', ['-x', 'c++-header']], } def options(opt): opt.add_option('--without-pch', action='store_false', default=True, dest='with_pch', help='''Try to use precompiled header to speed up compilation (only g++ and clang++)''') def configure(conf): if (conf.options.with_pch and conf.env['COMPILER_CXX'] in PCH_COMPILER_OPTIONS.keys()): conf.env.WITH_PCH = True flags = PCH_COMPILER_OPTIONS[conf.env['COMPILER_CXX']] conf.env.CXXPCH_F = flags[0] conf.env.CXXPCH_EXT = flags[1] conf.env.CXXPCH_FLAGS = flags[2] @TaskGen.feature('pch') @TaskGen.before('process_source') def apply_pch(self): if not self.env.WITH_PCH: return if getattr(self.bld, 'pch_tasks', None) is None: self.bld.pch_tasks = {} if getattr(self, 'headers', None) is None: return self.headers = self.to_nodes(self.headers) if getattr(self, 'name', None): try: task = self.bld.pch_tasks["%s.%s" % (self.name, self.idx)] self.bld.fatal("Duplicated 'pch' task with name %r" % "%s.%s" % (self.name, self.idx)) except KeyError: pass out = '%s.%d%s' % (self.target, self.idx, self.env['CXXPCH_EXT']) out = self.path.find_or_declare(out) task = self.create_task('gchx', self.headers, out) # target should be an absolute path of `out`, but without precompiled header extension task.target = out.abspath()[:-len(out.suffix())] self.pch_task = task if getattr(self, 'name', None): self.bld.pch_tasks["%s.%s" % (self.name, self.idx)] = task @TaskGen.feature('cxx') @TaskGen.after_method('process_source', 'propagate_uselib_vars') def add_pch(self): if not (self.env['WITH_PCH'] and getattr(self, 'use', None) and getattr(self, 'compiled_tasks', None) and getattr(self.bld, 'pch_tasks', None)): return pch = None # find pch task, if any if getattr(self, 'pch_task', None): pch = self.pch_task else: for use in Utils.to_list(self.use): try: pch = self.bld.pch_tasks[use] except KeyError: pass if pch: for x in self.compiled_tasks: x.env.append_value('CXXFLAGS', self.env['CXXPCH_F'] + [pch.target]) class gchx(Task.Task): run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CXXPCH_FLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXXPCH_F:SRC} ${CXX_SRC_F}${SRC[0].abspath()} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' scan = c_preproc.scan color = 'BLUE' ext_out=['.h'] def runnable_status(self): try: node_deps = self.generator.bld.node_deps[self.uid()] except KeyError: node_deps = [] ret = Task.Task.runnable_status(self) if ret == Task.SKIP_ME and self.env.CXX_NAME == 'clang': t = os.stat(self.outputs[0].abspath()).st_mtime for n in self.inputs + node_deps: if os.stat(n.abspath()).st_mtime > t: return Task.RUN_ME return ret ldb-2.0.8/third_party/waf/waflib/extras/pep8.py0000660000000000000000000000662413573675414021353 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # # written by Sylvain Rouquette, 2011 ''' Install pep8 module: $ easy_install pep8 or $ pip install pep8 To add the pep8 tool to the waf file: $ ./waf-light --tools=compat15,pep8 or, if you have waf >= 1.6.2 $ ./waf update --files=pep8 Then add this to your wscript: [at]extension('.py', 'wscript') def run_pep8(self, node): self.create_task('Pep8', node) ''' import threading from waflib import Task, Options pep8 = __import__('pep8') class Pep8(Task.Task): color = 'PINK' lock = threading.Lock() def check_options(self): if pep8.options: return pep8.options = Options.options pep8.options.prog = 'pep8' excl = pep8.options.exclude.split(',') pep8.options.exclude = [s.rstrip('/') for s in excl] if pep8.options.filename: pep8.options.filename = pep8.options.filename.split(',') if pep8.options.select: pep8.options.select = pep8.options.select.split(',') else: pep8.options.select = [] if pep8.options.ignore: pep8.options.ignore = pep8.options.ignore.split(',') elif pep8.options.select: # Ignore all checks which are not explicitly selected pep8.options.ignore = [''] elif pep8.options.testsuite or pep8.options.doctest: # For doctest and testsuite, all checks are required pep8.options.ignore = [] else: # The default choice: ignore controversial checks pep8.options.ignore = pep8.DEFAULT_IGNORE.split(',') pep8.options.physical_checks = pep8.find_checks('physical_line') pep8.options.logical_checks = pep8.find_checks('logical_line') pep8.options.counters = dict.fromkeys(pep8.BENCHMARK_KEYS, 0) pep8.options.messages = {} def run(self): with Pep8.lock: self.check_options() pep8.input_file(self.inputs[0].abspath()) return 0 if not pep8.get_count() else -1 def options(opt): opt.add_option('-q', '--quiet', default=0, action='count', help="report only file names, or nothing with -qq") opt.add_option('-r', '--repeat', action='store_true', help="show all occurrences of the same error") opt.add_option('--exclude', metavar='patterns', default=pep8.DEFAULT_EXCLUDE, help="exclude files or directories which match these " "comma separated patterns (default: %s)" % pep8.DEFAULT_EXCLUDE, dest='exclude') opt.add_option('--filename', metavar='patterns', default='*.py', help="when parsing directories, only check filenames " "matching these comma separated patterns (default: " "*.py)") opt.add_option('--select', metavar='errors', default='', help="select errors and warnings (e.g. E,W6)") opt.add_option('--ignore', metavar='errors', default='', help="skip errors and warnings (e.g. E4,W)") opt.add_option('--show-source', action='store_true', help="show source code for each error") opt.add_option('--show-pep8', action='store_true', help="show text of PEP 8 for each error") opt.add_option('--statistics', action='store_true', help="count errors and warnings") opt.add_option('--count', action='store_true', help="print total number of errors and warnings " "to standard error and set exit code to 1 if " "total is not null") opt.add_option('--benchmark', action='store_true', help="measure processing speed") opt.add_option('--testsuite', metavar='dir', help="run regression tests from dir") opt.add_option('--doctest', action='store_true', help="run doctest on myself") ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py0000660000000000000000000000331313573675414021554 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Antoine Dechaume 2011 """ Detect the PGI C compiler """ import sys, re from waflib import Errors from waflib.Configure import conf from waflib.Tools.compiler_c import c_compiler c_compiler['linux'].append('pgicc') @conf def find_pgi_compiler(conf, var, name): """ Find the program name, and execute it to ensure it really is itself. """ if sys.platform == 'cygwin': conf.fatal('The PGI compiler does not work on Cygwin') v = conf.env cc = None if v[var]: cc = v[var] elif var in conf.environ: cc = conf.environ[var] if not cc: cc = conf.find_program(name, var=var) if not cc: conf.fatal('PGI Compiler (%s) was not found' % name) v[var + '_VERSION'] = conf.get_pgi_version(cc) v[var] = cc v[var + '_NAME'] = 'pgi' @conf def get_pgi_version(conf, cc): """Find the version of a pgi compiler.""" version_re = re.compile(r"The Portland Group", re.I).search cmd = cc + ['-V', '-E'] # Issue 1078, prevent wrappers from linking try: out, err = conf.cmd_and_log(cmd, output=0) except Errors.WafError: conf.fatal('Could not find pgi compiler %r' % cmd) if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not verify PGI signature') cmd = cc + ['-help=variable'] try: out, err = conf.cmd_and_log(cmd, output=0) except Errors.WafError: conf.fatal('Could not find pgi compiler %r' % cmd) version = re.findall(r'^COMPVER\s*=(.*)', out, re.M) if len(version) != 1: conf.fatal('Could not determine the compiler version') return version[0] def configure(conf): conf.find_pgi_compiler('CC', 'pgcc') conf.find_ar() conf.gcc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py0000660000000000000000000000061313573675414021771 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Antoine Dechaume 2011 """ Detect the PGI C++ compiler """ from waflib.Tools.compiler_cxx import cxx_compiler cxx_compiler['linux'].append('pgicxx') from waflib.extras import pgicc def configure(conf): conf.find_pgi_compiler('CXX', 'pgCC') conf.find_ar() conf.gxx_common_flags() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() ldb-2.0.8/third_party/waf/waflib/extras/proc.py0000660000000000000000000000327513573675414021441 0ustar rootroot00000000000000#! /usr/bin/env python # per rosengren 2011 from os import environ, path from waflib import TaskGen, Utils def options(opt): grp = opt.add_option_group('Oracle ProC Options') grp.add_option('--oracle_home', action='store', default=environ.get('PROC_ORACLE'), help='Path to Oracle installation home (has bin/lib)') grp.add_option('--tns_admin', action='store', default=environ.get('TNS_ADMIN'), help='Directory containing server list (TNS_NAMES.ORA)') grp.add_option('--connection', action='store', default='dummy-user/dummy-password@dummy-server', help='Format: user/password@server') def configure(cnf): env = cnf.env if not env.PROC_ORACLE: env.PROC_ORACLE = cnf.options.oracle_home if not env.PROC_TNS_ADMIN: env.PROC_TNS_ADMIN = cnf.options.tns_admin if not env.PROC_CONNECTION: env.PROC_CONNECTION = cnf.options.connection cnf.find_program('proc', var='PROC', path_list=env.PROC_ORACLE + path.sep + 'bin') def proc(tsk): env = tsk.env gen = tsk.generator inc_nodes = gen.to_incnodes(Utils.to_list(getattr(gen,'includes',[])) + env['INCLUDES']) cmd = ( [env.PROC] + ['SQLCHECK=SEMANTICS'] + (['SYS_INCLUDE=(' + ','.join(env.PROC_INCLUDES) + ')'] if env.PROC_INCLUDES else []) + ['INCLUDE=(' + ','.join( [i.bldpath() for i in inc_nodes] ) + ')'] + ['userid=' + env.PROC_CONNECTION] + ['INAME=' + tsk.inputs[0].bldpath()] + ['ONAME=' + tsk.outputs[0].bldpath()] ) exec_env = { 'ORACLE_HOME': env.PROC_ORACLE, 'LD_LIBRARY_PATH': env.PROC_ORACLE + path.sep + 'lib', } if env.PROC_TNS_ADMIN: exec_env['TNS_ADMIN'] = env.PROC_TNS_ADMIN return tsk.exec_command(cmd, env=exec_env) TaskGen.declare_chain( name = 'proc', rule = proc, ext_in = '.pc', ext_out = '.c', ) ldb-2.0.8/third_party/waf/waflib/extras/protoc.py0000660000000000000000000001533113573675414022000 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Philipp Bender, 2012 # Matt Clarkson, 2012 import re, os from waflib.Task import Task from waflib.TaskGen import extension from waflib import Errors, Context, Logs """ A simple tool to integrate protocol buffers into your build system. Example for C++: def configure(conf): conf.load('compiler_cxx cxx protoc') def build(bld): bld( features = 'cxx cxxprogram' source = 'main.cpp file1.proto proto/file2.proto', includes = '. proto', target = 'executable') Example for Python: def configure(conf): conf.load('python protoc') def build(bld): bld( features = 'py' source = 'main.py file1.proto proto/file2.proto', protoc_includes = 'proto') Example for both Python and C++ at same time: def configure(conf): conf.load('cxx python protoc') def build(bld): bld( features = 'cxx py' source = 'file1.proto proto/file2.proto', protoc_includes = 'proto') # or includes Example for Java: def options(opt): opt.load('java') def configure(conf): conf.load('python java protoc') # Here you have to point to your protobuf-java JAR and have it in classpath conf.env.CLASSPATH_PROTOBUF = ['protobuf-java-2.5.0.jar'] def build(bld): bld( features = 'javac protoc', name = 'pbjava', srcdir = 'inc/ src', # directories used by javac source = ['inc/message_inc.proto', 'inc/message.proto'], # source is used by protoc for .proto files use = 'PROTOBUF', protoc_includes = ['inc']) # for protoc to search dependencies Protoc includes passed via protoc_includes are either relative to the taskgen or to the project and are searched in this order. Include directories external to the waf project can also be passed to the extra by using protoc_extincludes protoc_extincludes = ['/usr/include/pblib'] Notes when using this tool: - protoc command line parsing is tricky. The generated files can be put in subfolders which depend on the order of the include paths. Try to be simple when creating task generators containing protoc stuff. """ class protoc(Task): run_str = '${PROTOC} ${PROTOC_FL:PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${PROTOC_ST:PROTOC_INCPATHS} ${PROTOC_ST:PROTOC_EXTINCPATHS} ${SRC[0].bldpath()}' color = 'BLUE' ext_out = ['.h', 'pb.cc', '.py', '.java'] def scan(self): """ Scan .proto dependencies """ node = self.inputs[0] nodes = [] names = [] seen = [] search_nodes = [] if not node: return (nodes, names) if 'cxx' in self.generator.features: search_nodes = self.generator.includes_nodes if 'py' in self.generator.features or 'javac' in self.generator.features: for incpath in getattr(self.generator, 'protoc_includes', []): incpath_node = self.generator.path.find_node(incpath) if incpath_node: search_nodes.append(incpath_node) else: # Check if relative to top-level for extra tg dependencies incpath_node = self.generator.bld.path.find_node(incpath) if incpath_node: search_nodes.append(incpath_node) else: raise Errors.WafError('protoc: include path %r does not exist' % incpath) def parse_node(node): if node in seen: return seen.append(node) code = node.read().splitlines() for line in code: m = re.search(r'^import\s+"(.*)";.*(//)?.*', line) if m: dep = m.groups()[0] for incnode in search_nodes: found = incnode.find_resource(dep) if found: nodes.append(found) parse_node(found) else: names.append(dep) parse_node(node) # Add also dependencies path to INCPATHS so protoc will find the included file for deppath in nodes: self.env.append_unique('INCPATHS', deppath.parent.bldpath()) return (nodes, names) @extension('.proto') def process_protoc(self, node): incdirs = [] out_nodes = [] protoc_flags = [] # ensure PROTOC_FLAGS is a list; a copy is used below anyway self.env.PROTOC_FLAGS = self.to_list(self.env.PROTOC_FLAGS) if 'cxx' in self.features: cpp_node = node.change_ext('.pb.cc') hpp_node = node.change_ext('.pb.h') self.source.append(cpp_node) out_nodes.append(cpp_node) out_nodes.append(hpp_node) protoc_flags.append('--cpp_out=%s' % node.parent.get_bld().bldpath()) if 'py' in self.features: py_node = node.change_ext('_pb2.py') self.source.append(py_node) out_nodes.append(py_node) protoc_flags.append('--python_out=%s' % node.parent.get_bld().bldpath()) if 'javac' in self.features: # Make javac get also pick java code generated in build if not node.parent.get_bld() in self.javac_task.srcdir: self.javac_task.srcdir.append(node.parent.get_bld()) protoc_flags.append('--java_out=%s' % node.parent.get_bld().bldpath()) node.parent.get_bld().mkdir() tsk = self.create_task('protoc', node, out_nodes) tsk.env.append_value('PROTOC_FLAGS', protoc_flags) if 'javac' in self.features: self.javac_task.set_run_after(tsk) # Instruct protoc where to search for .proto included files. # For C++ standard include files dirs are used, # but this doesn't apply to Python for example for incpath in getattr(self, 'protoc_includes', []): incpath_node = self.path.find_node(incpath) if incpath_node: incdirs.append(incpath_node.bldpath()) else: # Check if relative to top-level for extra tg dependencies incpath_node = self.bld.path.find_node(incpath) if incpath_node: incdirs.append(incpath_node.bldpath()) else: raise Errors.WafError('protoc: include path %r does not exist' % incpath) tsk.env.PROTOC_INCPATHS = incdirs # Include paths external to the waf project (ie. shared pb repositories) tsk.env.PROTOC_EXTINCPATHS = getattr(self, 'protoc_extincludes', []) # PR2115: protoc generates output of .proto files in nested # directories by canonicalizing paths. To avoid this we have to pass # as first include the full directory file of the .proto file tsk.env.prepend_value('INCPATHS', node.parent.bldpath()) use = getattr(self, 'use', '') if not 'PROTOBUF' in use: self.use = self.to_list(use) + ['PROTOBUF'] def configure(conf): conf.check_cfg(package='protobuf', uselib_store='PROTOBUF', args=['--cflags', '--libs']) conf.find_program('protoc', var='PROTOC') conf.start_msg('Checking for protoc version') protocver = conf.cmd_and_log(conf.env.PROTOC + ['--version'], output=Context.BOTH) protocver = ''.join(protocver).strip()[protocver[0].rfind(' ')+1:] conf.end_msg(protocver) conf.env.PROTOC_MAJOR = protocver[:protocver.find('.')] conf.env.PROTOC_ST = '-I%s' conf.env.PROTOC_FL = '%s' ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py0000660000000000000000000001610713573675414021556 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Federico Pellegrin, 2016-2019 (fedepell) adapted for Python """ This tool helps with finding Python Qt5 tools and libraries, and provides translation from QT5 files to Python code. The following snippet illustrates the tool usage:: def options(opt): opt.load('py pyqt5') def configure(conf): conf.load('py pyqt5') def build(bld): bld( features = 'py pyqt5', source = 'main.py textures.qrc aboutDialog.ui', ) Here, the UI description and resource files will be processed to generate code. Usage ===== Load the "pyqt5" tool. Add into the sources list also the qrc resources files or ui5 definition files and they will be translated into python code with the system tools (PyQt5, PySide2, PyQt4 are searched in this order) and then compiled """ try: from xml.sax import make_parser from xml.sax.handler import ContentHandler except ImportError: has_xml = False ContentHandler = object else: has_xml = True import os from waflib.Tools import python from waflib import Task, Options from waflib.TaskGen import feature, extension from waflib.Configure import conf from waflib import Logs EXT_RCC = ['.qrc'] """ File extension for the resource (.qrc) files """ EXT_UI = ['.ui'] """ File extension for the user interface (.ui) files """ class XMLHandler(ContentHandler): """ Parses ``.qrc`` files """ def __init__(self): self.buf = [] self.files = [] def startElement(self, name, attrs): if name == 'file': self.buf = [] def endElement(self, name): if name == 'file': self.files.append(str(''.join(self.buf))) def characters(self, cars): self.buf.append(cars) @extension(*EXT_RCC) def create_pyrcc_task(self, node): "Creates rcc and py task for ``.qrc`` files" rcnode = node.change_ext('.py') self.create_task('pyrcc', node, rcnode) if getattr(self, 'install_from', None): self.install_from = self.install_from.get_bld() else: self.install_from = self.path.get_bld() self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') self.process_py(rcnode) @extension(*EXT_UI) def create_pyuic_task(self, node): "Create uic tasks and py for user interface ``.ui`` definition files" uinode = node.change_ext('.py') self.create_task('ui5py', node, uinode) if getattr(self, 'install_from', None): self.install_from = self.install_from.get_bld() else: self.install_from = self.path.get_bld() self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') self.process_py(uinode) @extension('.ts') def add_pylang(self, node): """Adds all the .ts file into ``self.lang``""" self.lang = self.to_list(getattr(self, 'lang', [])) + [node] @feature('pyqt5') def apply_pyqt5(self): """ The additional parameters are: :param lang: list of translation files (\\*.ts) to process :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension """ if getattr(self, 'lang', None): qmtasks = [] for x in self.to_list(self.lang): if isinstance(x, str): x = self.path.find_resource(x + '.ts') qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm'))) if getattr(self, 'langname', None): qmnodes = [k.outputs[0] for k in qmtasks] rcnode = self.langname if isinstance(rcnode, str): rcnode = self.path.find_or_declare(rcnode + '.qrc') t = self.create_task('qm2rcc', qmnodes, rcnode) create_pyrcc_task(self, t.outputs[0]) class pyrcc(Task.Task): """ Processes ``.qrc`` files """ color = 'BLUE' run_str = '${QT_PYRCC} ${SRC} -o ${TGT}' ext_out = ['.py'] def rcname(self): return os.path.splitext(self.inputs[0].name)[0] def scan(self): """Parse the *.qrc* files""" if not has_xml: Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') return ([], []) parser = make_parser() curHandler = XMLHandler() parser.setContentHandler(curHandler) fi = open(self.inputs[0].abspath(), 'r') try: parser.parse(fi) finally: fi.close() nodes = [] names = [] root = self.inputs[0].parent for x in curHandler.files: nd = root.find_resource(x) if nd: nodes.append(nd) else: names.append(x) return (nodes, names) class ui5py(Task.Task): """ Processes ``.ui`` files for python """ color = 'BLUE' run_str = '${QT_PYUIC} ${SRC} -o ${TGT}' ext_out = ['.py'] class ts2qm(Task.Task): """ Generates ``.qm`` files from ``.ts`` files """ color = 'BLUE' run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' class qm2rcc(Task.Task): """ Generates ``.qrc`` files from ``.qm`` files """ color = 'BLUE' after = 'ts2qm' def run(self): """Create a qrc file including the inputs""" txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) code = '\n\n%s\n\n' % txt self.outputs[0].write(code) def configure(self): self.find_pyqt5_binaries() # warn about this during the configuration too if not has_xml: Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') @conf def find_pyqt5_binaries(self): """ Detects PyQt5 or PySide2 programs such as pyuic5/pyside2-uic, pyrcc5/pyside2-rcc """ env = self.env if getattr(Options.options, 'want_pyqt5', True): self.find_program(['pyuic5'], var='QT_PYUIC') self.find_program(['pyrcc5'], var='QT_PYRCC') self.find_program(['pylupdate5'], var='QT_PYLUPDATE') elif getattr(Options.options, 'want_pyside2', True): self.find_program(['pyside2-uic'], var='QT_PYUIC') self.find_program(['pyside2-rcc'], var='QT_PYRCC') self.find_program(['pyside2-lupdate'], var='QT_PYLUPDATE') elif getattr(Options.options, 'want_pyqt4', True): self.find_program(['pyuic4'], var='QT_PYUIC') self.find_program(['pyrcc4'], var='QT_PYRCC') self.find_program(['pylupdate4'], var='QT_PYLUPDATE') else: self.find_program(['pyuic5','pyside2-uic','pyuic4'], var='QT_PYUIC') self.find_program(['pyrcc5','pyside2-rcc','pyrcc4'], var='QT_PYRCC') self.find_program(['pylupdate5', 'pyside2-lupdate','pylupdate4'], var='QT_PYLUPDATE') if not env.QT_PYUIC: self.fatal('cannot find the uic compiler for python for qt5') if not env.QT_PYRCC: self.fatal('cannot find the rcc compiler for python for qt5') self.find_program(['lrelease-qt5', 'lrelease'], var='QT_LRELEASE') def options(opt): """ Command-line options """ pyqt5opt=opt.add_option_group("Python QT5 Options") pyqt5opt.add_option('--pyqt5-pyqt5', action='store_true', default=False, dest='want_pyqt5', help='use PyQt5 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') pyqt5opt.add_option('--pyqt5-pyside2', action='store_true', default=False, dest='want_pyside2', help='use PySide2 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') pyqt5opt.add_option('--pyqt5-pyqt4', action='store_true', default=False, dest='want_pyqt4', help='use PyQt4 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') ldb-2.0.8/third_party/waf/waflib/extras/pytest.py0000660000000000000000000002014113573675414022015 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Calle Rosenquist, 2016-2018 (xbreak) """ Provides Python unit test support using :py:class:`waflib.Tools.waf_unit_test.utest` task via the **pytest** feature. To use pytest the following is needed: 1. Load `pytest` and the dependency `waf_unit_test` tools. 2. Create a task generator with feature `pytest` (not `test`) and customize behaviour with the following attributes: - `pytest_source`: Test input files. - `ut_str`: Test runner command, e.g. ``${PYTHON} -B -m unittest discover`` or if nose is used: ``${NOSETESTS} --no-byte-compile ${SRC}``. - `ut_shell`: Determines if ``ut_str`` is executed in a shell. Default: False. - `ut_cwd`: Working directory for test runner. Defaults to directory of first ``pytest_source`` file. Additionally the following `pytest` specific attributes are used in dependent taskgens: - `pytest_path`: Node or string list of additional Python paths. - `pytest_libpath`: Node or string list of additional library paths. The `use` dependencies are used for both update calculation and to populate the following environment variables for the `pytest` test runner: 1. `PYTHONPATH` (`sys.path`) of any dependent taskgen that has the feature `py`: - `install_from` attribute is used to determine where the root of the Python sources are located. If `install_from` is not specified the default is to use the taskgen path as the root. - `pytest_path` attribute is used to manually specify additional Python paths. 2. Dynamic linker search path variable (e.g. `LD_LIBRARY_PATH`) of any dependent taskgen with non-static link_task. - `pytest_libpath` attribute is used to manually specify additional linker paths. Note: `pytest` cannot automatically determine the correct `PYTHONPATH` for `pyext` taskgens because the extension might be part of a Python package or used standalone: - When used as part of another `py` package, the `PYTHONPATH` is provided by that taskgen so no additional action is required. - When used as a standalone module, the user needs to specify the `PYTHONPATH` explicitly via the `pytest_path` attribute on the `pyext` taskgen. For details c.f. the pytest playground examples. For example:: # A standalone Python C extension that demonstrates unit test environment population # of PYTHONPATH and LD_LIBRARY_PATH/PATH/DYLD_LIBRARY_PATH. # # Note: `pytest_path` is provided here because pytest cannot automatically determine # if the extension is part of another Python package or is used standalone. bld(name = 'foo_ext', features = 'c cshlib pyext', source = 'src/foo_ext.c', target = 'foo_ext', pytest_path = [ bld.path.get_bld() ]) # Python package under test that also depend on the Python module `foo_ext` # # Note: `install_from` is added automatically to `PYTHONPATH`. bld(name = 'foo', features = 'py', use = 'foo_ext', source = bld.path.ant_glob('src/foo/*.py'), install_from = 'src') # Unit test example using the built in module unittest and let that discover # any test cases. bld(name = 'foo_test', features = 'pytest', use = 'foo', pytest_source = bld.path.ant_glob('test/*.py'), ut_str = '${PYTHON} -B -m unittest discover') """ import os from waflib import Task, TaskGen, Errors, Utils, Logs from waflib.Tools import ccroot def _process_use_rec(self, name): """ Recursively process ``use`` for task generator with name ``name``.. Used by pytest_process_use. """ if name in self.pytest_use_not or name in self.pytest_use_seen: return try: tg = self.bld.get_tgen_by_name(name) except Errors.WafError: self.pytest_use_not.add(name) return self.pytest_use_seen.append(name) tg.post() for n in self.to_list(getattr(tg, 'use', [])): _process_use_rec(self, n) @TaskGen.feature('pytest') @TaskGen.after_method('process_source', 'apply_link') def pytest_process_use(self): """ Process the ``use`` attribute which contains a list of task generator names and store paths that later is used to populate the unit test runtime environment. """ self.pytest_use_not = set() self.pytest_use_seen = [] self.pytest_paths = [] # strings or Nodes self.pytest_libpaths = [] # strings or Nodes self.pytest_dep_nodes = [] names = self.to_list(getattr(self, 'use', [])) for name in names: _process_use_rec(self, name) def extend_unique(lst, varlst): ext = [] for x in varlst: if x not in lst: ext.append(x) lst.extend(ext) # Collect type specific info needed to construct a valid runtime environment # for the test. for name in self.pytest_use_seen: tg = self.bld.get_tgen_by_name(name) extend_unique(self.pytest_paths, Utils.to_list(getattr(tg, 'pytest_path', []))) extend_unique(self.pytest_libpaths, Utils.to_list(getattr(tg, 'pytest_libpath', []))) if 'py' in tg.features: # Python dependencies are added to PYTHONPATH pypath = getattr(tg, 'install_from', tg.path) if 'buildcopy' in tg.features: # Since buildcopy is used we assume that PYTHONPATH in build should be used, # not source extend_unique(self.pytest_paths, [pypath.get_bld().abspath()]) # Add buildcopy output nodes to dependencies extend_unique(self.pytest_dep_nodes, [o for task in getattr(tg, 'tasks', []) \ for o in getattr(task, 'outputs', [])]) else: # If buildcopy is not used, depend on sources instead extend_unique(self.pytest_dep_nodes, tg.source) extend_unique(self.pytest_paths, [pypath.abspath()]) if getattr(tg, 'link_task', None): # For tasks with a link_task (C, C++, D et.c.) include their library paths: if not isinstance(tg.link_task, ccroot.stlink_task): extend_unique(self.pytest_dep_nodes, tg.link_task.outputs) extend_unique(self.pytest_libpaths, tg.link_task.env.LIBPATH) if 'pyext' in tg.features: # If the taskgen is extending Python we also want to add the interpreter libpath. extend_unique(self.pytest_libpaths, tg.link_task.env.LIBPATH_PYEXT) else: # Only add to libpath if the link task is not a Python extension extend_unique(self.pytest_libpaths, [tg.link_task.outputs[0].parent.abspath()]) @TaskGen.feature('pytest') @TaskGen.after_method('pytest_process_use') def make_pytest(self): """ Creates a ``utest`` task with a populated environment for Python if not specified in ``ut_env``: - Paths in `pytest_paths` attribute are used to populate PYTHONPATH - Paths in `pytest_libpaths` attribute are used to populate the system library path (e.g. LD_LIBRARY_PATH) """ nodes = self.to_nodes(self.pytest_source) tsk = self.create_task('utest', nodes) tsk.dep_nodes.extend(self.pytest_dep_nodes) if getattr(self, 'ut_str', None): self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) tsk.vars = lst + tsk.vars if getattr(self, 'ut_cwd', None): if isinstance(self.ut_cwd, str): # we want a Node instance if os.path.isabs(self.ut_cwd): self.ut_cwd = self.bld.root.make_node(self.ut_cwd) else: self.ut_cwd = self.path.make_node(self.ut_cwd) else: if tsk.inputs: self.ut_cwd = tsk.inputs[0].parent else: raise Errors.WafError("no valid input files for pytest task, check pytest_source value") if not self.ut_cwd.exists(): self.ut_cwd.mkdir() if not hasattr(self, 'ut_env'): self.ut_env = dict(os.environ) def add_paths(var, lst): # Add list of paths to a variable, lst can contain strings or nodes lst = [ str(n) for n in lst ] Logs.debug("ut: %s: Adding paths %s=%s", self, var, lst) self.ut_env[var] = os.pathsep.join(lst) + os.pathsep + self.ut_env.get(var, '') # Prepend dependency paths to PYTHONPATH and LD_LIBRARY_PATH add_paths('PYTHONPATH', self.pytest_paths) if Utils.is_win32: add_paths('PATH', self.pytest_libpaths) elif Utils.unversioned_sys_platform() == 'darwin': add_paths('DYLD_LIBRARY_PATH', self.pytest_libpaths) add_paths('LD_LIBRARY_PATH', self.pytest_libpaths) else: add_paths('LD_LIBRARY_PATH', self.pytest_libpaths) ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py0000660000000000000000000000356113573675414022023 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Jérôme Carretero 2011 (zougloub) # QNX neutrino compatibility functions import sys, os from waflib import Utils class Popen(object): """ Popen cannot work on QNX from a threaded program: Forking in threads is not implemented in neutrino. Python's os.popen / spawn / fork won't work when running in threads (they will if in the main program thread) In waf, this happens mostly in build. And the use cases can be replaced by os.system() calls. """ __slots__ = ["prog", "kw", "popen", "verbose"] verbose = 0 def __init__(self, prog, **kw): try: self.prog = prog self.kw = kw self.popen = None if Popen.verbose: sys.stdout.write("Popen created: %r, kw=%r..." % (prog, kw)) do_delegate = kw.get('stdout') == -1 and kw.get('stderr') == -1 if do_delegate: if Popen.verbose: print("Delegating to real Popen") self.popen = self.real_Popen(prog, **kw) else: if Popen.verbose: print("Emulating") except Exception as e: if Popen.verbose: print("Exception: %s" % e) raise def __getattr__(self, name): if Popen.verbose: sys.stdout.write("Getattr: %s..." % name) if name in Popen.__slots__: return object.__getattribute__(self, name) else: if self.popen is not None: if Popen.verbose: print("from Popen") return getattr(self.popen, name) else: if name == "wait": return self.emu_wait else: raise Exception("subprocess emulation: not implemented: %s" % name) def emu_wait(self): if Popen.verbose: print("emulated wait (%r kw=%r)" % (self.prog, self.kw)) if isinstance(self.prog, str): cmd = self.prog else: cmd = " ".join(self.prog) if 'cwd' in self.kw: cmd = 'cd "%s" && %s' % (self.kw['cwd'], cmd) return os.system(cmd) if sys.platform == "qnx6": Popen.real_Popen = Utils.subprocess.Popen Utils.subprocess.Popen = Popen ldb-2.0.8/third_party/waf/waflib/extras/qt4.py0000660000000000000000000004752213573675414021211 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) """ Tool Description ================ This tool helps with finding Qt4 tools and libraries, and also provides syntactic sugar for using Qt4 tools. The following snippet illustrates the tool usage:: def options(opt): opt.load('compiler_cxx qt4') def configure(conf): conf.load('compiler_cxx qt4') def build(bld): bld( features = 'qt4 cxx cxxprogram', uselib = 'QTCORE QTGUI QTOPENGL QTSVG', source = 'main.cpp textures.qrc aboutDialog.ui', target = 'window', ) Here, the UI description and resource files will be processed to generate code. Usage ===== Load the "qt4" tool. You also need to edit your sources accordingly: - the normal way of doing things is to have your C++ files include the .moc file. This is regarded as the best practice (and provides much faster compilations). It also implies that the include paths have beenset properly. - to have the include paths added automatically, use the following:: from waflib.TaskGen import feature, before_method, after_method @feature('cxx') @after_method('process_source') @before_method('apply_incpaths') def add_includes_paths(self): incs = set(self.to_list(getattr(self, 'includes', ''))) for x in self.compiled_tasks: incs.add(x.inputs[0].parent.path_from(self.path)) self.includes = sorted(incs) Note: another tool provides Qt processing that does not require .moc includes, see 'playground/slow_qt/'. A few options (--qt{dir,bin,...}) and environment variables (QT4_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool, tool path selection, etc; please read the source for more info. """ try: from xml.sax import make_parser from xml.sax.handler import ContentHandler except ImportError: has_xml = False ContentHandler = object else: has_xml = True import os, sys from waflib.Tools import cxx from waflib import Task, Utils, Options, Errors, Context from waflib.TaskGen import feature, after_method, extension from waflib.Configure import conf from waflib import Logs MOC_H = ['.h', '.hpp', '.hxx', '.hh'] """ File extensions associated to the .moc files """ EXT_RCC = ['.qrc'] """ File extension for the resource (.qrc) files """ EXT_UI = ['.ui'] """ File extension for the user interface (.ui) files """ EXT_QT4 = ['.cpp', '.cc', '.cxx', '.C'] """ File extensions of C++ files that may require a .moc processing """ QT4_LIBS = "QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner" class qxx(Task.classes['cxx']): """ Each C++ file can have zero or several .moc files to create. They are known only when the files are scanned (preprocessor) To avoid scanning the c++ files each time (parsing C/C++), the results are retrieved from the task cache (bld.node_deps/bld.raw_deps). The moc tasks are also created *dynamically* during the build. """ def __init__(self, *k, **kw): Task.Task.__init__(self, *k, **kw) self.moc_done = 0 def runnable_status(self): """ Compute the task signature to make sure the scanner was executed. Create the moc tasks by using :py:meth:`waflib.Tools.qt4.qxx.add_moc_tasks` (if necessary), then postpone the task execution (there is no need to recompute the task signature). """ if self.moc_done: return Task.Task.runnable_status(self) else: for t in self.run_after: if not t.hasrun: return Task.ASK_LATER self.add_moc_tasks() return Task.Task.runnable_status(self) def create_moc_task(self, h_node, m_node): """ If several libraries use the same classes, it is possible that moc will run several times (Issue 1318) It is not possible to change the file names, but we can assume that the moc transformation will be identical, and the moc tasks can be shared in a global cache. The defines passed to moc will then depend on task generator order. If this is not acceptable, then use the tool slow_qt4 instead (and enjoy the slow builds... :-( ) """ try: moc_cache = self.generator.bld.moc_cache except AttributeError: moc_cache = self.generator.bld.moc_cache = {} try: return moc_cache[h_node] except KeyError: tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator) tsk.set_inputs(h_node) tsk.set_outputs(m_node) if self.generator: self.generator.tasks.append(tsk) # direct injection in the build phase (safe because called from the main thread) gen = self.generator.bld.producer gen.outstanding.append(tsk) gen.total += 1 return tsk def moc_h_ext(self): ext = [] try: ext = Options.options.qt_header_ext.split() except AttributeError: pass if not ext: ext = MOC_H return ext def add_moc_tasks(self): """ Create the moc tasks by looking in ``bld.raw_deps[self.uid()]`` """ node = self.inputs[0] bld = self.generator.bld try: # compute the signature once to know if there is a moc file to create self.signature() except KeyError: # the moc file may be referenced somewhere else pass else: # remove the signature, it must be recomputed with the moc task delattr(self, 'cache_sig') include_nodes = [node.parent] + self.generator.includes_nodes moctasks = [] mocfiles = set() for d in bld.raw_deps.get(self.uid(), []): if not d.endswith('.moc'): continue # process that base.moc only once if d in mocfiles: continue mocfiles.add(d) # find the source associated with the moc file h_node = None base2 = d[:-4] for x in include_nodes: for e in self.moc_h_ext(): h_node = x.find_node(base2 + e) if h_node: break if h_node: m_node = h_node.change_ext('.moc') break else: # foo.cpp -> foo.cpp.moc for k in EXT_QT4: if base2.endswith(k): for x in include_nodes: h_node = x.find_node(base2) if h_node: break if h_node: m_node = h_node.change_ext(k + '.moc') break if not h_node: raise Errors.WafError('No source found for %r which is a moc file' % d) # create the moc task task = self.create_moc_task(h_node, m_node) moctasks.append(task) # simple scheduler dependency: run the moc task before others self.run_after.update(set(moctasks)) self.moc_done = 1 class trans_update(Task.Task): """Update a .ts files from a list of C++ files""" run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}' color = 'BLUE' class XMLHandler(ContentHandler): """ Parser for *.qrc* files """ def __init__(self): self.buf = [] self.files = [] def startElement(self, name, attrs): if name == 'file': self.buf = [] def endElement(self, name): if name == 'file': self.files.append(str(''.join(self.buf))) def characters(self, cars): self.buf.append(cars) @extension(*EXT_RCC) def create_rcc_task(self, node): "Create rcc and cxx tasks for *.qrc* files" rcnode = node.change_ext('_rc.cpp') self.create_task('rcc', node, rcnode) cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o')) try: self.compiled_tasks.append(cpptask) except AttributeError: self.compiled_tasks = [cpptask] return cpptask @extension(*EXT_UI) def create_uic_task(self, node): "hook for uic tasks" uictask = self.create_task('ui4', node) uictask.outputs = [self.path.find_or_declare(self.env['ui_PATTERN'] % node.name[:-3])] @extension('.ts') def add_lang(self, node): """add all the .ts file into self.lang""" self.lang = self.to_list(getattr(self, 'lang', [])) + [node] @feature('qt4') @after_method('apply_link') def apply_qt4(self): """ Add MOC_FLAGS which may be necessary for moc:: def build(bld): bld.program(features='qt4', source='main.cpp', target='app', use='QTCORE') The additional parameters are: :param lang: list of translation files (\\*.ts) to process :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension :param update: whether to process the C++ files to update the \\*.ts files (use **waf --translate**) :type update: bool :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension """ if getattr(self, 'lang', None): qmtasks = [] for x in self.to_list(self.lang): if isinstance(x, str): x = self.path.find_resource(x + '.ts') qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm'))) if getattr(self, 'update', None) and Options.options.trans_qt4: cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [ a.inputs[0] for a in self.tasks if getattr(a, 'inputs', None) and a.inputs[0].name.endswith('.ui')] for x in qmtasks: self.create_task('trans_update', cxxnodes, x.inputs) if getattr(self, 'langname', None): qmnodes = [x.outputs[0] for x in qmtasks] rcnode = self.langname if isinstance(rcnode, str): rcnode = self.path.find_or_declare(rcnode + '.qrc') t = self.create_task('qm2rcc', qmnodes, rcnode) k = create_rcc_task(self, t.outputs[0]) self.link_task.inputs.append(k.outputs[0]) lst = [] for flag in self.to_list(self.env['CXXFLAGS']): if len(flag) < 2: continue f = flag[0:2] if f in ('-D', '-I', '/D', '/I'): if (f[0] == '/'): lst.append('-' + flag[1:]) else: lst.append(flag) self.env.append_value('MOC_FLAGS', lst) @extension(*EXT_QT4) def cxx_hook(self, node): """ Re-map C++ file extensions to the :py:class:`waflib.Tools.qt4.qxx` task. """ return self.create_compiled_task('qxx', node) class rcc(Task.Task): """ Process *.qrc* files """ color = 'BLUE' run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' ext_out = ['.h'] def rcname(self): return os.path.splitext(self.inputs[0].name)[0] def scan(self): """Parse the *.qrc* files""" if not has_xml: Logs.error('no xml support was found, the rcc dependencies will be incomplete!') return ([], []) parser = make_parser() curHandler = XMLHandler() parser.setContentHandler(curHandler) fi = open(self.inputs[0].abspath(), 'r') try: parser.parse(fi) finally: fi.close() nodes = [] names = [] root = self.inputs[0].parent for x in curHandler.files: nd = root.find_resource(x) if nd: nodes.append(nd) else: names.append(x) return (nodes, names) class moc(Task.Task): """ Create *.moc* files """ color = 'BLUE' run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' def keyword(self): return "Creating" def __str__(self): return self.outputs[0].path_from(self.generator.bld.launch_node()) class ui4(Task.Task): """ Process *.ui* files """ color = 'BLUE' run_str = '${QT_UIC} ${SRC} -o ${TGT}' ext_out = ['.h'] class ts2qm(Task.Task): """ Create *.qm* files from *.ts* files """ color = 'BLUE' run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' class qm2rcc(Task.Task): """ Transform *.qm* files into *.rc* files """ color = 'BLUE' after = 'ts2qm' def run(self): """Create a qrc file including the inputs""" txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) code = '\n\n%s\n\n' % txt self.outputs[0].write(code) def configure(self): """ Besides the configuration options, the environment variable QT4_ROOT may be used to give the location of the qt4 libraries (absolute path). The detection will use the program *pkg-config* through :py:func:`waflib.Tools.config_c.check_cfg` """ self.find_qt4_binaries() self.set_qt4_libs_to_check() self.set_qt4_defines() self.find_qt4_libraries() self.add_qt4_rpath() self.simplify_qt4_libs() @conf def find_qt4_binaries(self): env = self.env opt = Options.options qtdir = getattr(opt, 'qtdir', '') qtbin = getattr(opt, 'qtbin', '') paths = [] if qtdir: qtbin = os.path.join(qtdir, 'bin') # the qt directory has been given from QT4_ROOT - deduce the qt binary path if not qtdir: qtdir = os.environ.get('QT4_ROOT', '') qtbin = os.environ.get('QT4_BIN') or os.path.join(qtdir, 'bin') if qtbin: paths = [qtbin] # no qtdir, look in the path and in /usr/local/Trolltech if not qtdir: paths = os.environ.get('PATH', '').split(os.pathsep) paths.append('/usr/share/qt4/bin/') try: lst = Utils.listdir('/usr/local/Trolltech/') except OSError: pass else: if lst: lst.sort() lst.reverse() # keep the highest version qtdir = '/usr/local/Trolltech/%s/' % lst[0] qtbin = os.path.join(qtdir, 'bin') paths.append(qtbin) # at the end, try to find qmake in the paths given # keep the one with the highest version cand = None prev_ver = ['4', '0', '0'] for qmk in ('qmake-qt4', 'qmake4', 'qmake'): try: qmake = self.find_program(qmk, path_list=paths) except self.errors.ConfigurationError: pass else: try: version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip() except self.errors.WafError: pass else: if version: new_ver = version.split('.') if new_ver > prev_ver: cand = qmake prev_ver = new_ver if cand: self.env.QMAKE = cand else: self.fatal('Could not find qmake for qt4') qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_BINS']).strip() + os.sep def find_bin(lst, var): if var in env: return for f in lst: try: ret = self.find_program(f, path_list=paths) except self.errors.ConfigurationError: pass else: env[var]=ret break find_bin(['uic-qt3', 'uic3'], 'QT_UIC3') find_bin(['uic-qt4', 'uic'], 'QT_UIC') if not env.QT_UIC: self.fatal('cannot find the uic compiler for qt4') self.start_msg('Checking for uic version') uicver = self.cmd_and_log(env.QT_UIC + ["-version"], output=Context.BOTH) uicver = ''.join(uicver).strip() uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '') self.end_msg(uicver) if uicver.find(' 3.') != -1: self.fatal('this uic compiler is for qt3, add uic for qt4 to your path') find_bin(['moc-qt4', 'moc'], 'QT_MOC') find_bin(['rcc-qt4', 'rcc'], 'QT_RCC') find_bin(['lrelease-qt4', 'lrelease'], 'QT_LRELEASE') find_bin(['lupdate-qt4', 'lupdate'], 'QT_LUPDATE') env['UIC3_ST']= '%s -o %s' env['UIC_ST'] = '%s -o %s' env['MOC_ST'] = '-o' env['ui_PATTERN'] = 'ui_%s.h' env['QT_LRELEASE_FLAGS'] = ['-silent'] env.MOCCPPPATH_ST = '-I%s' env.MOCDEFINES_ST = '-D%s' @conf def find_qt4_libraries(self): qtlibs = getattr(Options.options, 'qtlibs', None) or os.environ.get("QT4_LIBDIR") if not qtlibs: try: qtlibs = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip() except Errors.WafError: qtdir = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() + os.sep qtlibs = os.path.join(qtdir, 'lib') self.msg('Found the Qt4 libraries in', qtlibs) qtincludes = os.environ.get("QT4_INCLUDES") or self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip() env = self.env if not 'PKG_CONFIG_PATH' in os.environ: os.environ['PKG_CONFIG_PATH'] = '%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib' % (qtlibs, qtlibs) try: if os.environ.get("QT4_XCOMPILE"): raise self.errors.ConfigurationError() self.check_cfg(atleast_pkgconfig_version='0.1') except self.errors.ConfigurationError: for i in self.qt4_vars: uselib = i.upper() if Utils.unversioned_sys_platform() == "darwin": # Since at least qt 4.7.3 each library locates in separate directory frameworkName = i + ".framework" qtDynamicLib = os.path.join(qtlibs, frameworkName, i) if os.path.exists(qtDynamicLib): env.append_unique('FRAMEWORK_' + uselib, i) self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') else: self.msg('Checking for %s' % i, False, 'YELLOW') env.append_unique('INCLUDES_' + uselib, os.path.join(qtlibs, frameworkName, 'Headers')) elif env.DEST_OS != "win32": qtDynamicLib = os.path.join(qtlibs, "lib" + i + ".so") qtStaticLib = os.path.join(qtlibs, "lib" + i + ".a") if os.path.exists(qtDynamicLib): env.append_unique('LIB_' + uselib, i) self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') elif os.path.exists(qtStaticLib): env.append_unique('LIB_' + uselib, i) self.msg('Checking for %s' % i, qtStaticLib, 'GREEN') else: self.msg('Checking for %s' % i, False, 'YELLOW') env.append_unique('LIBPATH_' + uselib, qtlibs) env.append_unique('INCLUDES_' + uselib, qtincludes) env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) else: # Release library names are like QtCore4 for k in ("lib%s.a", "lib%s4.a", "%s.lib", "%s4.lib"): lib = os.path.join(qtlibs, k % i) if os.path.exists(lib): env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')]) self.msg('Checking for %s' % i, lib, 'GREEN') break else: self.msg('Checking for %s' % i, False, 'YELLOW') env.append_unique('LIBPATH_' + uselib, qtlibs) env.append_unique('INCLUDES_' + uselib, qtincludes) env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) # Debug library names are like QtCore4d uselib = i.upper() + "_debug" for k in ("lib%sd.a", "lib%sd4.a", "%sd.lib", "%sd4.lib"): lib = os.path.join(qtlibs, k % i) if os.path.exists(lib): env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')]) self.msg('Checking for %s' % i, lib, 'GREEN') break else: self.msg('Checking for %s' % i, False, 'YELLOW') env.append_unique('LIBPATH_' + uselib, qtlibs) env.append_unique('INCLUDES_' + uselib, qtincludes) env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) else: for i in self.qt4_vars_debug + self.qt4_vars: self.check_cfg(package=i, args='--cflags --libs', mandatory=False) @conf def simplify_qt4_libs(self): # the libpaths make really long command-lines # remove the qtcore ones from qtgui, etc env = self.env def process_lib(vars_, coreval): for d in vars_: var = d.upper() if var == 'QTCORE': continue value = env['LIBPATH_'+var] if value: core = env[coreval] accu = [] for lib in value: if lib in core: continue accu.append(lib) env['LIBPATH_'+var] = accu process_lib(self.qt4_vars, 'LIBPATH_QTCORE') process_lib(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG') @conf def add_qt4_rpath(self): # rpath if wanted env = self.env if getattr(Options.options, 'want_rpath', False): def process_rpath(vars_, coreval): for d in vars_: var = d.upper() value = env['LIBPATH_'+var] if value: core = env[coreval] accu = [] for lib in value: if var != 'QTCORE': if lib in core: continue accu.append('-Wl,--rpath='+lib) env['RPATH_'+var] = accu process_rpath(self.qt4_vars, 'LIBPATH_QTCORE') process_rpath(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG') @conf def set_qt4_libs_to_check(self): if not hasattr(self, 'qt4_vars'): self.qt4_vars = QT4_LIBS self.qt4_vars = Utils.to_list(self.qt4_vars) if not hasattr(self, 'qt4_vars_debug'): self.qt4_vars_debug = [a + '_debug' for a in self.qt4_vars] self.qt4_vars_debug = Utils.to_list(self.qt4_vars_debug) @conf def set_qt4_defines(self): if sys.platform != 'win32': return for x in self.qt4_vars: y = x[2:].upper() self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y) self.env.append_unique('DEFINES_%s_DEBUG' % x.upper(), 'QT_%s_LIB' % y) def options(opt): """ Command-line options """ opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries') opt.add_option('--header-ext', type='string', default='', help='header extension for moc files', dest='qt_header_ext') for i in 'qtdir qtbin qtlibs'.split(): opt.add_option('--'+i, type='string', default='', dest=i) opt.add_option('--translate', action="store_true", help="collect translation strings", dest="trans_qt4", default=False) ldb-2.0.8/third_party/waf/waflib/extras/relocation.py0000660000000000000000000000433313573675414022631 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 """ Waf 1.6 Try to detect if the project directory was relocated, and if it was, change the node representing the project directory. Just call: waf configure build Note that if the project directory name changes, the signatures for the tasks using files in that directory will change, causing a partial build. """ import os from waflib import Build, ConfigSet, Task, Utils, Errors from waflib.TaskGen import feature, after_method EXTRA_LOCK = '.old_srcdir' old1 = Build.BuildContext.store def store(self): old1(self) db = os.path.join(self.variant_dir, EXTRA_LOCK) env = ConfigSet.ConfigSet() env.SRCDIR = self.srcnode.abspath() env.store(db) Build.BuildContext.store = store old2 = Build.BuildContext.init_dirs def init_dirs(self): if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)): raise Errors.WafError('The project was not configured: run "waf configure" first!') srcdir = None db = os.path.join(self.variant_dir, EXTRA_LOCK) env = ConfigSet.ConfigSet() try: env.load(db) srcdir = env.SRCDIR except: pass if srcdir: d = self.root.find_node(srcdir) if d and srcdir != self.top_dir and getattr(d, 'children', ''): srcnode = self.root.make_node(self.top_dir) print("relocating the source directory %r -> %r" % (srcdir, self.top_dir)) srcnode.children = {} for (k, v) in d.children.items(): srcnode.children[k] = v v.parent = srcnode d.children = {} old2(self) Build.BuildContext.init_dirs = init_dirs def uid(self): try: return self.uid_ except AttributeError: # this is not a real hot zone, but we want to avoid surprises here m = Utils.md5() up = m.update up(self.__class__.__name__.encode()) for x in self.inputs + self.outputs: up(x.path_from(x.ctx.srcnode).encode()) self.uid_ = m.digest() return self.uid_ Task.Task.uid = uid @feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes') @after_method('propagate_uselib_vars', 'process_source') def apply_incpaths(self): lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) self.includes_nodes = lst bld = self.bld self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.bldnode) or x.abspath() for x in lst] ldb-2.0.8/third_party/waf/waflib/extras/remote.py0000660000000000000000000002307213573675414021766 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Remote Builds tool using rsync+ssh __author__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2013" """ Simple Remote Builds ******************** This tool is an *experimental* tool (meaning, do not even try to pollute the waf bug tracker with bugs in here, contact me directly) providing simple remote builds. It uses rsync and ssh to perform the remote builds. It is intended for performing cross-compilation on platforms where a cross-compiler is either unavailable (eg. MacOS, QNX) a specific product does not exist (eg. Windows builds using Visual Studio) or simply not installed. This tool sends the sources and the waf script to the remote host, and commands the usual waf execution. There are alternatives to using this tool, such as setting up shared folders, logging on to remote machines, and building on the shared folders. Electing one method or another depends on the size of the program. Usage ===== 1. Set your wscript file so it includes a list of variants, e.g.:: from waflib import Utils top = '.' out = 'build' variants = [ 'linux_64_debug', 'linux_64_release', 'linux_32_debug', 'linux_32_release', ] from waflib.extras import remote def options(opt): # normal stuff from here on opt.load('compiler_c') def configure(conf): if not conf.variant: return # normal stuff from here on conf.load('compiler_c') def build(bld): if not bld.variant: return # normal stuff from here on bld(features='c cprogram', target='app', source='main.c') 2. Build the waf file, so it includes this tool, and put it in the current directory .. code:: bash ./waf-light --tools=remote 3. Set the host names to access the hosts: .. code:: bash export REMOTE_QNX=user@kiunix 4. Setup the ssh server and ssh keys The ssh key should not be protected by a password, or it will prompt for it every time. Create the key on the client: .. code:: bash ssh-keygen -t rsa -f foo.rsa Then copy foo.rsa.pub to the remote machine (user@kiunix:/home/user/.ssh/authorized_keys), and make sure the permissions are correct (chmod go-w ~ ~/.ssh ~/.ssh/authorized_keys) A separate key for the build processes can be set in the environment variable WAF_SSH_KEY. The tool will then use 'ssh-keyscan' to avoid prompting for remote hosts, so be warned to use this feature on internal networks only (MITM). .. code:: bash export WAF_SSH_KEY=~/foo.rsa 5. Perform the build: .. code:: bash waf configure_all build_all --remote """ import getpass, os, re, sys from collections import OrderedDict from waflib import Context, Options, Utils, ConfigSet from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext from waflib.Configure import ConfigurationContext is_remote = False if '--remote' in sys.argv: is_remote = True sys.argv.remove('--remote') class init(Context.Context): """ Generates the *_all commands """ cmd = 'init' fun = 'init' def execute(self): for x in list(Context.g_module.variants): self.make_variant(x) lst = ['remote'] for k in Options.commands: if k.endswith('_all'): name = k.replace('_all', '') for x in Context.g_module.variants: lst.append('%s_%s' % (name, x)) else: lst.append(k) del Options.commands[:] Options.commands += lst def make_variant(self, x): for y in (BuildContext, CleanContext, InstallContext, UninstallContext): name = y.__name__.replace('Context','').lower() class tmp(y): cmd = name + '_' + x fun = 'build' variant = x class tmp(ConfigurationContext): cmd = 'configure_' + x fun = 'configure' variant = x def __init__(self, **kw): ConfigurationContext.__init__(self, **kw) self.setenv(x) class remote(BuildContext): cmd = 'remote' fun = 'build' def get_ssh_hosts(self): lst = [] for v in Context.g_module.variants: self.env.HOST = self.login_to_host(self.variant_to_login(v)) cmd = Utils.subst_vars('${SSH_KEYSCAN} -t rsa,ecdsa ${HOST}', self.env) out, err = self.cmd_and_log(cmd, output=Context.BOTH, quiet=Context.BOTH) lst.append(out.strip()) return lst def setup_private_ssh_key(self): """ When WAF_SSH_KEY points to a private key, a .ssh directory will be created in the build directory Make sure that the ssh key does not prompt for a password """ key = os.environ.get('WAF_SSH_KEY', '') if not key: return if not os.path.isfile(key): self.fatal('Key in WAF_SSH_KEY must point to a valid file') self.ssh_dir = os.path.join(self.path.abspath(), 'build', '.ssh') self.ssh_hosts = os.path.join(self.ssh_dir, 'known_hosts') self.ssh_key = os.path.join(self.ssh_dir, os.path.basename(key)) self.ssh_config = os.path.join(self.ssh_dir, 'config') for x in self.ssh_hosts, self.ssh_key, self.ssh_config: if not os.path.isfile(x): if not os.path.isdir(self.ssh_dir): os.makedirs(self.ssh_dir) Utils.writef(self.ssh_key, Utils.readf(key), 'wb') os.chmod(self.ssh_key, 448) Utils.writef(self.ssh_hosts, '\n'.join(self.get_ssh_hosts())) os.chmod(self.ssh_key, 448) Utils.writef(self.ssh_config, 'UserKnownHostsFile %s' % self.ssh_hosts, 'wb') os.chmod(self.ssh_config, 448) self.env.SSH_OPTS = ['-F', self.ssh_config, '-i', self.ssh_key] self.env.append_value('RSYNC_SEND_OPTS', '--exclude=build/.ssh') def skip_unbuildable_variant(self): # skip variants that cannot be built on this OS for k in Options.commands: a, _, b = k.partition('_') if b in Context.g_module.variants: c, _, _ = b.partition('_') if c != Utils.unversioned_sys_platform(): Options.commands.remove(k) def login_to_host(self, login): return re.sub(r'(\w+@)', '', login) def variant_to_login(self, variant): """linux_32_debug -> search env.LINUX_32 and then env.LINUX""" x = variant[:variant.rfind('_')] ret = os.environ.get('REMOTE_' + x.upper(), '') if not ret: x = x[:x.find('_')] ret = os.environ.get('REMOTE_' + x.upper(), '') if not ret: ret = '%s@localhost' % getpass.getuser() return ret def execute(self): global is_remote if not is_remote: self.skip_unbuildable_variant() else: BuildContext.execute(self) def restore(self): self.top_dir = os.path.abspath(Context.g_module.top) self.srcnode = self.root.find_node(self.top_dir) self.path = self.srcnode self.out_dir = os.path.join(self.top_dir, Context.g_module.out) self.bldnode = self.root.make_node(self.out_dir) self.bldnode.mkdir() self.env = ConfigSet.ConfigSet() def extract_groups_of_builds(self): """Return a dict mapping each variants to the commands to build""" self.vgroups = {} for x in reversed(Options.commands): _, _, variant = x.partition('_') if variant in Context.g_module.variants: try: dct = self.vgroups[variant] except KeyError: dct = self.vgroups[variant] = OrderedDict() try: dct[variant].append(x) except KeyError: dct[variant] = [x] Options.commands.remove(x) def custom_options(self, login): try: return Context.g_module.host_options[login] except (AttributeError, KeyError): return {} def recurse(self, *k, **kw): self.env.RSYNC = getattr(Context.g_module, 'rsync', 'rsync -a --chmod=u+rwx') self.env.SSH = getattr(Context.g_module, 'ssh', 'ssh') self.env.SSH_KEYSCAN = getattr(Context.g_module, 'ssh_keyscan', 'ssh-keyscan') try: self.env.WAF = getattr(Context.g_module, 'waf') except AttributeError: try: os.stat('waf') except KeyError: self.fatal('Put a waf file in the directory (./waf-light --tools=remote)') else: self.env.WAF = './waf' self.extract_groups_of_builds() self.setup_private_ssh_key() for k, v in self.vgroups.items(): task = self(rule=rsync_and_ssh, always=True) task.env.login = self.variant_to_login(k) task.env.commands = [] for opt, value in v.items(): task.env.commands += value task.env.variant = task.env.commands[0].partition('_')[2] for opt, value in self.custom_options(k): task.env[opt] = value self.jobs = len(self.vgroups) def make_mkdir_command(self, task): return Utils.subst_vars('${SSH} ${SSH_OPTS} ${login} "rm -fr ${remote_dir} && mkdir -p ${remote_dir}"', task.env) def make_send_command(self, task): return Utils.subst_vars('${RSYNC} ${RSYNC_SEND_OPTS} -e "${SSH} ${SSH_OPTS}" ${local_dir} ${login}:${remote_dir}', task.env) def make_exec_command(self, task): txt = '''${SSH} ${SSH_OPTS} ${login} "cd ${remote_dir} && ${WAF} ${commands}"''' return Utils.subst_vars(txt, task.env) def make_save_command(self, task): return Utils.subst_vars('${RSYNC} ${RSYNC_SAVE_OPTS} -e "${SSH} ${SSH_OPTS}" ${login}:${remote_dir_variant} ${build_dir}', task.env) def rsync_and_ssh(task): # remove a warning task.uid_ = id(task) bld = task.generator.bld task.env.user, _, _ = task.env.login.partition('@') task.env.hdir = Utils.to_hex(Utils.h_list((task.generator.path.abspath(), task.env.variant))) task.env.remote_dir = '~%s/wafremote/%s' % (task.env.user, task.env.hdir) task.env.local_dir = bld.srcnode.abspath() + '/' task.env.remote_dir_variant = '%s/%s/%s' % (task.env.remote_dir, Context.g_module.out, task.env.variant) task.env.build_dir = bld.bldnode.abspath() ret = task.exec_command(bld.make_mkdir_command(task)) if ret: return ret ret = task.exec_command(bld.make_send_command(task)) if ret: return ret ret = task.exec_command(bld.make_exec_command(task)) if ret: return ret ret = task.exec_command(bld.make_save_command(task)) if ret: return ret ldb-2.0.8/third_party/waf/waflib/extras/resx.py0000660000000000000000000000203213573675414021445 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 import os from waflib import Task from waflib.TaskGen import extension def configure(conf): conf.find_program(['resgen'], var='RESGEN') conf.env.RESGENFLAGS = '/useSourcePath' @extension('.resx') def resx_file(self, node): """ Bind the .resx extension to a resgen task """ if not getattr(self, 'cs_task', None): self.bld.fatal('resx_file has no link task for use %r' % self) # Given assembly 'Foo' and file 'Sub/Dir/File.resx', create 'Foo.Sub.Dir.File.resources' assembly = getattr(self, 'namespace', os.path.splitext(self.gen)[0]) res = os.path.splitext(node.path_from(self.path))[0].replace('/', '.').replace('\\', '.') out = self.path.find_or_declare(assembly + '.' + res + '.resources') tsk = self.create_task('resgen', node, out) self.cs_task.dep_nodes.extend(tsk.outputs) # dependency self.env.append_value('RESOURCES', tsk.outputs[0].bldpath()) class resgen(Task.Task): """ Compile C# resource files """ color = 'YELLOW' run_str = '${RESGEN} ${RESGENFLAGS} ${SRC} ${TGT}' ldb-2.0.8/third_party/waf/waflib/extras/review.py0000660000000000000000000002160213573675414021771 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Laurent Birtz, 2011 # moved the code into a separate tool (ita) """ There are several things here: - a different command-line option management making options persistent - the review command to display the options set Assumptions: - configuration options are not always added to the right group (and do not count on the users to do it...) - the options are persistent between the executions (waf options are NOT persistent by design), even for the configuration - when the options change, the build is invalidated (forcing a reconfiguration) """ import os, textwrap, shutil from waflib import Logs, Context, ConfigSet, Options, Build, Configure class Odict(dict): """Ordered dictionary""" def __init__(self, data=None): self._keys = [] dict.__init__(self) if data: # we were provided a regular dict if isinstance(data, dict): self.append_from_dict(data) # we were provided a tuple list elif type(data) == list: self.append_from_plist(data) # we were provided invalid input else: raise Exception("expected a dict or a tuple list") def append_from_dict(self, dict): map(self.__setitem__, dict.keys(), dict.values()) def append_from_plist(self, plist): for pair in plist: if len(pair) != 2: raise Exception("invalid pairs list") for (k, v) in plist: self.__setitem__(k, v) def __delitem__(self, key): if not key in self._keys: raise KeyError(key) dict.__delitem__(self, key) self._keys.remove(key) def __setitem__(self, key, item): dict.__setitem__(self, key, item) if key not in self._keys: self._keys.append(key) def clear(self): dict.clear(self) self._keys = [] def copy(self): return Odict(self.plist()) def items(self): return zip(self._keys, self.values()) def keys(self): return list(self._keys) # return a copy of the list def values(self): return map(self.get, self._keys) def plist(self): p = [] for k, v in self.items(): p.append( (k, v) ) return p def __str__(self): buf = [] buf.append("{ ") for k, v in self.items(): buf.append('%r : %r, ' % (k, v)) buf.append("}") return ''.join(buf) review_options = Odict() """ Ordered dictionary mapping configuration option names to their optparse option. """ review_defaults = {} """ Dictionary mapping configuration option names to their default value. """ old_review_set = None """ Review set containing the configuration values before parsing the command line. """ new_review_set = None """ Review set containing the configuration values after parsing the command line. """ class OptionsReview(Options.OptionsContext): def __init__(self, **kw): super(self.__class__, self).__init__(**kw) def prepare_config_review(self): """ Find the configuration options that are reviewable, detach their default value from their optparse object and store them into the review dictionaries. """ gr = self.get_option_group('configure options') for opt in gr.option_list: if opt.action != 'store' or opt.dest in ("out", "top"): continue review_options[opt.dest] = opt review_defaults[opt.dest] = opt.default if gr.defaults.has_key(opt.dest): del gr.defaults[opt.dest] opt.default = None def parse_args(self): self.prepare_config_review() self.parser.get_option('--prefix').help = 'installation prefix' super(OptionsReview, self).parse_args() Context.create_context('review').refresh_review_set() class ReviewContext(Context.Context): '''reviews the configuration values''' cmd = 'review' def __init__(self, **kw): super(self.__class__, self).__init__(**kw) out = Options.options.out if not out: out = getattr(Context.g_module, Context.OUT, None) if not out: out = Options.lockfile.replace('.lock-waf', '') self.build_path = (os.path.isabs(out) and self.root or self.path).make_node(out).abspath() """Path to the build directory""" self.cache_path = os.path.join(self.build_path, Build.CACHE_DIR) """Path to the cache directory""" self.review_path = os.path.join(self.cache_path, 'review.cache') """Path to the review cache file""" def execute(self): """ Display and store the review set. Invalidate the cache as required. """ if not self.compare_review_set(old_review_set, new_review_set): self.invalidate_cache() self.store_review_set(new_review_set) print(self.display_review_set(new_review_set)) def invalidate_cache(self): """Invalidate the cache to prevent bad builds.""" try: Logs.warn("Removing the cached configuration since the options have changed") shutil.rmtree(self.cache_path) except: pass def refresh_review_set(self): """ Obtain the old review set and the new review set, and import the new set. """ global old_review_set, new_review_set old_review_set = self.load_review_set() new_review_set = self.update_review_set(old_review_set) self.import_review_set(new_review_set) def load_review_set(self): """ Load and return the review set from the cache if it exists. Otherwise, return an empty set. """ if os.path.isfile(self.review_path): return ConfigSet.ConfigSet(self.review_path) return ConfigSet.ConfigSet() def store_review_set(self, review_set): """ Store the review set specified in the cache. """ if not os.path.isdir(self.cache_path): os.makedirs(self.cache_path) review_set.store(self.review_path) def update_review_set(self, old_set): """ Merge the options passed on the command line with those imported from the previous review set and return the corresponding preview set. """ # Convert value to string. It's important that 'None' maps to # the empty string. def val_to_str(val): if val == None or val == '': return '' return str(val) new_set = ConfigSet.ConfigSet() opt_dict = Options.options.__dict__ for name in review_options.keys(): # the option is specified explicitly on the command line if name in opt_dict: # if the option is the default, pretend it was never specified if val_to_str(opt_dict[name]) != val_to_str(review_defaults[name]): new_set[name] = opt_dict[name] # the option was explicitly specified in a previous command elif name in old_set: new_set[name] = old_set[name] return new_set def import_review_set(self, review_set): """ Import the actual value of the reviewable options in the option dictionary, given the current review set. """ for name in review_options.keys(): if name in review_set: value = review_set[name] else: value = review_defaults[name] setattr(Options.options, name, value) def compare_review_set(self, set1, set2): """ Return true if the review sets specified are equal. """ if len(set1.keys()) != len(set2.keys()): return False for key in set1.keys(): if not key in set2 or set1[key] != set2[key]: return False return True def display_review_set(self, review_set): """ Return the string representing the review set specified. """ term_width = Logs.get_term_cols() lines = [] for dest in review_options.keys(): opt = review_options[dest] name = ", ".join(opt._short_opts + opt._long_opts) help = opt.help actual = None if dest in review_set: actual = review_set[dest] default = review_defaults[dest] lines.append(self.format_option(name, help, actual, default, term_width)) return "Configuration:\n\n" + "\n\n".join(lines) + "\n" def format_option(self, name, help, actual, default, term_width): """ Return the string representing the option specified. """ def val_to_str(val): if val == None or val == '': return "(void)" return str(val) max_name_len = 20 sep_len = 2 w = textwrap.TextWrapper() w.width = term_width - 1 if w.width < 60: w.width = 60 out = "" # format the help out += w.fill(help) + "\n" # format the name name_len = len(name) out += Logs.colors.CYAN + name + Logs.colors.NORMAL # set the indentation used when the value wraps to the next line w.subsequent_indent = " ".rjust(max_name_len + sep_len) w.width -= (max_name_len + sep_len) # the name string is too long, switch to the next line if name_len > max_name_len: out += "\n" + w.subsequent_indent # fill the remaining of the line with spaces else: out += " ".rjust(max_name_len + sep_len - name_len) # format the actual value, if there is one if actual != None: out += Logs.colors.BOLD + w.fill(val_to_str(actual)) + Logs.colors.NORMAL + "\n" + w.subsequent_indent # format the default value default_fmt = val_to_str(default) if actual != None: default_fmt = "default: " + default_fmt out += Logs.colors.NORMAL + w.fill(default_fmt) + Logs.colors.NORMAL return out # Monkey-patch ConfigurationContext.execute() to have it store the review set. old_configure_execute = Configure.ConfigurationContext.execute def new_configure_execute(self): old_configure_execute(self) Context.create_context('review').store_review_set(new_review_set) Configure.ConfigurationContext.execute = new_configure_execute ldb-2.0.8/third_party/waf/waflib/extras/rst.py0000660000000000000000000001544713573675414021312 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Jérôme Carretero, 2013 (zougloub) """ reStructuredText support (experimental) Example:: def configure(conf): conf.load('rst') if not conf.env.RST2HTML: conf.fatal('The program rst2html is required') def build(bld): bld( features = 'rst', type = 'rst2html', # rst2html, rst2pdf, ... source = 'index.rst', # mandatory, the source deps = 'image.png', # to give additional non-trivial dependencies ) By default the tool looks for a set of programs in PATH. The tools are defined in `rst_progs`. To configure with a special program use:: $ RST2HTML=/path/to/rst2html waf configure This tool is experimental; don't hesitate to contribute to it. """ import re from waflib import Node, Utils, Task, Errors, Logs from waflib.TaskGen import feature, before_method rst_progs = "rst2html rst2xetex rst2latex rst2xml rst2pdf rst2s5 rst2man rst2odt rst2rtf".split() def parse_rst_node(task, node, nodes, names, seen, dirs=None): # TODO add extensibility, to handle custom rst include tags... if dirs is None: dirs = (node.parent,node.get_bld().parent) if node in seen: return seen.append(node) code = node.read() re_rst = re.compile(r'^\s*.. ((?P\|\S+\|) )?(?Pinclude|image|figure):: (?P.*)$', re.M) for match in re_rst.finditer(code): ipath = match.group('file') itype = match.group('type') Logs.debug('rst: visiting %s: %s', itype, ipath) found = False for d in dirs: Logs.debug('rst: looking for %s in %s', ipath, d.abspath()) found = d.find_node(ipath) if found: Logs.debug('rst: found %s as %s', ipath, found.abspath()) nodes.append((itype, found)) if itype == 'include': parse_rst_node(task, found, nodes, names, seen) break if not found: names.append((itype, ipath)) class docutils(Task.Task): """ Compile a rst file. """ def scan(self): """ A recursive regex-based scanner that finds rst dependencies. """ nodes = [] names = [] seen = [] node = self.inputs[0] if not node: return (nodes, names) parse_rst_node(self, node, nodes, names, seen) Logs.debug('rst: %r: found the following file deps: %r', self, nodes) if names: Logs.warn('rst: %r: could not find the following file deps: %r', self, names) return ([v for (t,v) in nodes], [v for (t,v) in names]) def check_status(self, msg, retcode): """ Check an exit status and raise an error with a particular message :param msg: message to display if the code is non-zero :type msg: string :param retcode: condition :type retcode: boolean """ if retcode != 0: raise Errors.WafError('%r command exit status %r' % (msg, retcode)) def run(self): """ Runs the rst compilation using docutils """ raise NotImplementedError() class rst2html(docutils): color = 'BLUE' def __init__(self, *args, **kw): docutils.__init__(self, *args, **kw) self.command = self.generator.env.RST2HTML self.attributes = ['stylesheet'] def scan(self): nodes, names = docutils.scan(self) for attribute in self.attributes: stylesheet = getattr(self.generator, attribute, None) if stylesheet is not None: ssnode = self.generator.to_nodes(stylesheet)[0] nodes.append(ssnode) Logs.debug('rst: adding dep to %s %s', attribute, stylesheet) return nodes, names def run(self): cwdn = self.outputs[0].parent src = self.inputs[0].path_from(cwdn) dst = self.outputs[0].path_from(cwdn) cmd = self.command + [src, dst] cmd += Utils.to_list(getattr(self.generator, 'options', [])) for attribute in self.attributes: stylesheet = getattr(self.generator, attribute, None) if stylesheet is not None: stylesheet = self.generator.to_nodes(stylesheet)[0] cmd += ['--%s' % attribute, stylesheet.path_from(cwdn)] return self.exec_command(cmd, cwd=cwdn.abspath()) class rst2s5(rst2html): def __init__(self, *args, **kw): rst2html.__init__(self, *args, **kw) self.command = self.generator.env.RST2S5 self.attributes = ['stylesheet'] class rst2latex(rst2html): def __init__(self, *args, **kw): rst2html.__init__(self, *args, **kw) self.command = self.generator.env.RST2LATEX self.attributes = ['stylesheet'] class rst2xetex(rst2html): def __init__(self, *args, **kw): rst2html.__init__(self, *args, **kw) self.command = self.generator.env.RST2XETEX self.attributes = ['stylesheet'] class rst2pdf(docutils): color = 'BLUE' def run(self): cwdn = self.outputs[0].parent src = self.inputs[0].path_from(cwdn) dst = self.outputs[0].path_from(cwdn) cmd = self.generator.env.RST2PDF + [src, '-o', dst] cmd += Utils.to_list(getattr(self.generator, 'options', [])) return self.exec_command(cmd, cwd=cwdn.abspath()) @feature('rst') @before_method('process_source') def apply_rst(self): """ Create :py:class:`rst` or other rst-related task objects """ if self.target: if isinstance(self.target, Node.Node): tgt = self.target elif isinstance(self.target, str): tgt = self.path.get_bld().make_node(self.target) else: self.bld.fatal("rst: Don't know how to build target name %s which is not a string or Node for %s" % (self.target, self)) else: tgt = None tsk_type = getattr(self, 'type', None) src = self.to_nodes(self.source) assert len(src) == 1 src = src[0] if tsk_type is not None and tgt is None: if tsk_type.startswith('rst2'): ext = tsk_type[4:] else: self.bld.fatal("rst: Could not detect the output file extension for %s" % self) tgt = src.change_ext('.%s' % ext) elif tsk_type is None and tgt is not None: out = tgt.name ext = out[out.rfind('.')+1:] self.type = 'rst2' + ext elif tsk_type is not None and tgt is not None: # the user knows what he wants pass else: self.bld.fatal("rst: Need to indicate task type or target name for %s" % self) deps_lst = [] if getattr(self, 'deps', None): deps = self.to_list(self.deps) for filename in deps: n = self.path.find_resource(filename) if not n: self.bld.fatal('Could not find %r for %r' % (filename, self)) if not n in deps_lst: deps_lst.append(n) try: task = self.create_task(self.type, src, tgt) except KeyError: self.bld.fatal("rst: Task of type %s not implemented (created by %s)" % (self.type, self)) task.env = self.env # add the manual dependencies if deps_lst: try: lst = self.bld.node_deps[task.uid()] for n in deps_lst: if not n in lst: lst.append(n) except KeyError: self.bld.node_deps[task.uid()] = deps_lst inst_to = getattr(self, 'install_path', None) if inst_to: self.install_task = self.add_install_files(install_to=inst_to, install_from=task.outputs[:]) self.source = [] def configure(self): """ Try to find the rst programs. Do not raise any error if they are not found. You'll have to use additional code in configure() to die if programs were not found. """ for p in rst_progs: self.find_program(p, mandatory=False) ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py0000660000000000000000000001157513573675414023352 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Hans-Martin von Gaudecker, 2012 """ Run a Stata do-script in the directory specified by **ctx.bldnode**. The first and only argument will be the name of the do-script (no extension), which can be accessed inside the do-script by the local macro `1'. Useful for keeping a log file. The tool uses the log file that is automatically kept by Stata only for error-catching purposes, it will be destroyed if the task finished without error. In case of an error in **some_script.do**, you can inspect it as **some_script.log** in the **ctx.bldnode** directory. Note that Stata will not return an error code if it exits abnormally -- catching errors relies on parsing the log file mentioned before. Should the parser behave incorrectly please send an email to hmgaudecker [at] gmail. **WARNING** The tool will not work if multiple do-scripts of the same name---but in different directories---are run at the same time! Avoid this situation. Usage:: ctx(features='run_do_script', source='some_script.do', target=['some_table.tex', 'some_figure.eps'], deps='some_data.csv') """ import os, re, sys from waflib import Task, TaskGen, Logs if sys.platform == 'darwin': STATA_COMMANDS = ['Stata64MP', 'StataMP', 'Stata64SE', 'StataSE', 'Stata64', 'Stata'] STATAFLAGS = '-e -q do' STATAENCODING = 'MacRoman' elif sys.platform.startswith('linux'): STATA_COMMANDS = ['stata-mp', 'stata-se', 'stata'] STATAFLAGS = '-b -q do' # Not sure whether this is correct... STATAENCODING = 'Latin-1' elif sys.platform.lower().startswith('win'): STATA_COMMANDS = ['StataMP-64', 'StataMP-ia', 'StataMP', 'StataSE-64', 'StataSE-ia', 'StataSE', 'Stata-64', 'Stata-ia', 'Stata.e', 'WMPSTATA', 'WSESTATA', 'WSTATA'] STATAFLAGS = '/e do' STATAENCODING = 'Latin-1' else: raise Exception("Unknown sys.platform: %s " % sys.platform) def configure(ctx): ctx.find_program(STATA_COMMANDS, var='STATACMD', errmsg="""\n No Stata executable found!\n\n If Stata is needed:\n 1) Check the settings of your system path. 2) Note we are looking for Stata executables called: %s If yours has a different name, please report to hmgaudecker [at] gmail\n Else:\n Do not load the 'run_do_script' tool in the main wscript.\n\n""" % STATA_COMMANDS) ctx.env.STATAFLAGS = STATAFLAGS ctx.env.STATAENCODING = STATAENCODING class run_do_script_base(Task.Task): """Run a Stata do-script from the bldnode directory.""" run_str = '"${STATACMD}" ${STATAFLAGS} "${SRC[0].abspath()}" "${DOFILETRUNK}"' shell = True class run_do_script(run_do_script_base): """Use the log file automatically kept by Stata for error-catching. Erase it if the task finished without error. If not, it will show up as do_script.log in the bldnode directory. """ def run(self): run_do_script_base.run(self) ret, log_tail = self.check_erase_log_file() if ret: Logs.error("""Running Stata on %r failed with code %r.\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", self.inputs[0], ret, self.env.LOGFILEPATH, log_tail) return ret def check_erase_log_file(self): """Parse Stata's default log file and erase it if everything okay. Parser is based on Brendan Halpin's shell script found here: http://teaching.sociology.ul.ie/bhalpin/wordpress/?p=122 """ if sys.version_info.major >= 3: kwargs = {'file': self.env.LOGFILEPATH, 'mode': 'r', 'encoding': self.env.STATAENCODING} else: kwargs = {'name': self.env.LOGFILEPATH, 'mode': 'r'} with open(**kwargs) as log: log_tail = log.readlines()[-10:] for line in log_tail: error_found = re.match(r"r\(([0-9]+)\)", line) if error_found: return error_found.group(1), ''.join(log_tail) else: pass # Only end up here if the parser did not identify an error. os.remove(self.env.LOGFILEPATH) return None, None @TaskGen.feature('run_do_script') @TaskGen.before_method('process_source') def apply_run_do_script(tg): """Task generator customising the options etc. to call Stata in batch mode for running a do-script. """ # Convert sources and targets to nodes src_node = tg.path.find_resource(tg.source) tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] tsk = tg.create_task('run_do_script', src=src_node, tgt=tgt_nodes) tsk.env.DOFILETRUNK = os.path.splitext(src_node.name)[0] tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s.log' % (tsk.env.DOFILETRUNK)) # dependencies (if the attribute 'deps' changes, trigger a recompilation) for x in tg.to_list(getattr(tg, 'deps', [])): node = tg.path.find_resource(x) if not node: tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) tsk.dep_nodes.append(node) Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) # Bypass the execution of process_source by setting the source to an empty list tg.source = [] ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py0000660000000000000000000000577213573675414023206 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Hans-Martin von Gaudecker, 2012 """ Run a Matlab script. Note that the script is run in the directory where it lives -- Matlab won't allow it any other way. For error-catching purposes, keep an own log-file that is destroyed if the task finished without error. If not, it will show up as mscript_[index].log in the bldnode directory. Usage:: ctx(features='run_m_script', source='some_script.m', target=['some_table.tex', 'some_figure.eps'], deps='some_data.mat') """ import os, sys from waflib import Task, TaskGen, Logs MATLAB_COMMANDS = ['matlab'] def configure(ctx): ctx.find_program(MATLAB_COMMANDS, var='MATLABCMD', errmsg = """\n No Matlab executable found!\n\n If Matlab is needed:\n 1) Check the settings of your system path. 2) Note we are looking for Matlab executables called: %s If yours has a different name, please report to hmgaudecker [at] gmail\n Else:\n Do not load the 'run_m_script' tool in the main wscript.\n\n""" % MATLAB_COMMANDS) ctx.env.MATLABFLAGS = '-wait -nojvm -nosplash -minimize' class run_m_script_base(Task.Task): """Run a Matlab script.""" run_str = '"${MATLABCMD}" ${MATLABFLAGS} -logfile "${LOGFILEPATH}" -r "try, ${MSCRIPTTRUNK}, exit(0), catch err, disp(err.getReport()), exit(1), end"' shell = True class run_m_script(run_m_script_base): """Erase the Matlab overall log file if everything went okay, else raise an error and print its 10 last lines. """ def run(self): ret = run_m_script_base.run(self) logfile = self.env.LOGFILEPATH if ret: mode = 'r' if sys.version_info.major >= 3: mode = 'rb' with open(logfile, mode=mode) as f: tail = f.readlines()[-10:] Logs.error("""Running Matlab on %r returned the error %r\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", self.inputs[0], ret, logfile, '\n'.join(tail)) else: os.remove(logfile) return ret @TaskGen.feature('run_m_script') @TaskGen.before_method('process_source') def apply_run_m_script(tg): """Task generator customising the options etc. to call Matlab in batch mode for running a m-script. """ # Convert sources and targets to nodes src_node = tg.path.find_resource(tg.source) tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] tsk = tg.create_task('run_m_script', src=src_node, tgt=tgt_nodes) tsk.cwd = src_node.parent.abspath() tsk.env.MSCRIPTTRUNK = os.path.splitext(src_node.name)[0] tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s_%d.log' % (tsk.env.MSCRIPTTRUNK, tg.idx)) # dependencies (if the attribute 'deps' changes, trigger a recompilation) for x in tg.to_list(getattr(tg, 'deps', [])): node = tg.path.find_resource(x) if not node: tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) tsk.dep_nodes.append(node) Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) # Bypass the execution of process_source by setting the source to an empty list tg.source = [] ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py0000660000000000000000000000741413573675414023375 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Hans-Martin von Gaudecker, 2012 """ Run a Python script in the directory specified by **ctx.bldnode**. Select a Python version by specifying the **version** keyword for the task generator instance as integer 2 or 3. Default is 3. If the build environment has an attribute "PROJECT_PATHS" with a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH. Same a string passed to the optional **add_to_pythonpath** keyword (appended after the PROJECT_ROOT). Usage:: ctx(features='run_py_script', version=3, source='some_script.py', target=['some_table.tex', 'some_figure.eps'], deps='some_data.csv', add_to_pythonpath='src/some/library') """ import os, re from waflib import Task, TaskGen, Logs def configure(conf): """TODO: Might need to be updated for Windows once "PEP 397":http://www.python.org/dev/peps/pep-0397/ is settled. """ conf.find_program('python', var='PY2CMD', mandatory=False) conf.find_program('python3', var='PY3CMD', mandatory=False) if not conf.env.PY2CMD and not conf.env.PY3CMD: conf.fatal("No Python interpreter found!") class run_py_2_script(Task.Task): """Run a Python 2 script.""" run_str = '${PY2CMD} ${SRC[0].abspath()}' shell=True class run_py_3_script(Task.Task): """Run a Python 3 script.""" run_str = '${PY3CMD} ${SRC[0].abspath()}' shell=True @TaskGen.feature('run_py_script') @TaskGen.before_method('process_source') def apply_run_py_script(tg): """Task generator for running either Python 2 or Python 3 on a single script. Attributes: * source -- A **single** source node or string. (required) * target -- A single target or list of targets (nodes or strings) * deps -- A single dependency or list of dependencies (nodes or strings) * add_to_pythonpath -- A string that will be appended to the PYTHONPATH environment variable If the build environment has an attribute "PROJECT_PATHS" with a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH. """ # Set the Python version to use, default to 3. v = getattr(tg, 'version', 3) if v not in (2, 3): raise ValueError("Specify the 'version' attribute for run_py_script task generator as integer 2 or 3.\n Got: %s" %v) # Convert sources and targets to nodes src_node = tg.path.find_resource(tg.source) tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] # Create the task. tsk = tg.create_task('run_py_%d_script' %v, src=src_node, tgt=tgt_nodes) # custom execution environment # TODO use a list and os.sep.join(lst) at the end instead of concatenating strings tsk.env.env = dict(os.environ) tsk.env.env['PYTHONPATH'] = tsk.env.env.get('PYTHONPATH', '') project_paths = getattr(tsk.env, 'PROJECT_PATHS', None) if project_paths and 'PROJECT_ROOT' in project_paths: tsk.env.env['PYTHONPATH'] += os.pathsep + project_paths['PROJECT_ROOT'].abspath() if getattr(tg, 'add_to_pythonpath', None): tsk.env.env['PYTHONPATH'] += os.pathsep + tg.add_to_pythonpath # Clean up the PYTHONPATH -- replace double occurrences of path separator tsk.env.env['PYTHONPATH'] = re.sub(os.pathsep + '+', os.pathsep, tsk.env.env['PYTHONPATH']) # Clean up the PYTHONPATH -- doesn't like starting with path separator if tsk.env.env['PYTHONPATH'].startswith(os.pathsep): tsk.env.env['PYTHONPATH'] = tsk.env.env['PYTHONPATH'][1:] # dependencies (if the attribute 'deps' changes, trigger a recompilation) for x in tg.to_list(getattr(tg, 'deps', [])): node = tg.path.find_resource(x) if not node: tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) tsk.dep_nodes.append(node) Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) # Bypass the execution of process_source by setting the source to an empty list tg.source = [] ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py0000660000000000000000000000531613573675414023205 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Hans-Martin von Gaudecker, 2012 """ Run a R script in the directory specified by **ctx.bldnode**. For error-catching purposes, keep an own log-file that is destroyed if the task finished without error. If not, it will show up as rscript_[index].log in the bldnode directory. Usage:: ctx(features='run_r_script', source='some_script.r', target=['some_table.tex', 'some_figure.eps'], deps='some_data.csv') """ import os, sys from waflib import Task, TaskGen, Logs R_COMMANDS = ['RTerm', 'R', 'r'] def configure(ctx): ctx.find_program(R_COMMANDS, var='RCMD', errmsg = """\n No R executable found!\n\n If R is needed:\n 1) Check the settings of your system path. 2) Note we are looking for R executables called: %s If yours has a different name, please report to hmgaudecker [at] gmail\n Else:\n Do not load the 'run_r_script' tool in the main wscript.\n\n""" % R_COMMANDS) ctx.env.RFLAGS = 'CMD BATCH --slave' class run_r_script_base(Task.Task): """Run a R script.""" run_str = '"${RCMD}" ${RFLAGS} "${SRC[0].abspath()}" "${LOGFILEPATH}"' shell = True class run_r_script(run_r_script_base): """Erase the R overall log file if everything went okay, else raise an error and print its 10 last lines. """ def run(self): ret = run_r_script_base.run(self) logfile = self.env.LOGFILEPATH if ret: mode = 'r' if sys.version_info.major >= 3: mode = 'rb' with open(logfile, mode=mode) as f: tail = f.readlines()[-10:] Logs.error("""Running R on %r returned the error %r\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", self.inputs[0], ret, logfile, '\n'.join(tail)) else: os.remove(logfile) return ret @TaskGen.feature('run_r_script') @TaskGen.before_method('process_source') def apply_run_r_script(tg): """Task generator customising the options etc. to call R in batch mode for running a R script. """ # Convert sources and targets to nodes src_node = tg.path.find_resource(tg.source) tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] tsk = tg.create_task('run_r_script', src=src_node, tgt=tgt_nodes) tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s_%d.log' % (os.path.splitext(src_node.name)[0], tg.idx)) # dependencies (if the attribute 'deps' changes, trigger a recompilation) for x in tg.to_list(getattr(tg, 'deps', [])): node = tg.path.find_resource(x) if not node: tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) tsk.dep_nodes.append(node) Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) # Bypass the execution of process_source by setting the source to an empty list tg.source = [] ldb-2.0.8/third_party/waf/waflib/extras/sas.py0000660000000000000000000000363213573675414021261 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Mark Coggeshall, 2010 "SAS support" import os from waflib import Task, Errors, Logs from waflib.TaskGen import feature, before_method sas_fun, _ = Task.compile_fun('sas -sysin ${SRCFILE} -log ${LOGFILE} -print ${LSTFILE}', shell=False) class sas(Task.Task): vars = ['SAS', 'SASFLAGS'] def run(task): command = 'SAS' fun = sas_fun node = task.inputs[0] logfilenode = node.change_ext('.log') lstfilenode = node.change_ext('.lst') # set the cwd task.cwd = task.inputs[0].parent.get_src().abspath() Logs.debug('runner: %r on %r', command, node) SASINPUTS = node.parent.get_bld().abspath() + os.pathsep + node.parent.get_src().abspath() + os.pathsep task.env.env = {'SASINPUTS': SASINPUTS} task.env.SRCFILE = node.abspath() task.env.LOGFILE = logfilenode.abspath() task.env.LSTFILE = lstfilenode.abspath() ret = fun(task) if ret: Logs.error('Running %s on %r returned a non-zero exit', command, node) Logs.error('SRCFILE = %r', node) Logs.error('LOGFILE = %r', logfilenode) Logs.error('LSTFILE = %r', lstfilenode) return ret @feature('sas') @before_method('process_source') def apply_sas(self): if not getattr(self, 'type', None) in ('sas',): self.type = 'sas' self.env['logdir'] = getattr(self, 'logdir', 'log') self.env['lstdir'] = getattr(self, 'lstdir', 'lst') deps_lst = [] if getattr(self, 'deps', None): deps = self.to_list(self.deps) for filename in deps: n = self.path.find_resource(filename) if not n: n = self.bld.root.find_resource(filename) if not n: raise Errors.WafError('cannot find input file %s for processing' % filename) if not n in deps_lst: deps_lst.append(n) for node in self.to_nodes(self.source): if self.type == 'sas': task = self.create_task('sas', src=node) task.dep_nodes = deps_lst self.source = [] def configure(self): self.find_program('sas', var='SAS', mandatory=False) ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py0000660000000000000000000000416113573675414024356 0ustar rootroot00000000000000#!/usr/bin/python # encoding: utf-8 # vim: tabstop=4 noexpandtab """ Create a satellite assembly from "*.??.txt" files. ?? stands for a language code. The projects Resources subfolder contains resources.??.txt string files for several languages. The build folder will hold the satellite assemblies as ./??/ExeName.resources.dll #gen becomes template (It is called gen because it also uses resx.py). bld(source='Resources/resources.de.txt',gen=ExeName) """ import os, re from waflib import Task from waflib.TaskGen import feature,before_method class al(Task.Task): run_str = '${AL} ${ALFLAGS}' @feature('satellite_assembly') @before_method('process_source') def satellite_assembly(self): if not getattr(self, 'gen', None): self.bld.fatal('satellite_assembly needs a template assembly provided with the "gen" parameter') res_lang = re.compile(r'(.*)\.(\w\w)\.(?:resx|txt)',flags=re.I) # self.source can contain node objects, so this will break in one way or another self.source = self.to_list(self.source) for i, x in enumerate(self.source): #x = 'resources/resources.de.resx' #x = 'resources/resources.de.txt' mo = res_lang.match(x) if mo: template = os.path.splitext(self.gen)[0] templatedir, templatename = os.path.split(template) res = mo.group(1) lang = mo.group(2) #./Resources/resources.de.resources resources = self.path.find_or_declare(res+ '.' + lang + '.resources') self.create_task('resgen', self.to_nodes(x), [resources]) #./de/Exename.resources.dll satellite = self.path.find_or_declare(os.path.join(templatedir,lang,templatename) + '.resources.dll') tsk = self.create_task('al',[resources],[satellite]) tsk.env.append_value('ALFLAGS','/template:'+os.path.join(self.path.relpath(),self.gen)) tsk.env.append_value('ALFLAGS','/embed:'+resources.relpath()) tsk.env.append_value('ALFLAGS','/culture:'+lang) tsk.env.append_value('ALFLAGS','/out:'+satellite.relpath()) self.source[i] = None # remove the None elements that we just substituted self.source = list(filter(lambda x:x, self.source)) def configure(ctx): ctx.find_program('al', var='AL', mandatory=True) ctx.load('resx') ldb-2.0.8/third_party/waf/waflib/extras/scala.py0000660000000000000000000000637713573675414021567 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010 (ita) """ Scala support scalac outputs files a bit where it wants to """ import os from waflib import Task, Utils, Node from waflib.TaskGen import feature, before_method, after_method from waflib.Tools import ccroot ccroot.USELIB_VARS['scalac'] = set(['CLASSPATH', 'SCALACFLAGS']) from waflib.Tools import javaw @feature('scalac') @before_method('process_source') def apply_scalac(self): Utils.def_attrs(self, jarname='', classpath='', sourcepath='.', srcdir='.', jar_mf_attributes={}, jar_mf_classpath=[]) outdir = getattr(self, 'outdir', None) if outdir: if not isinstance(outdir, Node.Node): outdir = self.path.get_bld().make_node(self.outdir) else: outdir = self.path.get_bld() outdir.mkdir() self.env['OUTDIR'] = outdir.abspath() self.scalac_task = tsk = self.create_task('scalac') tmp = [] srcdir = getattr(self, 'srcdir', '') if isinstance(srcdir, Node.Node): srcdir = [srcdir] for x in Utils.to_list(srcdir): if isinstance(x, Node.Node): y = x else: y = self.path.find_dir(x) if not y: self.bld.fatal('Could not find the folder %s from %s' % (x, self.path)) tmp.append(y) tsk.srcdir = tmp # reuse some code feature('scalac')(javaw.use_javac_files) after_method('apply_scalac')(javaw.use_javac_files) feature('scalac')(javaw.set_classpath) after_method('apply_scalac', 'use_scalac_files')(javaw.set_classpath) SOURCE_RE = '**/*.scala' class scalac(javaw.javac): color = 'GREEN' vars = ['CLASSPATH', 'SCALACFLAGS', 'SCALAC', 'OUTDIR'] def runnable_status(self): """ Wait for dependent tasks to be complete, then read the file system to find the input nodes. """ for t in self.run_after: if not t.hasrun: return Task.ASK_LATER if not self.inputs: global SOURCE_RE self.inputs = [] for x in self.srcdir: self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False)) return super(javaw.javac, self).runnable_status() def run(self): """ Execute the scalac compiler """ env = self.env gen = self.generator bld = gen.bld wd = bld.bldnode.abspath() def to_list(xx): if isinstance(xx, str): return [xx] return xx self.last_cmd = lst = [] lst.extend(to_list(env['SCALAC'])) lst.extend(['-classpath']) lst.extend(to_list(env['CLASSPATH'])) lst.extend(['-d']) lst.extend(to_list(env['OUTDIR'])) lst.extend(to_list(env['SCALACFLAGS'])) lst.extend([a.abspath() for a in self.inputs]) lst = [x for x in lst if x] try: self.out = self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, output=0, quiet=0)[1] except: self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None) def configure(self): """ Detect the scalac program """ # If SCALA_HOME is set, we prepend it to the path list java_path = self.environ['PATH'].split(os.pathsep) v = self.env if 'SCALA_HOME' in self.environ: java_path = [os.path.join(self.environ['SCALA_HOME'], 'bin')] + java_path self.env['SCALA_HOME'] = [self.environ['SCALA_HOME']] for x in 'scalac scala'.split(): self.find_program(x, var=x.upper(), path_list=java_path) if 'CLASSPATH' in self.environ: v['CLASSPATH'] = self.environ['CLASSPATH'] v.SCALACFLAGS = ['-verbose'] if not v['SCALAC']: self.fatal('scalac is required for compiling scala classes') ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py0000660000000000000000000000537613573675414022256 0ustar rootroot00000000000000#! /usr/bin/env python # Thomas Nagy, 2011 (ita) """ Create _moc.cpp files The builds are 30-40% faster when .moc files are included, you should NOT use this tool. If you really really want it: def configure(conf): conf.load('compiler_cxx qt4') conf.load('slow_qt4') See playground/slow_qt/wscript for a complete example. """ from waflib.TaskGen import extension from waflib import Task import waflib.Tools.qt4 import waflib.Tools.cxx @extension(*waflib.Tools.qt4.EXT_QT4) def cxx_hook(self, node): return self.create_compiled_task('cxx_qt', node) class cxx_qt(Task.classes['cxx']): def runnable_status(self): ret = Task.classes['cxx'].runnable_status(self) if ret != Task.ASK_LATER and not getattr(self, 'moc_done', None): try: cache = self.generator.moc_cache except AttributeError: cache = self.generator.moc_cache = {} deps = self.generator.bld.node_deps[self.uid()] for x in [self.inputs[0]] + deps: if x.read().find('Q_OBJECT') > 0: # process "foo.h -> foo.moc" only if "foo.cpp" is in the sources for the current task generator # this code will work because it is in the main thread (runnable_status) if x.name.rfind('.') > -1: # a .h file... name = x.name[:x.name.rfind('.')] for tsk in self.generator.compiled_tasks: if tsk.inputs and tsk.inputs[0].name.startswith(name): break else: # no corresponding file, continue continue # the file foo.cpp could be compiled for a static and a shared library - hence the %number in the name cxx_node = x.parent.get_bld().make_node(x.name.replace('.', '_') + '_%d_moc.cpp' % self.generator.idx) if cxx_node in cache: continue cache[cxx_node] = self tsk = Task.classes['moc'](env=self.env, generator=self.generator) tsk.set_inputs(x) tsk.set_outputs(cxx_node) if x.name.endswith('.cpp'): # moc is trying to be too smart but it is too dumb: # why forcing the #include when Q_OBJECT is in the cpp file? gen = self.generator.bld.producer gen.outstanding.append(tsk) gen.total += 1 self.set_run_after(tsk) else: cxxtsk = Task.classes['cxx'](env=self.env, generator=self.generator) cxxtsk.set_inputs(tsk.outputs) cxxtsk.set_outputs(cxx_node.change_ext('.o')) cxxtsk.set_run_after(tsk) try: self.more_tasks.extend([tsk, cxxtsk]) except AttributeError: self.more_tasks = [tsk, cxxtsk] try: link = self.generator.link_task except AttributeError: pass else: link.set_run_after(cxxtsk) link.inputs.extend(cxxtsk.outputs) link.inputs.sort(key=lambda x: x.abspath()) self.moc_done = True for t in self.run_after: if not t.hasrun: return Task.ASK_LATER return ret ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py0000660000000000000000000000452513573675414023337 0ustar rootroot00000000000000#! /usr/bin/env python # per rosengren 2011 from waflib.TaskGen import feature, after_method from waflib.Task import Task, always_run from os.path import basename, isabs from os import tmpfile, linesep def options(opt): grp = opt.add_option_group('Softlink Libraries Options') grp.add_option('--exclude', default='/usr/lib,/lib', help='No symbolic links are created for libs within [%default]') def configure(cnf): cnf.find_program('ldd') if not cnf.env.SOFTLINK_EXCLUDE: cnf.env.SOFTLINK_EXCLUDE = cnf.options.exclude.split(',') @feature('softlink_libs') @after_method('process_rule') def add_finder(self): tgt = self.path.find_or_declare(self.target) self.create_task('sll_finder', tgt=tgt) self.create_task('sll_installer', tgt=tgt) always_run(sll_installer) class sll_finder(Task): ext_out = 'softlink_libs' def run(self): bld = self.generator.bld linked=[] target_paths = [] for g in bld.groups: for tgen in g: # FIXME it might be better to check if there is a link_task (getattr?) target_paths += [tgen.path.get_bld().bldpath()] linked += [t.outputs[0].bldpath() for t in getattr(tgen, 'tasks', []) if t.__class__.__name__ in ['cprogram', 'cshlib', 'cxxprogram', 'cxxshlib']] lib_list = [] if len(linked): cmd = [self.env.LDD] + linked # FIXME add DYLD_LIBRARY_PATH+PATH for osx+win32 ldd_env = {'LD_LIBRARY_PATH': ':'.join(target_paths + self.env.LIBPATH)} # FIXME the with syntax will not work in python 2 with tmpfile() as result: self.exec_command(cmd, env=ldd_env, stdout=result) result.seek(0) for line in result.readlines(): words = line.split() if len(words) < 3 or words[1] != '=>': continue lib = words[2] if lib == 'not': continue if any([lib.startswith(p) for p in [bld.bldnode.abspath(), '('] + self.env.SOFTLINK_EXCLUDE]): continue if not isabs(lib): continue lib_list.append(lib) lib_list = sorted(set(lib_list)) self.outputs[0].write(linesep.join(lib_list + self.env.DYNAMIC_LIBS)) return 0 class sll_installer(Task): ext_in = 'softlink_libs' def run(self): tgt = self.outputs[0] self.generator.bld.install_files('${LIBDIR}', tgt, postpone=False) lib_list=tgt.read().split() for lib in lib_list: self.generator.bld.symlink_as('${LIBDIR}/'+basename(lib), lib, postpone=False) return 0 ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py0000660000000000000000000000547413573675414022012 0ustar rootroot00000000000000"""Support for Sphinx documentation This is a wrapper for sphinx-build program. Please note that sphinx-build supports only one output format which can passed to build via sphinx_output_format attribute. The default output format is html. Example wscript: def configure(cnf): conf.load('sphinx') def build(bld): bld( features='sphinx', sphinx_source='sources', # path to source directory sphinx_options='-a -v', # sphinx-build program additional options sphinx_output_format='man' # output format of sphinx documentation ) """ from waflib.Node import Node from waflib import Utils from waflib.Task import Task from waflib.TaskGen import feature, after_method def configure(cnf): """Check if sphinx-build program is available and loads gnu_dirs tool.""" cnf.find_program('sphinx-build', var='SPHINX_BUILD', mandatory=False) cnf.load('gnu_dirs') @feature('sphinx') def build_sphinx(self): """Builds sphinx sources. """ if not self.env.SPHINX_BUILD: self.bld.fatal('Program SPHINX_BUILD not defined.') if not getattr(self, 'sphinx_source', None): self.bld.fatal('Attribute sphinx_source not defined.') if not isinstance(self.sphinx_source, Node): self.sphinx_source = self.path.find_node(self.sphinx_source) if not self.sphinx_source: self.bld.fatal('Can\'t find sphinx_source: %r' % self.sphinx_source) Utils.def_attrs(self, sphinx_output_format='html') self.env.SPHINX_OUTPUT_FORMAT = self.sphinx_output_format self.env.SPHINX_OPTIONS = getattr(self, 'sphinx_options', []) for source_file in self.sphinx_source.ant_glob('**/*'): self.bld.add_manual_dependency(self.sphinx_source, source_file) sphinx_build_task = self.create_task('SphinxBuildingTask') sphinx_build_task.set_inputs(self.sphinx_source) sphinx_build_task.set_outputs(self.path.get_bld()) # the sphinx-build results are in directory sphinx_output_directory = self.path.get_bld().make_node(self.env.SPHINX_OUTPUT_FORMAT) sphinx_output_directory.mkdir() Utils.def_attrs(self, install_path=get_install_path(self)) self.add_install_files(install_to=self.install_path, install_from=sphinx_output_directory.ant_glob('**/*'), cwd=sphinx_output_directory, relative_trick=True) def get_install_path(tg): if tg.env.SPHINX_OUTPUT_FORMAT == 'man': return tg.env.MANDIR elif tg.env.SPHINX_OUTPUT_FORMAT == 'info': return tg.env.INFODIR else: return tg.env.DOCDIR class SphinxBuildingTask(Task): color = 'BOLD' run_str = '${SPHINX_BUILD} -M ${SPHINX_OUTPUT_FORMAT} ${SRC} ${TGT} ${SPHINX_OPTIONS}' def keyword(self): return 'Compiling (%s)' % self.env.SPHINX_OUTPUT_FORMAT ldb-2.0.8/third_party/waf/waflib/extras/stale.py0000660000000000000000000000437113573675414021604 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: UTF-8 # Thomas Nagy, 2006-2015 (ita) """ Add a pre-build hook to remove build files (declared in the system) that do not have a corresponding target This can be used for example to remove the targets that have changed name without performing a full 'waf clean' Of course, it will only work if there are no dynamically generated nodes/tasks, in which case the method will have to be modified to exclude some folders for example. Make sure to set bld.post_mode = waflib.Build.POST_AT_ONCE """ from waflib import Logs, Build from waflib.Runner import Parallel DYNAMIC_EXT = [] # add your non-cleanable files/extensions here MOC_H_EXTS = '.cpp .cxx .hpp .hxx .h'.split() def can_delete(node): """Imperfect moc cleanup which does not look for a Q_OBJECT macro in the files""" if not node.name.endswith('.moc'): return True base = node.name[:-4] p1 = node.parent.get_src() p2 = node.parent.get_bld() for k in MOC_H_EXTS: h_name = base + k n = p1.search_node(h_name) if n: return False n = p2.search_node(h_name) if n: return False # foo.cpp.moc, foo.h.moc, etc. if base.endswith(k): return False return True # recursion over the nodes to find the stale files def stale_rec(node, nodes): if node.abspath() in node.ctx.env[Build.CFG_FILES]: return if getattr(node, 'children', []): for x in node.children.values(): if x.name != "c4che": stale_rec(x, nodes) else: for ext in DYNAMIC_EXT: if node.name.endswith(ext): break else: if not node in nodes: if can_delete(node): Logs.warn('Removing stale file -> %r', node) node.delete() old = Parallel.refill_task_list def refill_task_list(self): iit = old(self) bld = self.bld # execute this operation only once if getattr(self, 'stale_done', False): return iit self.stale_done = True # this does not work in partial builds if bld.targets != '*': return iit # this does not work in dynamic builds if getattr(bld, 'post_mode') == Build.POST_AT_ONCE: return iit # obtain the nodes to use during the build nodes = [] for tasks in bld.groups: for x in tasks: try: nodes.extend(x.outputs) except AttributeError: pass stale_rec(bld.bldnode, nodes) return iit Parallel.refill_task_list = refill_task_list ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py0000660000000000000000000001000613573675414022621 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2015 (ita) """ Execute tasks through strace to obtain dependencies after the process is run. This scheme is similar to that of the Fabricate script. To use:: def configure(conf): conf.load('strace') WARNING: * This will not work when advanced scanners are needed (qt4/qt5) * The overhead of running 'strace' is significant (56s -> 1m29s) * It will not work on Windows :-) """ import os, re, threading from waflib import Task, Logs, Utils #TRACECALLS = 'trace=access,chdir,clone,creat,execve,exit_group,fork,lstat,lstat64,mkdir,open,rename,stat,stat64,symlink,vfork' TRACECALLS = 'trace=process,file' BANNED = ('/tmp', '/proc', '/sys', '/dev') s_process = r'(?:clone|fork|vfork)\(.*?(?P\d+)' s_file = r'(?P\w+)\("(?P([^"\\]|\\.)*)"(.*)' re_lines = re.compile(r'^(?P\d+)\s+(?:(?:%s)|(?:%s))\r*$' % (s_file, s_process), re.IGNORECASE | re.MULTILINE) strace_lock = threading.Lock() def configure(conf): conf.find_program('strace') def task_method(func): # Decorator function to bind/replace methods on the base Task class # # The methods Task.exec_command and Task.sig_implicit_deps already exists and are rarely overridden # we thus expect that we are the only ones doing this try: setattr(Task.Task, 'nostrace_%s' % func.__name__, getattr(Task.Task, func.__name__)) except AttributeError: pass setattr(Task.Task, func.__name__, func) return func @task_method def get_strace_file(self): try: return self.strace_file except AttributeError: pass if self.outputs: ret = self.outputs[0].abspath() + '.strace' else: ret = '%s%s%d%s' % (self.generator.bld.bldnode.abspath(), os.sep, id(self), '.strace') self.strace_file = ret return ret @task_method def get_strace_args(self): return (self.env.STRACE or ['strace']) + ['-e', TRACECALLS, '-f', '-o', self.get_strace_file()] @task_method def exec_command(self, cmd, **kw): bld = self.generator.bld if not 'cwd' in kw: kw['cwd'] = self.get_cwd() args = self.get_strace_args() fname = self.get_strace_file() if isinstance(cmd, list): cmd = args + cmd else: cmd = '%s %s' % (' '.join(args), cmd) try: ret = bld.exec_command(cmd, **kw) finally: if not ret: self.parse_strace_deps(fname, kw['cwd']) return ret @task_method def sig_implicit_deps(self): # bypass the scanner functions return @task_method def parse_strace_deps(self, path, cwd): # uncomment the following line to disable the dependencies and force a file scan # return try: cnt = Utils.readf(path) finally: try: os.remove(path) except OSError: pass if not isinstance(cwd, str): cwd = cwd.abspath() nodes = [] bld = self.generator.bld try: cache = bld.strace_cache except AttributeError: cache = bld.strace_cache = {} # chdir and relative paths pid_to_cwd = {} global BANNED done = set() for m in re.finditer(re_lines, cnt): # scraping the output of strace pid = m.group('pid') if m.group('npid'): npid = m.group('npid') pid_to_cwd[npid] = pid_to_cwd.get(pid, cwd) continue p = m.group('path').replace('\\"', '"') if p == '.' or m.group().find('= -1 ENOENT') > -1: # just to speed it up a bit continue if not os.path.isabs(p): p = os.path.join(pid_to_cwd.get(pid, cwd), p) call = m.group('call') if call == 'chdir': pid_to_cwd[pid] = p continue if p in done: continue done.add(p) for x in BANNED: if p.startswith(x): break else: if p.endswith('/') or os.path.isdir(p): continue try: node = cache[p] except KeyError: strace_lock.acquire() try: cache[p] = node = bld.root.find_node(p) if not node: continue finally: strace_lock.release() nodes.append(node) # record the dependencies then force the task signature recalculation for next time if Logs.verbose: Logs.debug('deps: real scanner for %r returned %r', self, nodes) bld = self.generator.bld bld.node_deps[self.uid()] = nodes bld.raw_deps[self.uid()] = [] try: del self.cache_sig except AttributeError: pass self.signature() ldb-2.0.8/third_party/waf/waflib/extras/swig.py0000660000000000000000000001415413573675414021445 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: UTF-8 # Petar Forai # Thomas Nagy 2008-2010 (ita) import re from waflib import Task, Logs from waflib.TaskGen import extension, feature, after_method from waflib.Configure import conf from waflib.Tools import c_preproc """ tasks have to be added dynamically: - swig interface files may be created at runtime - the module name may be unknown in advance """ SWIG_EXTS = ['.swig', '.i'] re_module = re.compile(r'%module(?:\s*\(.*\))?\s+(.+)', re.M) re_1 = re.compile(r'^%module.*?\s+([\w]+)\s*?$', re.M) re_2 = re.compile(r'[#%](?:include|import(?:\(module=".*"\))+|python(?:begin|code)) [<"](.*)[">]', re.M) class swig(Task.Task): color = 'BLUE' run_str = '${SWIG} ${SWIGFLAGS} ${SWIGPATH_ST:INCPATHS} ${SWIGDEF_ST:DEFINES} ${SRC}' ext_out = ['.h'] # might produce .h files although it is not mandatory vars = ['SWIG_VERSION', 'SWIGDEPS'] def runnable_status(self): for t in self.run_after: if not t.hasrun: return Task.ASK_LATER if not getattr(self, 'init_outputs', None): self.init_outputs = True if not getattr(self, 'module', None): # search the module name txt = self.inputs[0].read() m = re_module.search(txt) if not m: raise ValueError("could not find the swig module name") self.module = m.group(1) swig_c(self) # add the language-specific output files as nodes # call funs in the dict swig_langs for x in self.env['SWIGFLAGS']: # obtain the language x = x[1:] try: fun = swig_langs[x] except KeyError: pass else: fun(self) return super(swig, self).runnable_status() def scan(self): "scan for swig dependencies, climb the .i files" lst_src = [] seen = [] missing = [] to_see = [self.inputs[0]] while to_see: node = to_see.pop(0) if node in seen: continue seen.append(node) lst_src.append(node) # read the file code = node.read() code = c_preproc.re_nl.sub('', code) code = c_preproc.re_cpp.sub(c_preproc.repl, code) # find .i files and project headers names = re_2.findall(code) for n in names: for d in self.generator.includes_nodes + [node.parent]: u = d.find_resource(n) if u: to_see.append(u) break else: missing.append(n) return (lst_src, missing) # provide additional language processing swig_langs = {} def swigf(fun): swig_langs[fun.__name__.replace('swig_', '')] = fun return fun swig.swigf = swigf def swig_c(self): ext = '.swigwrap_%d.c' % self.generator.idx flags = self.env['SWIGFLAGS'] if '-c++' in flags: ext += 'xx' out_node = self.inputs[0].parent.find_or_declare(self.module + ext) if '-c++' in flags: c_tsk = self.generator.cxx_hook(out_node) else: c_tsk = self.generator.c_hook(out_node) c_tsk.set_run_after(self) # transfer weights from swig task to c task if getattr(self, 'weight', None): c_tsk.weight = self.weight if getattr(self, 'tree_weight', None): c_tsk.tree_weight = self.tree_weight try: self.more_tasks.append(c_tsk) except AttributeError: self.more_tasks = [c_tsk] try: ltask = self.generator.link_task except AttributeError: pass else: ltask.set_run_after(c_tsk) # setting input nodes does not declare the build order # because the build already started, but it sets # the dependency to enable rebuilds ltask.inputs.append(c_tsk.outputs[0]) self.outputs.append(out_node) if not '-o' in self.env['SWIGFLAGS']: self.env.append_value('SWIGFLAGS', ['-o', self.outputs[0].abspath()]) @swigf def swig_python(tsk): node = tsk.inputs[0].parent if tsk.outdir: node = tsk.outdir tsk.set_outputs(node.find_or_declare(tsk.module+'.py')) @swigf def swig_ocaml(tsk): node = tsk.inputs[0].parent if tsk.outdir: node = tsk.outdir tsk.set_outputs(node.find_or_declare(tsk.module+'.ml')) tsk.set_outputs(node.find_or_declare(tsk.module+'.mli')) @extension(*SWIG_EXTS) def i_file(self, node): # the task instance tsk = self.create_task('swig') tsk.set_inputs(node) tsk.module = getattr(self, 'swig_module', None) flags = self.to_list(getattr(self, 'swig_flags', [])) tsk.env.append_value('SWIGFLAGS', flags) tsk.outdir = None if '-outdir' in flags: outdir = flags[flags.index('-outdir')+1] outdir = tsk.generator.bld.bldnode.make_node(outdir) outdir.mkdir() tsk.outdir = outdir @feature('c', 'cxx', 'd', 'fc', 'asm') @after_method('apply_link', 'process_source') def enforce_swig_before_link(self): try: link_task = self.link_task except AttributeError: pass else: for x in self.tasks: if x.__class__.__name__ == 'swig': link_task.run_after.add(x) @conf def check_swig_version(conf, minver=None): """ Check if the swig tool is found matching a given minimum version. minver should be a tuple, eg. to check for swig >= 1.3.28 pass (1,3,28) as minver. If successful, SWIG_VERSION is defined as 'MAJOR.MINOR' (eg. '1.3') of the actual swig version found. :param minver: minimum version :type minver: tuple of int :return: swig version :rtype: tuple of int """ assert minver is None or isinstance(minver, tuple) swigbin = conf.env['SWIG'] if not swigbin: conf.fatal('could not find the swig executable') # Get swig version string cmd = swigbin + ['-version'] Logs.debug('swig: Running swig command %r', cmd) reg_swig = re.compile(r'SWIG Version\s(.*)', re.M) swig_out = conf.cmd_and_log(cmd) swigver_tuple = tuple([int(s) for s in reg_swig.findall(swig_out)[0].split('.')]) # Compare swig version with the minimum required result = (minver is None) or (swigver_tuple >= minver) if result: # Define useful environment variables swigver = '.'.join([str(x) for x in swigver_tuple[:2]]) conf.env['SWIG_VERSION'] = swigver # Feedback swigver_full = '.'.join(map(str, swigver_tuple[:3])) if minver is None: conf.msg('Checking for swig version', swigver_full) else: minver_str = '.'.join(map(str, minver)) conf.msg('Checking for swig version >= %s' % (minver_str,), swigver_full, color=result and 'GREEN' or 'YELLOW') if not result: conf.fatal('The swig version is too old, expecting %r' % (minver,)) return swigver_tuple def configure(conf): conf.find_program('swig', var='SWIG') conf.env.SWIGPATH_ST = '-I%s' conf.env.SWIGDEF_ST = '-D%s' ldb-2.0.8/third_party/waf/waflib/extras/syms.py0000660000000000000000000000621013573675414021461 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 """ This tool supports the export_symbols_regex to export the symbols in a shared library. by default, all symbols are exported by gcc, and nothing by msvc. to use the tool, do something like: def build(ctx): ctx(features='c cshlib syms', source='a.c b.c', export_symbols_regex='mylib_.*', target='testlib') only the symbols starting with 'mylib_' will be exported. """ import re from waflib.Context import STDOUT from waflib.Task import Task from waflib.Errors import WafError from waflib.TaskGen import feature, after_method class gen_sym(Task): def run(self): obj = self.inputs[0] kw = {} reg = getattr(self.generator, 'export_symbols_regex', '.+?') if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME): re_nm = re.compile(r'External\s+\|\s+_(?P%s)\b' % reg) cmd = (self.env.DUMPBIN or ['dumpbin']) + ['/symbols', obj.abspath()] else: if self.env.DEST_BINFMT == 'pe': #gcc uses nm, and has a preceding _ on windows re_nm = re.compile(r'(T|D)\s+_(?P%s)\b' % reg) elif self.env.DEST_BINFMT=='mac-o': re_nm=re.compile(r'(T|D)\s+(?P_?(%s))\b' % reg) else: re_nm = re.compile(r'(T|D)\s+(?P%s)\b' % reg) cmd = (self.env.NM or ['nm']) + ['-g', obj.abspath()] syms = [m.group('symbol') for m in re_nm.finditer(self.generator.bld.cmd_and_log(cmd, quiet=STDOUT, **kw))] self.outputs[0].write('%r' % syms) class compile_sym(Task): def run(self): syms = {} for x in self.inputs: slist = eval(x.read()) for s in slist: syms[s] = 1 lsyms = list(syms.keys()) lsyms.sort() if self.env.DEST_BINFMT == 'pe': self.outputs[0].write('EXPORTS\n' + '\n'.join(lsyms)) elif self.env.DEST_BINFMT == 'elf': self.outputs[0].write('{ global:\n' + ';\n'.join(lsyms) + ";\nlocal: *; };\n") elif self.env.DEST_BINFMT=='mac-o': self.outputs[0].write('\n'.join(lsyms) + '\n') else: raise WafError('NotImplemented') @feature('syms') @after_method('process_source', 'process_use', 'apply_link', 'process_uselib_local', 'propagate_uselib_vars') def do_the_symbol_stuff(self): def_node = self.path.find_or_declare(getattr(self, 'sym_file', self.target + '.def')) compiled_tasks = getattr(self, 'compiled_tasks', None) if compiled_tasks: ins = [x.outputs[0] for x in compiled_tasks] self.gen_sym_tasks = [self.create_task('gen_sym', x, x.change_ext('.%d.sym' % self.idx)) for x in ins] self.create_task('compile_sym', [x.outputs[0] for x in self.gen_sym_tasks], def_node) link_task = getattr(self, 'link_task', None) if link_task: self.link_task.dep_nodes.append(def_node) if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME): self.link_task.env.append_value('LINKFLAGS', ['/def:' + def_node.bldpath()]) elif self.env.DEST_BINFMT == 'pe': # gcc on windows takes *.def as an additional input self.link_task.inputs.append(def_node) elif self.env.DEST_BINFMT == 'elf': self.link_task.env.append_value('LINKFLAGS', ['-Wl,-version-script', '-Wl,' + def_node.bldpath()]) elif self.env.DEST_BINFMT=='mac-o': self.link_task.env.append_value('LINKFLAGS',['-Wl,-exported_symbols_list,' + def_node.bldpath()]) else: raise WafError('NotImplemented') ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py0000660000000000000000000002240213573675414021601 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Texas Instruments code generator support (experimental) # When reporting issues, please directly assign the bug to the maintainer. __author__ = __maintainer__ = "Jérôme Carretero " __copyright__ = "Jérôme Carretero, 2012" """ TI cgt6x is a compiler suite for TI DSPs. The toolchain does pretty weird things, and I'm sure I'm missing some of them. But still, the tool saves time. What this tool does is: - create a TI compiler environment - create TI compiler features, to handle some specifics about this compiler It has a few idiosyncracies, such as not giving the liberty of the .o file names - automatically activate them when using the TI compiler - handle the tconf tool The tool TODO: - the set_platform_flags() function is not nice - more tests - broaden tool scope, if needed """ import os, re from waflib import Options, Utils, Task, TaskGen from waflib.Tools import c, ccroot, c_preproc from waflib.Configure import conf from waflib.TaskGen import feature, before_method from waflib.Tools.c import cprogram opj = os.path.join @conf def find_ticc(conf): conf.find_program(['cl6x'], var='CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) conf.env.CC_NAME = 'ticc' @conf def find_tild(conf): conf.find_program(['lnk6x'], var='LINK_CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) conf.env.LINK_CC_NAME = 'tild' @conf def find_tiar(conf): conf.find_program(['ar6x'], var='AR', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) conf.env.AR_NAME = 'tiar' conf.env.ARFLAGS = 'qru' @conf def ticc_common_flags(conf): v = conf.env if not v['LINK_CC']: v['LINK_CC'] = v['CC'] v['CCLNK_SRC_F'] = [] v['CCLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-d%s' v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-i%s' # template for adding libpaths v['STLIB_ST'] = '-l=%s.lib' v['STLIBPATH_ST'] = '-i%s' # program v['cprogram_PATTERN'] = '%s.out' # static lib #v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic'] v['cstlib_PATTERN'] = '%s.lib' def configure(conf): v = conf.env v.TI_CGT_DIR = getattr(Options.options, 'ti-cgt-dir', "") v.TI_DSPLINK_DIR = getattr(Options.options, 'ti-dsplink-dir', "") v.TI_BIOSUTILS_DIR = getattr(Options.options, 'ti-biosutils-dir', "") v.TI_DSPBIOS_DIR = getattr(Options.options, 'ti-dspbios-dir', "") v.TI_XDCTOOLS_DIR = getattr(Options.options, 'ti-xdctools-dir', "") conf.find_ticc() conf.find_tiar() conf.find_tild() conf.ticc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() conf.find_program(['tconf'], var='TCONF', path_list=v.TI_XDCTOOLS_DIR) conf.env.TCONF_INCLUDES += [ opj(conf.env.TI_DSPBIOS_DIR, 'packages'), ] conf.env.INCLUDES += [ opj(conf.env.TI_CGT_DIR, 'include'), ] conf.env.LIBPATH += [ opj(conf.env.TI_CGT_DIR, "lib"), ] conf.env.INCLUDES_DSPBIOS += [ opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'include'), ] conf.env.LIBPATH_DSPBIOS += [ opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'lib'), ] conf.env.INCLUDES_DSPLINK += [ opj(conf.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc'), ] @conf def ti_set_debug(cfg, debug=1): """ Sets debug flags for the compiler. TODO: - for each TI CFLAG/INCLUDES/LINKFLAGS/LIBPATH replace RELEASE by DEBUG - -g --no_compress """ if debug: cfg.env.CFLAGS += "-d_DEBUG -dDEBUG -dDDSP_DEBUG".split() @conf def ti_dsplink_set_platform_flags(cfg, splat, dsp, dspbios_ver, board): """ Sets the INCLUDES, LINKFLAGS for DSPLINK and TCONF_INCLUDES For the specific hardware. Assumes that DSPLINK was built in its own folder. :param splat: short platform name (eg. OMAPL138) :param dsp: DSP name (eg. 674X) :param dspbios_ver: string identifying DspBios version (eg. 5.XX) :param board: board name (eg. OMAPL138GEM) """ d1 = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver) d = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver, board) cfg.env.TCONF_INCLUDES += [d1, d] cfg.env.INCLUDES_DSPLINK += [ opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', dsp), d, ] cfg.env.LINKFLAGS_DSPLINK += [ opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'export', 'BIN', 'DspBios', splat, board+'_0', 'RELEASE', 'dsplink%s.lib' % x) for x in ('', 'pool', 'mpcs', 'mplist', 'msg', 'data', 'notify', 'ringio') ] def options(opt): opt.add_option('--with-ti-cgt', type='string', dest='ti-cgt-dir', help = 'Specify alternate cgt root folder', default="") opt.add_option('--with-ti-biosutils', type='string', dest='ti-biosutils-dir', help = 'Specify alternate biosutils folder', default="") opt.add_option('--with-ti-dspbios', type='string', dest='ti-dspbios-dir', help = 'Specify alternate dspbios folder', default="") opt.add_option('--with-ti-dsplink', type='string', dest='ti-dsplink-dir', help = 'Specify alternate dsplink folder', default="") opt.add_option('--with-ti-xdctools', type='string', dest='ti-xdctools-dir', help = 'Specify alternate xdctools folder', default="") class ti_cprogram(cprogram): """ Link object files into a c program Changes: - the linked executable to have a relative path (because we can) - put the LIBPATH first """ run_str = '${LINK_CC} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].bldpath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ' @feature("c") @before_method('apply_link') def use_ti_cprogram(self): """ Automatically uses ti_cprogram link process """ if 'cprogram' in self.features and self.env.CC_NAME == 'ticc': self.features.insert(0, "ti_cprogram") class ti_c(Task.Task): """ Compile task for the TI codegen compiler This compiler does not allow specifying the output file name, only the output path. """ "Compile C files into object files" run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${SRC} -c ${OUT} ${CPPFLAGS}' vars = ['CCDEPS'] # unused variable to depend on, just in case ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] scan = c_preproc.scan def create_compiled_task(self, name, node): """ Overrides ccroot.create_compiled_task to support ti_c """ out = '%s' % (node.change_ext('.obj').name) if self.env.CC_NAME == 'ticc': name = 'ti_c' task = self.create_task(name, node, node.parent.find_or_declare(out)) self.env.OUT = '-fr%s' % (node.parent.get_bld().abspath()) try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] return task @TaskGen.extension('.c') def c_hook(self, node): "Bind the c file extension to the creation of a :py:class:`waflib.Tools.c.c` instance" if self.env.CC_NAME == 'ticc': return create_compiled_task(self, 'ti_c', node) else: return self.create_compiled_task('c', node) @feature("ti-tconf") @before_method('process_source') def apply_tconf(self): sources = [x.get_src() for x in self.to_nodes(self.source, path=self.path.get_src())] node = sources[0] assert(sources[0].name.endswith(".tcf")) if len(sources) > 1: assert(sources[1].name.endswith(".cmd")) target = getattr(self, 'target', self.source) target_node = node.get_bld().parent.find_or_declare(node.name) procid = "%d" % int(getattr(self, 'procid', 0)) importpaths = [] includes = Utils.to_list(getattr(self, 'includes', [])) for x in includes + self.env.TCONF_INCLUDES: if x == os.path.abspath(x): importpaths.append(x) else: relpath = self.path.find_node(x).path_from(target_node.parent) importpaths.append(relpath) task = self.create_task('ti_tconf', sources, target_node.change_ext('.cdb')) task.path = self.path task.includes = includes task.cwd = target_node.parent.abspath() task.env = self.env.derive() task.env["TCONFSRC"] = node.path_from(target_node.parent) task.env["TCONFINC"] = '-Dconfig.importPath=%s' % ";".join(importpaths) task.env['TCONFPROGNAME'] = '-Dconfig.programName=%s' % target task.env['PROCID'] = procid task.outputs = [ target_node.change_ext("cfg_c.c"), target_node.change_ext("cfg.s62"), target_node.change_ext("cfg.cmd"), ] create_compiled_task(self, 'ti_c', task.outputs[1]) ctask = create_compiled_task(self, 'ti_c', task.outputs[0]) ctask.env = self.env.derive() self.add_those_o_files(target_node.change_ext("cfg.cmd")) if len(sources) > 1: self.add_those_o_files(sources[1]) self.source = [] re_tconf_include = re.compile(r'(?Putils\.importFile)\("(?P.*)"\)',re.M) class ti_tconf(Task.Task): run_str = '${TCONF} ${TCONFINC} ${TCONFPROGNAME} ${TCONFSRC} ${PROCID}' color = 'PINK' def scan(self): includes = Utils.to_list(getattr(self, 'includes', [])) def deps(node): nodes, names = [], [] if node: code = Utils.readf(node.abspath()) for match in re_tconf_include.finditer(code): path = match.group('file') if path: for x in includes: filename = opj(x, path) fi = self.path.find_resource(filename) if fi: subnodes, subnames = deps(fi) nodes += subnodes names += subnames nodes.append(fi) names.append(path) break return nodes, names return deps(self.inputs[0]) ldb-2.0.8/third_party/waf/waflib/extras/unity.py0000660000000000000000000000547013573675414021645 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 """ Compile whole groups of C/C++ files at once (C and C++ files are processed independently though). To enable globally:: def options(opt): opt.load('compiler_cxx') def build(bld): bld.load('compiler_cxx unity') To enable for specific task generators only:: def build(bld): bld(features='c cprogram unity', source='main.c', ...) The file order is often significant in such builds, so it can be necessary to adjust the order of source files and the batch sizes. To control the amount of files processed in a batch per target (the default is 50):: def build(bld): bld(features='c cprogram', unity_size=20) """ from waflib import Task, Options from waflib.Tools import c_preproc from waflib import TaskGen MAX_BATCH = 50 EXTS_C = ('.c',) EXTS_CXX = ('.cpp','.cc','.cxx','.C','.c++') def options(opt): global MAX_BATCH opt.add_option('--batchsize', action='store', dest='batchsize', type='int', default=MAX_BATCH, help='default unity batch size (0 disables unity builds)') @TaskGen.taskgen_method def batch_size(self): default = getattr(Options.options, 'batchsize', MAX_BATCH) if default < 1: return 0 return getattr(self, 'unity_size', default) class unity(Task.Task): color = 'BLUE' scan = c_preproc.scan def to_include(self, node): ret = node.path_from(self.outputs[0].parent) ret = ret.replace('\\', '\\\\').replace('"', '\\"') return ret def run(self): lst = ['#include "%s"\n' % self.to_include(node) for node in self.inputs] txt = ''.join(lst) self.outputs[0].write(txt) def __str__(self): node = self.outputs[0] return node.path_from(node.ctx.launch_node()) def bind_unity(obj, cls_name, exts): if not 'mappings' in obj.__dict__: obj.mappings = dict(obj.mappings) for j in exts: fun = obj.mappings[j] if fun.__name__ == 'unity_fun': raise ValueError('Attempt to bind unity mappings multiple times %r' % j) def unity_fun(self, node): cnt = self.batch_size() if cnt <= 1: return fun(self, node) x = getattr(self, 'master_%s' % cls_name, None) if not x or len(x.inputs) >= cnt: x = self.create_task('unity') setattr(self, 'master_%s' % cls_name, x) cnt_cur = getattr(self, 'cnt_%s' % cls_name, 0) c_node = node.parent.find_or_declare('unity_%s_%d_%d.%s' % (self.idx, cnt_cur, cnt, cls_name)) x.outputs = [c_node] setattr(self, 'cnt_%s' % cls_name, cnt_cur + 1) fun(self, c_node) x.inputs.append(node) obj.mappings[j] = unity_fun @TaskGen.feature('unity') @TaskGen.before('process_source') def single_unity(self): lst = self.to_list(self.features) if 'c' in lst: bind_unity(self, 'c', EXTS_C) if 'cxx' in lst: bind_unity(self, 'cxx', EXTS_CXX) def build(bld): if bld.env.CC_NAME: bind_unity(TaskGen.task_gen, 'c', EXTS_C) if bld.env.CXX_NAME: bind_unity(TaskGen.task_gen, 'cxx', EXTS_CXX) ldb-2.0.8/third_party/waf/waflib/extras/use_config.py0000660000000000000000000001303113573675414022606 0ustar rootroot00000000000000#!/usr/bin/env python # coding=utf-8 # Mathieu Courtois - EDF R&D, 2013 - http://www.code-aster.org """ When a project has a lot of options the 'waf configure' command line can be very long and it becomes a cause of error. This tool provides a convenient way to load a set of configuration parameters from a local file or from a remote url. The configuration parameters are stored in a Python file that is imported as an extra waf tool can be. Example: $ waf configure --use-config-dir=http://www.anywhere.org --use-config=myconf1 ... The file 'myconf1' will be downloaded from 'http://www.anywhere.org' (or 'http://www.anywhere.org/wafcfg'). If the files are available locally, it could be: $ waf configure --use-config-dir=/somewhere/myconfigurations --use-config=myconf1 ... The configuration of 'myconf1.py' is automatically loaded by calling its 'configure' function. In this example, it defines environment variables and set options: def configure(self): self.env['CC'] = 'gcc-4.8' self.env.append_value('LIBPATH', [...]) self.options.perlbinary = '/usr/local/bin/perl' self.options.pyc = False The corresponding command line should have been: $ CC=gcc-4.8 LIBPATH=... waf configure --nopyc --with-perl-binary=/usr/local/bin/perl This is an extra tool, not bundled with the default waf binary. To add the use_config tool to the waf file: $ ./waf-light --tools=use_config When using this tool, the wscript will look like: def options(opt): opt.load('use_config') def configure(conf): conf.load('use_config') """ import sys import os.path as osp import os local_repo = '' """Local repository containing additional Waf tools (plugins)""" remote_repo = 'https://gitlab.com/ita1024/waf/raw/master/' """ Remote directory containing downloadable waf tools. The missing tools can be downloaded by using:: $ waf configure --download """ remote_locs = ['waflib/extras', 'waflib/Tools'] """ Remote directories for use with :py:const:`waflib.extras.use_config.remote_repo` """ try: from urllib import request except ImportError: from urllib import urlopen else: urlopen = request.urlopen from waflib import Errors, Context, Logs, Utils, Options, Configure try: from urllib.parse import urlparse except ImportError: from urlparse import urlparse DEFAULT_DIR = 'wafcfg' # add first the current wafcfg subdirectory sys.path.append(osp.abspath(DEFAULT_DIR)) def options(self): group = self.add_option_group('configure options') group.add_option('--download', dest='download', default=False, action='store_true', help='try to download the tools if missing') group.add_option('--use-config', action='store', default=None, metavar='CFG', dest='use_config', help='force the configuration parameters by importing ' 'CFG.py. Several modules may be provided (comma ' 'separated).') group.add_option('--use-config-dir', action='store', default=DEFAULT_DIR, metavar='CFG_DIR', dest='use_config_dir', help='path or url where to find the configuration file') def download_check(node): """ Hook to check for the tools which are downloaded. Replace with your function if necessary. """ pass def download_tool(tool, force=False, ctx=None): """ Download a Waf tool from the remote repository defined in :py:const:`waflib.extras.use_config.remote_repo`:: $ waf configure --download """ for x in Utils.to_list(remote_repo): for sub in Utils.to_list(remote_locs): url = '/'.join((x, sub, tool + '.py')) try: web = urlopen(url) try: if web.getcode() != 200: continue except AttributeError: pass except Exception: # on python3 urlopen throws an exception # python 2.3 does not have getcode and throws an exception to fail continue else: tmp = ctx.root.make_node(os.sep.join((Context.waf_dir, 'waflib', 'extras', tool + '.py'))) tmp.write(web.read(), 'wb') Logs.warn('Downloaded %s from %s', tool, url) download_check(tmp) try: module = Context.load_tool(tool) except Exception: Logs.warn('The tool %s from %s is unusable', tool, url) try: tmp.delete() except Exception: pass continue return module raise Errors.WafError('Could not load the Waf tool') def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): try: module = Context.load_tool_default(tool, tooldir, ctx, with_sys_path) except ImportError as e: if not ctx or not hasattr(Options.options, 'download'): Logs.error('Could not load %r during options phase (download unavailable at this point)' % tool) raise if Options.options.download: module = download_tool(tool, ctx=ctx) if not module: ctx.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s' % (tool, sys.path, e)) else: ctx.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s' % (tool, sys.path, e)) return module Context.load_tool_default = Context.load_tool Context.load_tool = load_tool Configure.download_tool = download_tool def configure(self): opts = self.options use_cfg = opts.use_config if use_cfg is None: return url = urlparse(opts.use_config_dir) kwargs = {} if url.scheme: kwargs['download'] = True kwargs['remote_url'] = url.geturl() # search first with the exact url, else try with +'/wafcfg' kwargs['remote_locs'] = ['', DEFAULT_DIR] tooldir = url.geturl() + ' ' + DEFAULT_DIR for cfg in use_cfg.split(','): Logs.pprint('NORMAL', "Searching configuration '%s'..." % cfg) self.load(cfg, tooldir=tooldir, **kwargs) self.start_msg('Checking for configuration') self.end_msg(use_cfg) ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py0000660000000000000000000001053513573675414022104 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: UTF-8 # Nicolas Joseph 2009 """ ported from waf 1.5: TODO: tabs vs spaces """ from waflib import Task, Utils, Errors, Logs from waflib.TaskGen import feature VALADOC_STR = '${VALADOC}' class valadoc(Task.Task): vars = ['VALADOC', 'VALADOCFLAGS'] color = 'BLUE' after = ['cprogram', 'cstlib', 'cshlib', 'cxxprogram', 'cxxstlib', 'cxxshlib'] quiet = True # no outputs .. this is weird def __init__(self, *k, **kw): Task.Task.__init__(self, *k, **kw) self.output_dir = '' self.doclet = '' self.package_name = '' self.package_version = '' self.files = [] self.vapi_dirs = [] self.protected = True self.private = False self.inherit = False self.deps = False self.vala_defines = [] self.vala_target_glib = None self.enable_non_null_experimental = False self.force = False def run(self): if not self.env['VALADOCFLAGS']: self.env['VALADOCFLAGS'] = '' cmd = [Utils.subst_vars(VALADOC_STR, self.env)] cmd.append ('-o %s' % self.output_dir) if getattr(self, 'doclet', None): cmd.append ('--doclet %s' % self.doclet) cmd.append ('--package-name %s' % self.package_name) if getattr(self, 'package_version', None): cmd.append ('--package-version %s' % self.package_version) if getattr(self, 'packages', None): for package in self.packages: cmd.append ('--pkg %s' % package) if getattr(self, 'vapi_dirs', None): for vapi_dir in self.vapi_dirs: cmd.append ('--vapidir %s' % vapi_dir) if not getattr(self, 'protected', None): cmd.append ('--no-protected') if getattr(self, 'private', None): cmd.append ('--private') if getattr(self, 'inherit', None): cmd.append ('--inherit') if getattr(self, 'deps', None): cmd.append ('--deps') if getattr(self, 'vala_defines', None): for define in self.vala_defines: cmd.append ('--define %s' % define) if getattr(self, 'vala_target_glib', None): cmd.append ('--target-glib=%s' % self.vala_target_glib) if getattr(self, 'enable_non_null_experimental', None): cmd.append ('--enable-non-null-experimental') if getattr(self, 'force', None): cmd.append ('--force') cmd.append (' '.join ([x.abspath() for x in self.files])) return self.generator.bld.exec_command(' '.join(cmd)) @feature('valadoc') def process_valadoc(self): """ Generate API documentation from Vala source code with valadoc doc = bld( features = 'valadoc', output_dir = '../doc/html', package_name = 'vala-gtk-example', package_version = '1.0.0', packages = 'gtk+-2.0', vapi_dirs = '../vapi', force = True ) path = bld.path.find_dir ('../src') doc.files = path.ant_glob (incl='**/*.vala') """ task = self.create_task('valadoc') if getattr(self, 'output_dir', None): task.output_dir = self.path.find_or_declare(self.output_dir).abspath() else: Errors.WafError('no output directory') if getattr(self, 'doclet', None): task.doclet = self.doclet else: Errors.WafError('no doclet directory') if getattr(self, 'package_name', None): task.package_name = self.package_name else: Errors.WafError('no package name') if getattr(self, 'package_version', None): task.package_version = self.package_version if getattr(self, 'packages', None): task.packages = Utils.to_list(self.packages) if getattr(self, 'vapi_dirs', None): vapi_dirs = Utils.to_list(self.vapi_dirs) for vapi_dir in vapi_dirs: try: task.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath()) except AttributeError: Logs.warn('Unable to locate Vala API directory: %r', vapi_dir) if getattr(self, 'files', None): task.files = self.files else: Errors.WafError('no input file') if getattr(self, 'protected', None): task.protected = self.protected if getattr(self, 'private', None): task.private = self.private if getattr(self, 'inherit', None): task.inherit = self.inherit if getattr(self, 'deps', None): task.deps = self.deps if getattr(self, 'vala_defines', None): task.vala_defines = Utils.to_list(self.vala_defines) if getattr(self, 'vala_target_glib', None): task.vala_target_glib = self.vala_target_glib if getattr(self, 'enable_non_null_experimental', None): task.enable_non_null_experimental = self.enable_non_null_experimental if getattr(self, 'force', None): task.force = self.force def configure(conf): conf.find_program('valadoc', errmsg='You must install valadoc for generate the API documentation') ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py0000660000000000000000000001006013573675414022463 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 """ Use extended attributes instead of database files 1. Input files will be made writable 2. This is only for systems providing extended filesystem attributes 3. By default, hashes are calculated only if timestamp/size change (HASH_CACHE below) 4. The module enables "deep_inputs" on all tasks by propagating task signatures 5. This module also skips task signature comparisons for task code changes due to point 4. 6. This module is for Python3/Linux only, but it could be extended to Python2/other systems using the xattr library 7. For projects in which tasks always declare output files, it should be possible to store the rest of build context attributes on output files (imp_sigs, raw_deps and node_deps) but this is not done here On a simple C++ project benchmark, the variations before and after adding waf_xattr.py were observed: total build time: 20s -> 22s no-op build time: 2.4s -> 1.8s pickle file size: 2.9MB -> 2.6MB """ import os from waflib import Logs, Node, Task, Utils, Errors from waflib.Task import SKIP_ME, RUN_ME, CANCEL_ME, ASK_LATER, SKIPPED, MISSING HASH_CACHE = True SIG_VAR = 'user.waf.sig' SEP = ','.encode() TEMPLATE = '%b%d,%d'.encode() try: PermissionError except NameError: PermissionError = IOError def getxattr(self): return os.getxattr(self.abspath(), SIG_VAR) def setxattr(self, val): os.setxattr(self.abspath(), SIG_VAR, val) def h_file(self): try: ret = getxattr(self) except OSError: if HASH_CACHE: st = os.stat(self.abspath()) mtime = st.st_mtime size = st.st_size else: if len(ret) == 16: # for build directory files return ret if HASH_CACHE: # check if timestamp and mtime match to avoid re-hashing st = os.stat(self.abspath()) mtime, size = ret[16:].split(SEP) if int(1000 * st.st_mtime) == int(mtime) and st.st_size == int(size): return ret[:16] ret = Utils.h_file(self.abspath()) if HASH_CACHE: val = TEMPLATE % (ret, int(1000 * st.st_mtime), int(st.st_size)) try: setxattr(self, val) except PermissionError: os.chmod(self.abspath(), st.st_mode | 128) setxattr(self, val) return ret def runnable_status(self): bld = self.generator.bld if bld.is_install < 0: return SKIP_ME for t in self.run_after: if not t.hasrun: return ASK_LATER elif t.hasrun < SKIPPED: # a dependency has an error return CANCEL_ME # first compute the signature try: new_sig = self.signature() except Errors.TaskNotReady: return ASK_LATER if not self.outputs: # compare the signature to a signature computed previously # this part is only for tasks with no output files key = self.uid() try: prev_sig = bld.task_sigs[key] except KeyError: Logs.debug('task: task %r must run: it was never run before or the task code changed', self) return RUN_ME if new_sig != prev_sig: Logs.debug('task: task %r must run: the task signature changed', self) return RUN_ME # compare the signatures of the outputs to make a decision for node in self.outputs: try: sig = node.h_file() except EnvironmentError: Logs.debug('task: task %r must run: an output node does not exist', self) return RUN_ME if sig != new_sig: Logs.debug('task: task %r must run: an output node is stale', self) return RUN_ME return (self.always_run and RUN_ME) or SKIP_ME def post_run(self): bld = self.generator.bld sig = self.signature() for node in self.outputs: if not node.exists(): self.hasrun = MISSING self.err_msg = '-> missing file: %r' % node.abspath() raise Errors.WafError(self.err_msg) os.setxattr(node.abspath(), 'user.waf.sig', sig) if not self.outputs: # only for task with no outputs bld.task_sigs[self.uid()] = sig if not self.keep_last_cmd: try: del self.last_cmd except AttributeError: pass try: os.getxattr except AttributeError: pass else: h_file.__doc__ = Node.Node.h_file.__doc__ # keep file hashes as file attributes Node.Node.h_file = h_file # enable "deep_inputs" on all tasks Task.Task.runnable_status = runnable_status Task.Task.post_run = post_run Task.Task.sig_deep_inputs = Utils.nada ldb-2.0.8/third_party/waf/waflib/extras/why.py0000660000000000000000000000354313573675414021303 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010 (ita) """ This tool modifies the task signature scheme to store and obtain information about the task execution (why it must run, etc):: def configure(conf): conf.load('why') After adding the tool, a full rebuild is necessary: waf clean build --zones=task """ from waflib import Task, Utils, Logs, Errors def signature(self): # compute the result one time, and suppose the scan_signature will give the good result try: return self.cache_sig except AttributeError: pass self.m = Utils.md5() self.m.update(self.hcode) id_sig = self.m.digest() # explicit deps self.m = Utils.md5() self.sig_explicit_deps() exp_sig = self.m.digest() # env vars self.m = Utils.md5() self.sig_vars() var_sig = self.m.digest() # implicit deps / scanner results self.m = Utils.md5() if self.scan: try: self.sig_implicit_deps() except Errors.TaskRescan: return self.signature() impl_sig = self.m.digest() ret = self.cache_sig = impl_sig + id_sig + exp_sig + var_sig return ret Task.Task.signature = signature old = Task.Task.runnable_status def runnable_status(self): ret = old(self) if ret == Task.RUN_ME: try: old_sigs = self.generator.bld.task_sigs[self.uid()] except (KeyError, AttributeError): Logs.debug("task: task must run as no previous signature exists") else: new_sigs = self.cache_sig def v(x): return Utils.to_hex(x) Logs.debug('Task %r', self) msgs = ['* Implicit or scanner dependency', '* Task code', '* Source file, explicit or manual dependency', '* Configuration data variable'] tmp = 'task: -> %s: %s %s' for x in range(len(msgs)): l = len(Utils.SIG_NIL) a = new_sigs[x*l : (x+1)*l] b = old_sigs[x*l : (x+1)*l] if (a != b): Logs.debug(tmp, msgs[x].ljust(35), v(a), v(b)) return ret Task.Task.runnable_status = runnable_status ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py0000660000000000000000000001114413573675414022477 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 """ Windows-specific optimizations This module can help reducing the overhead of listing files on windows (more than 10000 files). Python 3.5 already provides the listdir optimization though. """ import os from waflib import Utils, Build, Node, Logs try: TP = '%s\\*'.decode('ascii') except AttributeError: TP = '%s\\*' if Utils.is_win32: from waflib.Tools import md5_tstamp import ctypes, ctypes.wintypes FindFirstFile = ctypes.windll.kernel32.FindFirstFileW FindNextFile = ctypes.windll.kernel32.FindNextFileW FindClose = ctypes.windll.kernel32.FindClose FILE_ATTRIBUTE_DIRECTORY = 0x10 INVALID_HANDLE_VALUE = -1 UPPER_FOLDERS = ('.', '..') try: UPPER_FOLDERS = [unicode(x) for x in UPPER_FOLDERS] except NameError: pass def cached_hash_file(self): try: cache = self.ctx.cache_listdir_cache_hash_file except AttributeError: cache = self.ctx.cache_listdir_cache_hash_file = {} if id(self.parent) in cache: try: t = cache[id(self.parent)][self.name] except KeyError: raise IOError('Not a file') else: # an opportunity to list the files and the timestamps at once findData = ctypes.wintypes.WIN32_FIND_DATAW() find = FindFirstFile(TP % self.parent.abspath(), ctypes.byref(findData)) if find == INVALID_HANDLE_VALUE: cache[id(self.parent)] = {} raise IOError('Not a file') cache[id(self.parent)] = lst_files = {} try: while True: if findData.cFileName not in UPPER_FOLDERS: thatsadir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY if not thatsadir: ts = findData.ftLastWriteTime d = (ts.dwLowDateTime << 32) | ts.dwHighDateTime lst_files[str(findData.cFileName)] = d if not FindNextFile(find, ctypes.byref(findData)): break except Exception: cache[id(self.parent)] = {} raise IOError('Not a file') finally: FindClose(find) t = lst_files[self.name] fname = self.abspath() if fname in Build.hashes_md5_tstamp: if Build.hashes_md5_tstamp[fname][0] == t: return Build.hashes_md5_tstamp[fname][1] try: fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT) except OSError: raise IOError('Cannot read from %r' % fname) f = os.fdopen(fd, 'rb') m = Utils.md5() rb = 1 try: while rb: rb = f.read(200000) m.update(rb) finally: f.close() # ensure that the cache is overwritten Build.hashes_md5_tstamp[fname] = (t, m.digest()) return m.digest() Node.Node.cached_hash_file = cached_hash_file def get_bld_sig_win32(self): try: return self.ctx.hash_cache[id(self)] except KeyError: pass except AttributeError: self.ctx.hash_cache = {} self.ctx.hash_cache[id(self)] = ret = Utils.h_file(self.abspath()) return ret Node.Node.get_bld_sig = get_bld_sig_win32 def isfile_cached(self): # optimize for nt.stat calls, assuming there are many files for few folders try: cache = self.__class__.cache_isfile_cache except AttributeError: cache = self.__class__.cache_isfile_cache = {} try: c1 = cache[id(self.parent)] except KeyError: c1 = cache[id(self.parent)] = [] curpath = self.parent.abspath() findData = ctypes.wintypes.WIN32_FIND_DATAW() find = FindFirstFile(TP % curpath, ctypes.byref(findData)) if find == INVALID_HANDLE_VALUE: Logs.error("invalid win32 handle isfile_cached %r", self.abspath()) return os.path.isfile(self.abspath()) try: while True: if findData.cFileName not in UPPER_FOLDERS: thatsadir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY if not thatsadir: c1.append(str(findData.cFileName)) if not FindNextFile(find, ctypes.byref(findData)): break except Exception as e: Logs.error('exception while listing a folder %r %r', self.abspath(), e) return os.path.isfile(self.abspath()) finally: FindClose(find) return self.name in c1 Node.Node.isfile_cached = isfile_cached def find_or_declare_win32(self, lst): # assuming that "find_or_declare" is called before the build starts, remove the calls to os.path.isfile if isinstance(lst, str): lst = [x for x in Utils.split_path(lst) if x and x != '.'] node = self.get_bld().search_node(lst) if node: if not node.isfile_cached(): try: node.parent.mkdir() except OSError: pass return node self = self.get_src() node = self.find_node(lst) if node: if not node.isfile_cached(): try: node.parent.mkdir() except OSError: pass return node node = self.get_bld().make_node(lst) node.parent.mkdir() return node Node.Node.find_or_declare = find_or_declare_win32 ldb-2.0.8/third_party/waf/waflib/extras/wix.py0000660000000000000000000000514313573675414021301 0ustar rootroot00000000000000#!/usr/bin/python # encoding: utf-8 # vim: tabstop=4 noexpandtab """ Windows Installer XML Tool (WiX) .wxs --- candle ---> .wxobj --- light ---> .msi bld(features='wix', some.wxs, gen='some.msi', candleflags=[..], lightflags=[..]) bld(features='wix', source=['bundle.wxs','WixBalExtension'], gen='setup.exe', candleflags=[..]) """ import os, copy from waflib import TaskGen from waflib import Task from waflib.Utils import winreg class candle(Task.Task): run_str = '${CANDLE} -nologo ${CANDLEFLAGS} -out ${TGT} ${SRC[0].abspath()}', class light(Task.Task): run_str = "${LIGHT} -nologo -b ${SRC[0].parent.abspath()} ${LIGHTFLAGS} -out ${TGT} ${SRC[0].abspath()}" @TaskGen.feature('wix') @TaskGen.before_method('process_source') def wix(self): #X.wxs -> ${SRC} for CANDLE #X.wxobj -> ${SRC} for LIGHT #X.dll -> -ext X in ${LIGHTFLAGS} #X.wxl -> wixui.wixlib -loc X.wxl in ${LIGHTFLAGS} wxobj = [] wxs = [] exts = [] wxl = [] rest = [] for x in self.source: if x.endswith('.wxobj'): wxobj.append(x) elif x.endswith('.wxs'): wxobj.append(self.path.find_or_declare(x[:-4]+'.wxobj')) wxs.append(x) elif x.endswith('.dll'): exts.append(x[:-4]) elif '.' not in x: exts.append(x) elif x.endswith('.wxl'): wxl.append(x) else: rest.append(x) self.source = self.to_nodes(rest) #.wxs cndl = self.create_task('candle', self.to_nodes(wxs), self.to_nodes(wxobj)) lght = self.create_task('light', self.to_nodes(wxobj), self.path.find_or_declare(self.gen)) cndl.env.CANDLEFLAGS = copy.copy(getattr(self,'candleflags',[])) lght.env.LIGHTFLAGS = copy.copy(getattr(self,'lightflags',[])) for x in wxl: lght.env.append_value('LIGHTFLAGS','wixui.wixlib') lght.env.append_value('LIGHTFLAGS','-loc') lght.env.append_value('LIGHTFLAGS',x) for x in exts: cndl.env.append_value('CANDLEFLAGS','-ext') cndl.env.append_value('CANDLEFLAGS',x) lght.env.append_value('LIGHTFLAGS','-ext') lght.env.append_value('LIGHTFLAGS',x) #wix_bin_path() def wix_bin_path(): basekey = r"SOFTWARE\Microsoft\.NETFramework\AssemblyFolders" query = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, basekey) cnt=winreg.QueryInfoKey(query)[0] thiskey = r'C:\Program Files (x86)\WiX Toolset v3.10\SDK' for i in range(cnt-1,-1,-1): thiskey = winreg.EnumKey(query,i) if 'WiX' in thiskey: break winreg.CloseKey(query) return os.path.normpath(winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, basekey+r'\\'+thiskey)+'..\\bin') def configure(ctx): path_list=[wix_bin_path()] ctx.find_program('candle', var='CANDLE', mandatory=True, path_list = path_list) ctx.find_program('light', var='LIGHT', mandatory=True, path_list = path_list) ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py0000660000000000000000000005711013573675414021663 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # XCode 3/XCode 4/XCode 6/Xcode 7 generator for Waf # Based on work by Nicolas Mercier 2011 # Extended by Simon Warg 2015, https://github.com/mimon # XCode project file format based on http://www.monobjc.net/xcode-project-file-format.html """ See playground/xcode6/ for usage examples. """ from waflib import Context, TaskGen, Build, Utils, Errors, Logs import os, sys # FIXME too few extensions XCODE_EXTS = ['.c', '.cpp', '.m', '.mm'] HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' MAP_EXT = { '': "folder", '.h' : "sourcecode.c.h", '.hh': "sourcecode.cpp.h", '.inl': "sourcecode.cpp.h", '.hpp': "sourcecode.cpp.h", '.c': "sourcecode.c.c", '.m': "sourcecode.c.objc", '.mm': "sourcecode.cpp.objcpp", '.cc': "sourcecode.cpp.cpp", '.cpp': "sourcecode.cpp.cpp", '.C': "sourcecode.cpp.cpp", '.cxx': "sourcecode.cpp.cpp", '.c++': "sourcecode.cpp.cpp", '.l': "sourcecode.lex", # luthor '.ll': "sourcecode.lex", '.y': "sourcecode.yacc", '.yy': "sourcecode.yacc", '.plist': "text.plist.xml", ".nib": "wrapper.nib", ".xib": "text.xib", } # Used in PBXNativeTarget elements PRODUCT_TYPE_APPLICATION = 'com.apple.product-type.application' PRODUCT_TYPE_FRAMEWORK = 'com.apple.product-type.framework' PRODUCT_TYPE_EXECUTABLE = 'com.apple.product-type.tool' PRODUCT_TYPE_LIB_STATIC = 'com.apple.product-type.library.static' PRODUCT_TYPE_LIB_DYNAMIC = 'com.apple.product-type.library.dynamic' PRODUCT_TYPE_EXTENSION = 'com.apple.product-type.kernel-extension' PRODUCT_TYPE_IOKIT = 'com.apple.product-type.kernel-extension.iokit' # Used in PBXFileReference elements FILE_TYPE_APPLICATION = 'wrapper.cfbundle' FILE_TYPE_FRAMEWORK = 'wrapper.framework' FILE_TYPE_LIB_DYNAMIC = 'compiled.mach-o.dylib' FILE_TYPE_LIB_STATIC = 'archive.ar' FILE_TYPE_EXECUTABLE = 'compiled.mach-o.executable' # Tuple packs of the above TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') TARGET_TYPE_DYNAMIC_LIB = (PRODUCT_TYPE_LIB_DYNAMIC, FILE_TYPE_LIB_DYNAMIC, '.dylib') TARGET_TYPE_STATIC_LIB = (PRODUCT_TYPE_LIB_STATIC, FILE_TYPE_LIB_STATIC, '.a') TARGET_TYPE_EXECUTABLE = (PRODUCT_TYPE_EXECUTABLE, FILE_TYPE_EXECUTABLE, '') # Maps target type string to its data TARGET_TYPES = { 'framework': TARGET_TYPE_FRAMEWORK, 'app': TARGET_TYPE_APPLICATION, 'dylib': TARGET_TYPE_DYNAMIC_LIB, 'stlib': TARGET_TYPE_STATIC_LIB, 'exe' :TARGET_TYPE_EXECUTABLE, } def delete_invalid_values(dct): """ Deletes entries that are dictionaries or sets """ for k, v in list(dct.items()): if isinstance(v, dict) or isinstance(v, set): del dct[k] return dct """ Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' which is a dictionary of configuration name and buildsettings pair. E.g.: env.PROJ_CONFIGURATION = { 'Debug': { 'ARCHS': 'x86', ... } 'Release': { 'ARCHS' x86_64' ... } } The user can define a completely customized dictionary in configure() stage. Otherwise a default Debug/Release will be created based on env variable """ def configure(self): if not self.env.PROJ_CONFIGURATION: self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") # Check for any added config files added by the tool 'c_config'. if 'cfg_files' in self.env: self.env.INCLUDES = Utils.to_list(self.env.INCLUDES) + [os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files] # Create default project configuration? if 'PROJ_CONFIGURATION' not in self.env: defaults = delete_invalid_values(self.env.get_merged_dict()) self.env.PROJ_CONFIGURATION = { "Debug": defaults, "Release": defaults, } # Some build settings are required to be present by XCode. We will supply default values # if user hasn't defined any. defaults_required = [('PRODUCT_NAME', '$(TARGET_NAME)')] for cfgname,settings in self.env.PROJ_CONFIGURATION.items(): for default_var, default_val in defaults_required: if default_var not in settings: settings[default_var] = default_val # Error check customization if not isinstance(self.env.PROJ_CONFIGURATION, dict): raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") part1 = 0 part2 = 10000 part3 = 0 id = 562000999 def newid(): global id id += 1 return "%04X%04X%04X%012d" % (0, 10000, 0, id) """ Represents a tree node in the XCode project plist file format. When written to a file, all attributes of XCodeNode are stringified together with its value. However, attributes starting with an underscore _ are ignored during that process and allows you to store arbitrary values that are not supposed to be written out. """ class XCodeNode(object): def __init__(self): self._id = newid() self._been_written = False def tostring(self, value): if isinstance(value, dict): result = "{\n" for k,v in value.items(): result = result + "\t\t\t%s = %s;\n" % (k, self.tostring(v)) result = result + "\t\t}" return result elif isinstance(value, str): return "\"%s\"" % value elif isinstance(value, list): result = "(\n" for i in value: result = result + "\t\t\t%s,\n" % self.tostring(i) result = result + "\t\t)" return result elif isinstance(value, XCodeNode): return value._id else: return str(value) def write_recursive(self, value, file): if isinstance(value, dict): for k,v in value.items(): self.write_recursive(v, file) elif isinstance(value, list): for i in value: self.write_recursive(i, file) elif isinstance(value, XCodeNode): value.write(file) def write(self, file): if not self._been_written: self._been_written = True for attribute,value in self.__dict__.items(): if attribute[0] != '_': self.write_recursive(value, file) w = file.write w("\t%s = {\n" % self._id) w("\t\tisa = %s;\n" % self.__class__.__name__) for attribute,value in self.__dict__.items(): if attribute[0] != '_': w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) w("\t};\n\n") # Configurations class XCBuildConfiguration(XCodeNode): def __init__(self, name, settings = {}, env=None): XCodeNode.__init__(self) self.baseConfigurationReference = "" self.buildSettings = settings self.name = name if env and env.ARCH: settings['ARCHS'] = " ".join(env.ARCH) class XCConfigurationList(XCodeNode): def __init__(self, configlst): """ :param configlst: list of XCConfigurationList """ XCodeNode.__init__(self) self.buildConfigurations = configlst self.defaultConfigurationIsVisible = 0 self.defaultConfigurationName = configlst and configlst[0].name or "" # Group/Files class PBXFileReference(XCodeNode): def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): XCodeNode.__init__(self) self.fileEncoding = 4 if not filetype: _, ext = os.path.splitext(name) filetype = MAP_EXT.get(ext, 'text') self.lastKnownFileType = filetype self.explicitFileType = filetype self.name = name self.path = path self.sourceTree = sourcetree def __hash__(self): return (self.path+self.name).__hash__() def __eq__(self, other): return (self.path, self.name) == (other.path, other.name) class PBXBuildFile(XCodeNode): """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ def __init__(self, fileRef, settings={}): XCodeNode.__init__(self) # fileRef is a reference to a PBXFileReference object self.fileRef = fileRef # A map of key/value pairs for additional settings. self.settings = settings def __hash__(self): return (self.fileRef).__hash__() def __eq__(self, other): return self.fileRef == other.fileRef class PBXGroup(XCodeNode): def __init__(self, name, sourcetree = 'SOURCE_TREE'): XCodeNode.__init__(self) self.children = [] self.name = name self.sourceTree = sourcetree # Maintain a lookup table for all PBXFileReferences # that are contained in this group. self._filerefs = {} def add(self, sources): """ Add a list of PBXFileReferences to this group :param sources: list of PBXFileReferences objects """ self._filerefs.update(dict(zip(sources, sources))) self.children.extend(sources) def get_sub_groups(self): """ Returns all child PBXGroup objects contained in this group """ return list(filter(lambda x: isinstance(x, PBXGroup), self.children)) def find_fileref(self, fileref): """ Recursively search this group for an existing PBXFileReference. Returns None if none were found. The reason you'd want to reuse existing PBXFileReferences from a PBXGroup is that XCode doesn't like PBXFileReferences that aren't part of a PBXGroup hierarchy. If it isn't, the consequence is that certain UI features like 'Reveal in Finder' stops working. """ if fileref in self._filerefs: return self._filerefs[fileref] elif self.children: for childgroup in self.get_sub_groups(): f = childgroup.find_fileref(fileref) if f: return f return None class PBXContainerItemProxy(XCodeNode): """ This is the element for to decorate a target item. """ def __init__(self, containerPortal, remoteGlobalIDString, remoteInfo='', proxyType=1): XCodeNode.__init__(self) self.containerPortal = containerPortal # PBXProject self.remoteGlobalIDString = remoteGlobalIDString # PBXNativeTarget self.remoteInfo = remoteInfo # Target name self.proxyType = proxyType class PBXTargetDependency(XCodeNode): """ This is the element for referencing other target through content proxies. """ def __init__(self, native_target, proxy): XCodeNode.__init__(self) self.target = native_target self.targetProxy = proxy class PBXFrameworksBuildPhase(XCodeNode): """ This is the element for the framework link build phase, i.e. linking to frameworks """ def __init__(self, pbxbuildfiles): XCodeNode.__init__(self) self.buildActionMask = 2147483647 self.runOnlyForDeploymentPostprocessing = 0 self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) class PBXHeadersBuildPhase(XCodeNode): """ This is the element for adding header files to be packaged into the .framework """ def __init__(self, pbxbuildfiles): XCodeNode.__init__(self) self.buildActionMask = 2147483647 self.runOnlyForDeploymentPostprocessing = 0 self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) class PBXCopyFilesBuildPhase(XCodeNode): """ Represents the PBXCopyFilesBuildPhase section. PBXBuildFile can be added to this node to copy files after build is done. """ def __init__(self, pbxbuildfiles, dstpath, dstSubpathSpec=0, *args, **kwargs): XCodeNode.__init__(self) self.files = pbxbuildfiles self.dstPath = dstpath self.dstSubfolderSpec = dstSubpathSpec class PBXSourcesBuildPhase(XCodeNode): """ Represents the 'Compile Sources' build phase in a Xcode target """ def __init__(self, buildfiles): XCodeNode.__init__(self) self.files = buildfiles # List of PBXBuildFile objects class PBXLegacyTarget(XCodeNode): def __init__(self, action, target=''): XCodeNode.__init__(self) self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})]) if not target: self.buildArgumentsString = "%s %s" % (sys.argv[0], action) else: self.buildArgumentsString = "%s %s --targets=%s" % (sys.argv[0], action, target) self.buildPhases = [] self.buildToolPath = sys.executable self.buildWorkingDirectory = "" self.dependencies = [] self.name = target or action self.productName = target or action self.passBuildSettingsInEnvironment = 0 class PBXShellScriptBuildPhase(XCodeNode): def __init__(self, action, target): XCodeNode.__init__(self) self.buildActionMask = 2147483647 self.files = [] self.inputPaths = [] self.outputPaths = [] self.runOnlyForDeploymentPostProcessing = 0 self.shellPath = "/bin/sh" self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): """ Represents a target in XCode, e.g. App, DyLib, Framework etc. """ def __init__(self, target, node, target_type=TARGET_TYPE_APPLICATION, configlist=[], buildphases=[]): XCodeNode.__init__(self) product_type = target_type[0] file_type = target_type[1] self.buildConfigurationList = XCConfigurationList(configlist) self.buildPhases = buildphases self.buildRules = [] self.dependencies = [] self.name = target self.productName = target self.productType = product_type # See TARGET_TYPE_ tuples constants self.productReference = PBXFileReference(node.name, node.abspath(), file_type, '') def add_configuration(self, cf): """ :type cf: XCBuildConfiguration """ self.buildConfigurationList.buildConfigurations.append(cf) def add_build_phase(self, phase): # Some build phase types may appear only once. If a phase type already exists, then merge them. if ( (phase.__class__ == PBXFrameworksBuildPhase) or (phase.__class__ == PBXSourcesBuildPhase) ): for b in self.buildPhases: if b.__class__ == phase.__class__: b.files.extend(phase.files) return self.buildPhases.append(phase) def add_dependency(self, depnd): self.dependencies.append(depnd) # Root project object class PBXProject(XCodeNode): def __init__(self, name, version, env): XCodeNode.__init__(self) if not isinstance(env.PROJ_CONFIGURATION, dict): raise Errors.WafError("Error: env.PROJ_CONFIGURATION must be a dictionary. This is done for you if you do not define one yourself. However, did you load the xcode module at the end of your wscript configure() ?") # Retrieve project configuration configurations = [] for config_name, settings in env.PROJ_CONFIGURATION.items(): cf = XCBuildConfiguration(config_name, settings) configurations.append(cf) self.buildConfigurationList = XCConfigurationList(configurations) self.compatibilityVersion = version[0] self.hasScannedForEncodings = 1 self.mainGroup = PBXGroup(name) self.projectRoot = "" self.projectDirPath = "" self.targets = [] self._objectVersion = version[1] def create_target_dependency(self, target, name): """ : param target : PXBNativeTarget """ proxy = PBXContainerItemProxy(self, target, name) dependency = PBXTargetDependency(target, proxy) return dependency def write(self, file): # Make sure this is written only once if self._been_written: return w = file.write w("// !$*UTF8*$!\n") w("{\n") w("\tarchiveVersion = 1;\n") w("\tclasses = {\n") w("\t};\n") w("\tobjectVersion = %d;\n" % self._objectVersion) w("\tobjects = {\n\n") XCodeNode.write(self, file) w("\t};\n") w("\trootObject = %s;\n" % self._id) w("}\n") def add_target(self, target): self.targets.append(target) def get_target(self, name): """ Get a reference to PBXNativeTarget if it exists """ for t in self.targets: if t.name == name: return t return None @TaskGen.feature('c', 'cxx') @TaskGen.after('propagate_uselib_vars', 'apply_incpaths') def process_xcode(self): bld = self.bld try: p = bld.project except AttributeError: return if not hasattr(self, 'target_type'): return products_group = bld.products_group target_group = PBXGroup(self.name) p.mainGroup.children.append(target_group) # Determine what type to build - framework, app bundle etc. target_type = getattr(self, 'target_type', 'app') if target_type not in TARGET_TYPES: raise Errors.WafError("Target type '%s' does not exists. Available options are '%s'. In target '%s'" % (target_type, "', '".join(TARGET_TYPES.keys()), self.name)) else: target_type = TARGET_TYPES[target_type] file_ext = target_type[2] # Create the output node target_node = self.path.find_or_declare(self.name+file_ext) target = PBXNativeTarget(self.name, target_node, target_type, [], []) products_group.children.append(target.productReference) # Pull source files from the 'source' attribute and assign them to a UI group. # Use a default UI group named 'Source' unless the user # provides a 'group_files' dictionary to customize the UI grouping. sources = getattr(self, 'source', []) if hasattr(self, 'group_files'): group_files = getattr(self, 'group_files', []) for grpname,files in group_files.items(): group = bld.create_group(grpname, files) target_group.children.append(group) else: group = bld.create_group('Source', sources) target_group.children.append(group) # Create a PBXFileReference for each source file. # If the source file already exists as a PBXFileReference in any of the UI groups, then # reuse that PBXFileReference object (XCode does not like it if we don't reuse) for idx, path in enumerate(sources): fileref = PBXFileReference(path.name, path.abspath()) existing_fileref = target_group.find_fileref(fileref) if existing_fileref: sources[idx] = existing_fileref else: sources[idx] = fileref # If the 'source' attribute contains any file extension that XCode can't work with, # then remove it. The allowed file extensions are defined in XCODE_EXTS. is_valid_file_extension = lambda file: os.path.splitext(file.path)[1] in XCODE_EXTS sources = list(filter(is_valid_file_extension, sources)) buildfiles = [bld.unique_buildfile(PBXBuildFile(x)) for x in sources] target.add_build_phase(PBXSourcesBuildPhase(buildfiles)) # Check if any framework to link against is some other target we've made libs = getattr(self, 'tmp_use_seen', []) for lib in libs: use_target = p.get_target(lib) if use_target: # Create an XCode dependency so that XCode knows to build the other target before this target dependency = p.create_target_dependency(use_target, use_target.name) target.add_dependency(dependency) buildphase = PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)]) target.add_build_phase(buildphase) if lib in self.env.LIB: self.env.LIB = list(filter(lambda x: x != lib, self.env.LIB)) # If 'export_headers' is present, add files to the Headers build phase in xcode. # These are files that'll get packed into the Framework for instance. exp_hdrs = getattr(self, 'export_headers', []) hdrs = bld.as_nodes(Utils.to_list(exp_hdrs)) files = [p.mainGroup.find_fileref(PBXFileReference(n.name, n.abspath())) for n in hdrs] files = [PBXBuildFile(f, {'ATTRIBUTES': ('Public',)}) for f in files] buildphase = PBXHeadersBuildPhase(files) target.add_build_phase(buildphase) # Merge frameworks and libs into one list, and prefix the frameworks frameworks = Utils.to_list(self.env.FRAMEWORK) frameworks = ' '.join(['-framework %s' % (f.split('.framework')[0]) for f in frameworks]) libs = Utils.to_list(self.env.STLIB) + Utils.to_list(self.env.LIB) libs = ' '.join(bld.env['STLIB_ST'] % t for t in libs) # Override target specific build settings bldsettings = { 'HEADER_SEARCH_PATHS': ['$(inherited)'] + self.env['INCPATHS'], 'LIBRARY_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(self.env.LIBPATH) + Utils.to_list(self.env.STLIBPATH) + Utils.to_list(self.env.LIBDIR) , 'FRAMEWORK_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(self.env.FRAMEWORKPATH), 'OTHER_LDFLAGS': libs + ' ' + frameworks, 'OTHER_LIBTOOLFLAGS': bld.env['LINKFLAGS'], 'OTHER_CPLUSPLUSFLAGS': Utils.to_list(self.env['CXXFLAGS']), 'OTHER_CFLAGS': Utils.to_list(self.env['CFLAGS']), 'INSTALL_PATH': [] } # Install path installpaths = Utils.to_list(getattr(self, 'install', [])) prodbuildfile = PBXBuildFile(target.productReference) for instpath in installpaths: bldsettings['INSTALL_PATH'].append(instpath) target.add_build_phase(PBXCopyFilesBuildPhase([prodbuildfile], instpath)) if not bldsettings['INSTALL_PATH']: del bldsettings['INSTALL_PATH'] # Create build settings which can override the project settings. Defaults to none if user # did not pass argument. This will be filled up with target specific # search paths, libs to link etc. settings = getattr(self, 'settings', {}) # The keys represents different build configuration, e.g. Debug, Release and so on.. # Insert our generated build settings to all configuration names keys = set(settings.keys() + bld.env.PROJ_CONFIGURATION.keys()) for k in keys: if k in settings: settings[k].update(bldsettings) else: settings[k] = bldsettings for k,v in settings.items(): target.add_configuration(XCBuildConfiguration(k, v)) p.add_target(target) class xcode(Build.BuildContext): cmd = 'xcode6' fun = 'build' def as_nodes(self, files): """ Returns a list of waflib.Nodes from a list of string of file paths """ nodes = [] for x in files: if not isinstance(x, str): d = x else: d = self.srcnode.find_node(x) if not d: raise Errors.WafError('File \'%s\' was not found' % x) nodes.append(d) return nodes def create_group(self, name, files): """ Returns a new PBXGroup containing the files (paths) passed in the files arg :type files: string """ group = PBXGroup(name) """ Do not use unique file reference here, since XCode seem to allow only one file reference to be referenced by a group. """ files_ = [] for d in self.as_nodes(Utils.to_list(files)): fileref = PBXFileReference(d.name, d.abspath()) files_.append(fileref) group.add(files_) return group def unique_buildfile(self, buildfile): """ Returns a unique buildfile, possibly an existing one. Use this after you've constructed a PBXBuildFile to make sure there is only one PBXBuildFile for the same file in the same project. """ try: build_files = self.build_files except AttributeError: build_files = self.build_files = {} if buildfile not in build_files: build_files[buildfile] = buildfile return build_files[buildfile] def execute(self): """ Entry point """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) p = PBXProject(appname, ('Xcode 3.2', 46), self.env) # If we don't create a Products group, then # XCode will create one, which entails that # we'll start to see duplicate files in the UI # for some reason. products_group = PBXGroup('Products') p.mainGroup.children.append(products_group) self.project = p self.products_group = products_group # post all task generators # the process_xcode method above will be called for each target if self.targets and self.targets != '*': (self._min_grp, self._exact_tg) = self.get_targets() self.current_group = 0 while self.current_group < len(self.groups): self.post_group() self.current_group += 1 node = self.bldnode.make_node('%s.xcodeproj' % appname) node.mkdir() node = node.make_node('project.pbxproj') with open(node.abspath(), 'w') as f: p.write(f) Logs.pprint('GREEN', 'Wrote %r' % node.abspath()) def bind_fun(tgtype): def fun(self, *k, **kw): tgtype = fun.__name__ if tgtype == 'shlib' or tgtype == 'dylib': features = 'cxx cxxshlib' tgtype = 'dylib' elif tgtype == 'framework': features = 'cxx cxxshlib' tgtype = 'framework' elif tgtype == 'program': features = 'cxx cxxprogram' tgtype = 'exe' elif tgtype == 'app': features = 'cxx cxxprogram' tgtype = 'app' elif tgtype == 'stlib': features = 'cxx cxxstlib' tgtype = 'stlib' lst = kw['features'] = Utils.to_list(kw.get('features', [])) for x in features.split(): if not x in kw['features']: lst.append(x) kw['target_type'] = tgtype return self(*k, **kw) fun.__name__ = tgtype setattr(Build.BuildContext, tgtype, fun) return fun for xx in 'app framework dylib shlib stlib program'.split(): bind_fun(xx) ldb-2.0.8/third_party/waf/waflib/fixpy2.py0000660000000000000000000000263513573675414020410 0ustar rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010-2018 (ita) from __future__ import with_statement import os all_modifs = {} def fixdir(dir): """Call all substitution functions on Waf folders""" for k in all_modifs: for v in all_modifs[k]: modif(os.path.join(dir, 'waflib'), k, v) def modif(dir, name, fun): """Call a substitution function""" if name == '*': lst = [] for y in '. Tools extras'.split(): for x in os.listdir(os.path.join(dir, y)): if x.endswith('.py'): lst.append(y + os.sep + x) for x in lst: modif(dir, x, fun) return filename = os.path.join(dir, name) with open(filename, 'r') as f: txt = f.read() txt = fun(txt) with open(filename, 'w') as f: f.write(txt) def subst(*k): """register a substitution function""" def do_subst(fun): for x in k: try: all_modifs[x].append(fun) except KeyError: all_modifs[x] = [fun] return fun return do_subst @subst('*') def r1(code): "utf-8 fixes for python < 2.6" code = code.replace('as e:', ',e:') code = code.replace(".decode(sys.stdout.encoding or'latin-1',errors='replace')", '') return code.replace('.encode()', '') @subst('Runner.py') def r4(code): "generator syntax" return code.replace('next(self.biter)', 'self.biter.next()') @subst('Context.py') def r5(code): return code.replace("('Execution failure: %s'%str(e),ex=e)", "('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]") ldb-2.0.8/third_party/waf/waflib/processor.py0000770000000000000000000000310113573675414021175 0ustar rootroot00000000000000#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2016-2018 (ita) import os, sys, traceback, base64, signal try: import cPickle except ImportError: import pickle as cPickle try: import subprocess32 as subprocess except ImportError: import subprocess try: TimeoutExpired = subprocess.TimeoutExpired except AttributeError: class TimeoutExpired(Exception): pass def run(): txt = sys.stdin.readline().strip() if not txt: # parent process probably ended sys.exit(1) [cmd, kwargs, cargs] = cPickle.loads(base64.b64decode(txt)) cargs = cargs or {} if not 'close_fds' in kwargs: # workers have no fds kwargs['close_fds'] = False ret = 1 out, err, ex, trace = (None, None, None, None) try: proc = subprocess.Popen(cmd, **kwargs) try: out, err = proc.communicate(**cargs) except TimeoutExpired: if kwargs.get('start_new_session') and hasattr(os, 'killpg'): os.killpg(proc.pid, signal.SIGKILL) else: proc.kill() out, err = proc.communicate() exc = TimeoutExpired(proc.args, timeout=cargs['timeout'], output=out) exc.stderr = err raise exc ret = proc.returncode except Exception as e: exc_type, exc_value, tb = sys.exc_info() exc_lines = traceback.format_exception(exc_type, exc_value, tb) trace = str(cmd) + '\n' + ''.join(exc_lines) ex = e.__class__.__name__ # it is just text so maybe we do not need to pickle() tmp = [ret, out, err, ex, trace] obj = base64.b64encode(cPickle.dumps(tmp)) sys.stdout.write(obj.decode()) sys.stdout.write('\n') sys.stdout.flush() while 1: try: run() except KeyboardInterrupt: break ldb-2.0.8/lib/util/binsearch.h0000660000000000000000000001073713444661620016066 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. a generic binary search macro Copyright (C) Andrew Tridgell 2009 ** NOTE! The following LGPL license applies to the binsearch.h ** header. 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 . */ #ifndef _BINSEARCH_H #define _BINSEARCH_H /* a binary array search, where the array is an array of pointers to structures, and we want to find a match for 'target' on 'field' in those structures. Inputs: array: base pointer to an array of structures arrray_size: number of elements in the array field: the name of the field in the structure we are keying off target: the field value we are looking for comparison_fn: the comparison function result: where the result of the search is put if the element is found, then 'result' is set to point to the found array element. If not, then 'result' is set to NULL. The array is assumed to be sorted by the same comparison_fn as the search (with, for example, qsort) */ #define BINARY_ARRAY_SEARCH_P(array, array_size, field, target, comparison_fn, result) do { \ int32_t _b, _e; \ (result) = NULL; \ if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ int32_t _i = (_b+_e)/2; \ int _r = comparison_fn(target, array[_i]->field); \ if (_r == 0) { (result) = array[_i]; break; } \ if (_r < 0) _e = _i - 1; else _b = _i + 1; \ }} } while (0) /* like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array of structures, rather than pointers to structures result points to the found structure, or NULL */ #define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \ int32_t _b, _e; \ (result) = NULL; \ if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ int32_t _i = (_b+_e)/2; \ int _r = comparison_fn(target, array[_i].field); \ if (_r == 0) { (result) = &array[_i]; break; } \ if (_r < 0) _e = _i - 1; else _b = _i + 1; \ }} } while (0) /* like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array of elements, rather than pointers to structures result points to the found structure, or NULL */ #define BINARY_ARRAY_SEARCH_V(array, array_size, target, comparison_fn, result) do { \ int32_t _b, _e; \ (result) = NULL; \ if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ int32_t _i = (_b+_e)/2; \ int _r = comparison_fn(target, array[_i]); \ if (_r == 0) { (result) = &array[_i]; break; } \ if (_r < 0) _e = _i - 1; else _b = _i + 1; \ }} } while (0) /* like BINARY_ARRAY_SEARCH_V, but if an exact result is not found, the 'next' argument will point to the element after the place where the exact result would have been. If an exact result is found, 'next' will be NULL. If the target is beyond the end of the list, both 'exact' and 'next' will be NULL. Unlike other binsearch macros, where there are several elements that compare the same, the exact result will always point to the first one. If you don't care to distinguish between the 'greater than' and 'equals' cases, you can use the same pointer for both 'exact' and 'next'. As with all the binsearch macros, the comparison function is always called with the search term first. */ #define BINARY_ARRAY_SEARCH_GTE(array, array_size, target, comparison_fn, \ exact, next) do { \ int32_t _b, _e; \ (exact) = NULL; (next) = NULL; \ if ((array_size) > 0) { \ for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ int32_t _i = (_b + _e) / 2; \ int _r = comparison_fn(target, &array[_i]); \ if (_r == 0) { \ (exact) = &array[_i]; \ _e = _i - 1; \ } else if (_r < 0) { _e = _i - 1; \ } else { _b = _i + 1; } \ } \ if ((exact) == NULL &&_b < (array_size)) { \ (next) = &array[_b]; \ } } } while (0) #endif ldb-2.0.8/lib/util/attr.h0000660000000000000000000000517612702766507015111 0ustar rootroot00000000000000/* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij 2007 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 . */ #ifndef __UTIL_ATTR_H__ #define __UTIL_ATTR_H__ #ifndef _UNUSED_ #ifdef __GNUC__ /** gcc attribute used on function parameters so that it does not emit * warnings about them being unused. **/ # define _UNUSED_ __attribute__ ((unused)) #else # define _UNUSED_ /** Feel free to add definitions for other compilers here. */ #endif #endif #ifndef UNUSED #define UNUSED(param) param _UNUSED_ #endif #ifndef _DEPRECATED_ #ifdef HAVE___ATTRIBUTE__ #define _DEPRECATED_ __attribute__ ((deprecated)) #else #define _DEPRECATED_ #endif #endif #ifndef _WARN_UNUSED_RESULT_ #ifdef HAVE___ATTRIBUTE__ #define _WARN_UNUSED_RESULT_ __attribute__ ((warn_unused_result)) #else #define _WARN_UNUSED_RESULT_ #endif #endif #ifndef _NORETURN_ #ifdef HAVE___ATTRIBUTE__ #define _NORETURN_ __attribute__ ((noreturn)) #else #define _NORETURN_ #endif #endif #ifndef _PURE_ #ifdef HAVE___ATTRIBUTE__ #define _PURE_ __attribute__((pure)) #else #define _PURE_ #endif #endif #ifndef NONNULL #ifdef HAVE___ATTRIBUTE__ #define NONNULL(param) param __attribute__((nonnull)) #else #define NONNULL(param) param #endif #endif #ifndef PRINTF_ATTRIBUTE #ifdef HAVE___ATTRIBUTE__ /** Use gcc attribute to check printf fns. a1 is the 1-based index of * the parameter containing the format, and a2 the index of the first * argument. Note that some gcc 2.x versions don't handle this * properly **/ #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) #else #define PRINTF_ATTRIBUTE(a1, a2) #endif #endif #ifndef FORMAT_ATTRIBUTE #ifdef HAVE___ATTRIBUTE__ /** Use gcc attribute to check printf fns. a1 is argument to format() * in the above macro. This is needed to support Heimdal's printf * decorations. Note that some gcc 2.x versions don't handle this * properly. **/ #define FORMAT_ATTRIBUTE(a) __attribute__ ((format a)) #else #define FORMAT_ATTRIBUTE(a) #endif #endif #endif /* __UTIL_ATTR_H__ */